SEANT Posted January 10, 2009 Share Posted January 10, 2009 > SEANT, Lee Mac There is vlax-curve-getClosestPointToProjection function, especially for such cases. That should do. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 > Lee Mac About right and left side. Create a temporary curve using _OFFSET on minimal distance and measure the distance from the block to the main and to the temporary curve. Do you understand what I hinted? Thats a nice idea ASMI, offset it one side, say RHS, then say, if the distance to the temp curve is greater than the main curve its on the left and if not, its on the right Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 This is possibly a “non-issue” but interesting none the less. The closest point from an object to a 3D polyline may not give meaningful information if: The attached example is exaggerated to illustrate the point. I have used the 3D closest point and then just used simple pythagorean geometry on the x,y coords to get 2D distance. - is this not correct? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 > SEANT, Lee Mac There is vlax-curve-getClosestPointToProjection function, especially for such cases. I have read the ACAD help file on this, but how would one specify the normal vector, in what format? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 Ok, using ASMI's suggestion: (defun c:pdis (/ varlist oldvars cCurve nlist sAng cBlock txtpnt index ent dPt1 dPt2 blkDist blkDist2 blkDist3 blklist txt dCurve lPt1 rl ) (defun makelay (x) (if (not (tblsearch "Layer" x)) (progn (setvar "cmdecho" 0) (command "-layer" "m" x "") (setvar "cmdecho" 1) ) ;_ end progn ) ;_ end if ) ;_ end defun (defun Make_Text (txt_pt txt_val) (entmake (list '(0 . "TEXT") '(8 . "TEXT") (cons 10 txt_pt) (cons 40 2.5) (cons 1 txt_val) '(50 . 0.0) '(7 . "STANDARD") '(71 . 0) '(72 . 0) '(73 . 0) ) ; end list ) ; end entmake ) ;_ end defun (defun massoc (key alist / x) (foreach x alist (if (eq key (car x)) (setq nlist (cons (cdr x) nlist)) ) ;_ end if ) ;_ end foreach (setq nlist (reverse nlist)) ) ;_ end defun (setq varlist (list "CMDECHO" "CLAYER") oldvars (mapcar 'getvar varlist) ) ;_ end setq (setvar "cmdecho" 0) (vl-load-com) (if (and (setq cCurve (car (entsel "\nSelect curve to measure > "))) (member (cdr (assoc 0 (entget cCurve))) '("LINE" "POLYLINE" "LWPOLYLINE" "SPLINE" "ARC" "CIRCLE" "ELLIPSE") ) ;_ end member ) ; end and (progn (massoc 10 (entget cCurve)) (setq sAng (angle (nth 0 nlist) (nth 1 nlist) ) ;_ end angle ) ;_ end setq (while (and (setq cBlock (ssget '((0 . "INSERT")))) (setq txtpnt (getpoint "\nSelect Point for Table > ")) ) ;_ end and (makelay "TEXT") (setq index (1- (sslength cBlock)) blklist "\n" txt 1 ) ;_ end setq (command "_offset" "0.01" cCurve (polar (nth 0 nlist) (- sAng (/ pi 2)) 0.01) "") (setq dCurve (entlast)) (while (not (minusp index)) (setq ent (entget (ssname cBlock index)) dPt1 (cdr (assoc 10 ent)) dPt2 (vlax-curve-getClosestPointTo cCurve dPt1) blkDist2 (distance dPt1 dPt2) blkDist (expt (+ (expt (- (car dPt1) (car dPt2)) 2) (expt (- (cadr dPt1) (cadr dPt2)) 2) ) ;_ end + 0.5 ) ;_ end exp ) ;_ end setq (setq lPt1 (vlax-curve-getClosestPointTo dCurve dPt1) blkDist3 (distance dPt1 lPt1) ) ;_ end setq (if (< blkDist3 blkDist2) (setq rl "RIGHT") (setq rl "LEFT") ) ;_ end if (setq blklist (strcat "Block Coord: " (rtos (car dPt1) 2 1) "," (rtos (cadr dPt1) 2 1) " Distance: " (rtos blkDist 2 1) " : " rl ) ;_ end strcat ) ;_ end setq (Make_Text (polar txtpnt (* pi 1.5) (* 3.5 txt)) blklist) (setq index (1- index) txt (1+ txt) ) ;_ end setq ) ; end while (entdel dCurve) ) ;_ end while ) ;_ end progn (princ "\n<!> Empty selection or this isn't a Curve (line, polyline, etc.) <!> ") ) ; end if (mapcar 'setvar varlist oldvars) (princ) ) ;_ end defun Quote Link to comment Share on other sites More sharing options...
SEANT Posted January 10, 2009 Share Posted January 10, 2009 I have used the 3D closest point and then just used simple pythagorean geometry on the x,y coords to get 2D distance. - is this not correct? In a “real world” view, I’d say your method is correct. I brought up the issue to highlight the problems associated with a 2D only requirement. For example, if a local zoning board were interested in offsets only as they appeared on a 2D map, the closest point may be different than one would find in the field (see “3dPolyIssue.dwg”). The objective of these zoning laws may be better served with the inclusion of the third dimension, but my experience has been that zoning departments are woefully behind technically, and put too much trust in their old hand drawn maps. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 In a “real world” view, I’d say your method is correct. I brought up the issue to highlight the problems associated with a 2D only requirement. For example, if a local zoning board were interested in offsets only as they appeared on a 2D map, the closest point may be different than one would find in the field (see “3dPolyIssue.dwg”). The objective of these zoning laws may be better served with the inclusion of the third dimension, but my experience has been that zoning departments are woefully behind technically, and put too much trust in their old hand drawn maps. I understand where you are coming from SEANT - I suppose the error percentage is negligible for such an application. Quote Link to comment Share on other sites More sharing options...
SEANT Posted January 10, 2009 Share Posted January 10, 2009 I understand where you are coming from SEANT - I suppose the error percentage is negligible for such an application. I suspect that as well. I actually only brought it up as a matter of interest. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 I suspect that as well. I actually only brought it up as a matter of interest. And its a good point, as a lecturer at my university pointed out: "With Mathematics there is the possibility of perfect rigour, so why settle for less?" Quote Link to comment Share on other sites More sharing options...
ASMI Posted January 10, 2009 Share Posted January 10, 2009 > Lee Mac I have read the ACAD help file on this, but how would one specify the normal vector, in what format? This is variant, array of doubles with 3 members (x, y, z). For X,Y plane it equal (0.0 0.0 1.0) because normal vector directed as Z axis. Use vlax-3d-point function to make it variant-array: Command: (vlax-3d-point '(0.0 0.0 1.0)) #<variant 8197 ...> Quote Link to comment Share on other sites More sharing options...
SEANT Posted January 10, 2009 Share Posted January 10, 2009 And its a good point, as a lecturer at my university pointed out: "With Mathematics there is the possibility of perfect rigour, so why settle for less?" He doesn’t sound like the type to give “partial credit” to incorrect answers on exams. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 He doesn’t sound like the type to give “partial credit” to incorrect answers on exams. Haha, very true. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 10, 2009 Share Posted January 10, 2009 > Lee Mac This is variant, array of doubles with 3 members (x, y, z). For X,Y plane it equal (0.0 0.0 1.0) because normal vector directed as Z axis. Use vlax-3d-point function to make it variant-array: Command: (vlax-3d-point '(0.0 0.0 1.0)) #<variant 8197 ...> I tried to check the result of this with no luck: (setq a (getpoint)) (vlax-curve-getClosestPointToProjection (car (entsel)) a (vlax-3d-point '(0.0 0.0 1.0))) Should this return a 2D point? (with z coord zero) Quote Link to comment Share on other sites More sharing options...
ASMI Posted January 11, 2009 Share Posted January 11, 2009 Excuse me you should to use ordinary coordinates list, not variant. (vlax-curve-getClosestPointToProjection (car (entsel)) a '(0.0 0.0 1.0)) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 11, 2009 Share Posted January 11, 2009 I suppose this would be a position vector. - not intuitively obvious - I think the ACAD help file should've included an example. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 11, 2009 Share Posted January 11, 2009 So I suppose something like this if I have used it properly: (defun c:pdis (/ varlist oldvars cCurve nlist sAng cBlock txtpnt index ent dPt1 dPt2 blkDist blkDist2 blkDist3 blklist txt dCurve lPt1 rl ) (defun makelay (x) (if (not (tblsearch "Layer" x)) (progn (setvar "cmdecho" 0) (command "-layer" "m" x "") (setvar "cmdecho" 1) ) ;_ end progn ) ;_ end if ) ;_ end defun (defun Make_Text (txt_pt txt_val) (entmake (list '(0 . "TEXT") '(8 . "TEXT") (cons 10 txt_pt) (cons 40 2.5) (cons 1 txt_val) '(50 . 0.0) '(7 . "STANDARD") '(71 . 0) '(72 . 0) '(73 . 0) ) ; end list ) ; end entmake ) ;_ end defun (defun massoc (key alist / x) (foreach x alist (if (eq key (car x)) (setq nlist (cons (cdr x) nlist)) ) ;_ end if ) ;_ end foreach (setq nlist (reverse nlist)) ) ;_ end defun (setq varlist (list "CMDECHO" "CLAYER") oldvars (mapcar 'getvar varlist) ) ;_ end setq (setvar "cmdecho" 0) (vl-load-com) (if (and (setq cCurve (car (entsel "\nSelect curve to measure > "))) (member (cdr (assoc 0 (entget cCurve))) '("LINE" "POLYLINE" "LWPOLYLINE" "SPLINE" "ARC" "CIRCLE" "ELLIPSE") ) ;_ end member ) ; end and (progn (massoc 10 (entget cCurve)) (setq sAng (angle (nth 0 nlist) (nth 1 nlist) ) ;_ end angle ) ;_ end setq (while (and (setq cBlock (ssget '((0 . "INSERT")))) (setq txtpnt (getpoint "\nSelect Point for Table > ")) ) ;_ end and (makelay "TEXT") (setq index (1- (sslength cBlock)) blklist "\n" txt 1 ) ;_ end setq (command "_offset" "0.01" cCurve (polar (nth 0 nlist) (- sAng (/ pi 2)) 0.01) "") (setq dCurve (entlast)) (while (not (minusp index)) (setq ent (entget (ssname cBlock index)) dPt1 (cdr (assoc 10 ent)) dPt2 (vlax-curve-getClosestPointToProjection cCurve dPt1 '(0.0 0.0 1.0)) blkDist2 (distance dPt1 dPt2) blkDist (expt (+ (expt (- (car dPt1) (car dPt2)) 2) (expt (- (cadr dPt1) (cadr dPt2)) 2) ) ;_ end + 0.5 ) ;_ end exp ) ;_ end setq (setq lPt1 (vlax-curve-getClosestPointToProjection dCurve dPt1 '(0.0 0.0 1.0)) blkDist3 (distance dPt1 lPt1) ) ;_ end setq (if (< blkDist3 blkDist2) (setq rl "RIGHT") (setq rl "LEFT") ) ;_ end if (setq blklist (strcat "Block Coord: " (rtos (car dPt1) 2 1) "," (rtos (cadr dPt1) 2 1) " Distance: " (rtos blkDist 2 1) " : " rl ) ;_ end strcat ) ;_ end setq (Make_Text (polar txtpnt (* pi 1.5) (* 3.5 txt)) blklist) (setq index (1- index) txt (1+ txt) ) ;_ end setq ) ; end while (entdel dCurve) ) ;_ end while ) ;_ end progn (princ "\n<!> Empty selection or this isn't a Curve (line, polyline, etc.) <!> ") ) ; end if (mapcar 'setvar varlist oldvars) (princ) ) ;_ end defun Quote Link to comment Share on other sites More sharing options...
wannabe Posted January 12, 2009 Author Share Posted January 12, 2009 Lee I tried the routine on page 5 of this thread and it gives the following error: Select curve to measure > ; error: bad argument type: 2D/3D point: nil. Is the one posted above worth giving a shot? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 12, 2009 Share Posted January 12, 2009 Hmmm.... code posted on sheet 5 works on my machine: Closest Point Example.zip Quote Link to comment Share on other sites More sharing options...
wannabe Posted January 13, 2009 Author Share Posted January 13, 2009 any chance u cud try with my drawing? Quote Link to comment Share on other sites More sharing options...
wannabe Posted January 13, 2009 Author Share Posted January 13, 2009 It doesn't work on my 3D polyline, but normal ones it does. EDIT: Works amazingly on 2D pl's. How is the side it is on being worked out? 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.