vanowm Posted September 26, 2015 Share Posted September 26, 2015 (edited) Hello. I've searched on the forum and on the web for a way draw a line perpendicular to point A which is snapped to an object, but couldn't find a good solution that would work with every 2D object (lines, plines, splines, arcs, etc). My current manual approach is to use offset for the object, it works fine but only on objects that can be offset. Another method is to use polar tracking with "Relative to last segment", but it fails on curves and intersections. So far the most promising solution I could find is to use polar command which detects the angle of a segment of a spline and then use polar command to draw line at 90 degree: http://www.cadtutor.net/forum/showthread.php?5953-lines-perpendicular-to-spline&p=35506&viewfull=1#post35506 So my challenge now is to get these parts working: 1) when user selects point A, detect which object it was clicked at. This is necessary when the selected point is an intersection. For that I think we'll need capture cursor location for example with this: (CAR (CDR (GRREAD nil 15))) and then find the object near it. Done. Post #2 2) find an angle of the object (segment) at point A Done. Post #3 3) Determine if we need to use 90 degree or 270 degree angle for the line. I'm guessing this can be calculated from angle between point A and B (?) Any help on these challenges would be greatly appreciated. Thank you. Edited September 27, 2015 by vanowm Quote Link to comment Share on other sites More sharing options...
vanowm Posted September 27, 2015 Author Share Posted September 27, 2015 (edited) The 1) challenge is done using Lee-Mac's DynOffset (DEFUN c:test (/ p1 cur ss EntLst) (SETQ p1 (GETPOINT "Select start point") cur (CAR (CDR (GRREAD nil 15))) ; cursor coordinates ss (SSGET "_C" p1 p1) ;get all objects at selected point EntLst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))) EntLst (VL-SORT ;sort objects by distance to cursor EntLst (FUNCTION (LAMBDA (a b) (< (DISTANCE cur (VLAX-CURVE-GETCLOSESTPOINTTO a cur) ) (DISTANCE cur (VLAX-CURVE-GETCLOSESTPOINTTO b cur) ) ) ) ) ) ) (CDR (ASSOC 0 (ENTGET (car EntLst)))) ;closest to cursor object is the first item in the EntLst list ) Edited September 27, 2015 by vanowm Quote Link to comment Share on other sites More sharing options...
vanowm Posted September 27, 2015 Author Share Posted September 27, 2015 Solved 2) challenge: (DEFUN c:test (/ p1 p3 ss EntLst cur ang) (SETQ p1 (GETPOINT "Select start point") cur (CAR (CDR (GRREAD nil 15))) ; cursor coordinates ss (SSGET "_C" p1 p1) ; get all objects at selected point EntLst (VL-REMOVE-IF 'LISTP (MAPCAR 'CADR (SSNAMEX ss))) EntLst (VL-SORT ; sort objects by distance to cursor EntLst (FUNCTION (LAMBDA (a b) (< (DISTANCE cur (VLAX-CURVE-GETCLOSESTPOINTTO a cur) ) (DISTANCE cur (VLAX-CURVE-GETCLOSESTPOINTTO b cur) ) ) ) ) ) ent (CAR EntLst) ; closest to cursor p3 (VLAX-CURVE-GETPOINTATDIST ent (+ 0.0001 (VLAX-CURVE-GETDISTATPOINT ent p1))) ; coordinates on this entity 0.0001 away from p1 ang (ANGLE p1 p3) ; get angle between p1 and p3 ) (ENTMAKE (LIST '(0 . "LINE") (CONS 10 (TRANS p1 1 0)) (CONS 11 (TRANS (POLAR p1 ang 1000) 1 0)) ) ) ) Quote Link to comment Share on other sites More sharing options...
marko_ribar Posted September 27, 2015 Share Posted September 27, 2015 (edited) I've searched on the forum and on the web for a way draw a line perpendicular to point A which is snapped to an object, but couldn't find a good solution that would work with every 2D object (lines, plines, splines, arcs, etc). Why just not : (defun c:perpline ( / f p a o ) (vl-load-com) (if (eq (getvar 'worlducs) 0) (progn (command "_.UCS" "_W") (setq f t) ) ) (while (or (null p) (not (and p (setq p (osnap p "_nea"))))) (setq p (getpoint "\nPick point on curve - closest one will be accounted : ")) ) (setq a (angle '(0.0 0.0) (vlax-curve-getfirstderiv (setq e (car (nentselp p))) (vlax-curve-getparamatpoint e (vlax-curve-getclosestpointto e p))))) (command "_.UCS" "_3P" "_non" p "_non" (polar p a 1.0) "_non" (polar p (+ (* 0.5 pi) a) 1.0)) (setq o (getvar 'orthomode)) (setvar 'orthomode 1) (command "_.LINE" "_non" '(0.0 0.0 0.0) "\\" "") (setvar 'orthomode o) (command "_.UCS" "_P") (if f (command "_.UCS" "_P") ) (princ) ) Edited September 27, 2015 by marko_ribar typo Quote Link to comment Share on other sites More sharing options...
vanowm Posted September 27, 2015 Author Share Posted September 27, 2015 (edited) That's actually pretty good, thank you. Unfortunately it's not 100% working in my quick test. For some reason on huge (dimension wise) entities it draws zero length line when I enter length manually: test1: word view, pick first point on any object, then enter 10 as length. result: line with 0 length test2: zoom in to a part of an object, pick first point and enter 10 as length: result: 10 inch line [EDIT] Found what's causing it: with too short line osnap would catch the starting coordinates as the end of line. Drawing1.dwg Edited September 27, 2015 by vanowm Quote Link to comment Share on other sites More sharing options...
tombu Posted September 28, 2015 Share Posted September 28, 2015 For 3) set SNAPANG to the value from 2) then put the cursor on the side you want the line and enter the distance. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 28, 2015 Share Posted September 28, 2015 Maybe this program can help? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.