I am trying to see if there is a way to build an xline perpendicular to an entity by passing this entity and a point instead of two points. Does anyone know?
I know that this works
(command "xline" "_per" pt0 pt "") ; draw the perpendicular
but I have too many lines at pt0 and instead of passing a pt0, I would like to tell LISP the entity that I want to build a perpendicular to and a point at which I need it.
Thank you in advance for your help.
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by Lee_Mac. Go to Solution.
Solved by Kent1Cooper. Go to Solution.
perhaps something like this ?
(defun c:XXX (/ pt pt1 pt2 ang omode) (setq omode (getvar "osmode")) (setq pt (cdr(assoc 10(entget (car (entsel "\nSelect the Line:")))))) (while (setq pt1 (getpoint "\n Pick the point for Xline:")) (setq ang (angle pt pt1)) (setq pt2 (polar pt1 (+ ang 1.5707) 1)) (setvar "osmode" 0) (command "xline" pt1 pt2 "") (setvar "osmode" omode) );while );defun
Ajilal.Vijayan's approach should probably have some object-snap additions, to ensure that the points used to calculate the angle are actually on the entity, since both selection functions can return something if the cursor location is only within PICKBOX-size range of the entity [in fact, the second one could have no relation to it at all]. Even with that, it would only work with Lines or Polyline line segments or a few other straight things. You can have it work equally well with Circles, Arcs, Splines, Ellipses, Polyline arc segments:
(defun C:XLPP (/ ent pt); = XLine Perpendicular at Point
(setq
ent (car (entsel "\nSelect object for Xline to be perpendicular to: "))
pt (getpoint "\nPoint at which to draw perpendicular Xline: ")
pt (vlax-curve-getClosestPointTo ent pt); force to be ON entity
); setq
(command
"_.xline" "_none" pt "_none"
(polar
pt
(+
(angle ; direction of ent at pt
'(0 0 0)
(vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt))
); angle
(/ pi 2); 90 degrees in radians
); +
1 ; [could be any distance]
); polar
"" ; close Xline command
); command
(princ)
); defun
Lightly tested. Using (...-getClosestPointTo ...) rather than Osnap Nearest allows the through-point to be not on the entity, if you want -- it will draw an Xline through that point, passing perpendicularly through the nearest point on the entity. [Consider whether to use the Extend option in that function.] It could be enhanced to verify whether something was actually selected, and whether it's a perpendicularable entity type, etc.
Here's another way:
(defun c:xper ( / der pnt sel ) (while (progn (setvar 'errno 0) (setq sel (entsel)) (cond ( (= 7 (getvar 'errno)) (princ "\nMissed, try again.") ) ( (null sel) nil) ( (vl-catch-all-error-p (setq pnt (vl-catch-all-apply 'vlax-curve-getclosestpointto (list (car sel) (trans (cadr sel) 1 0)) ) ) ) (princ "\nInvalid object selected.") ) ( (setq der (trans (vlax-curve-getfirstderiv (car sel) (vlax-curve-getparamatpoint (car sel) pnt)) 0 (car sel) t)) (entmake (list '(000 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 pnt) (list 11 (- (cadr der)) (car der)) ) ) nil ;; Remove for continuous use ) ) ) ) (princ) ) (vl-load-com) (princ)
Hello Kent,
This code works very well on a simple geometry but once I get to a complex figure, it starts giving me a fist... I think the problem is that the point that I feed to the statement below doesn't alway precisely lie on a curve. Is there a way to force it to find the closest point to pt on ent curve?
vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt)
I am getting pt in my program through ssget from another line not through user's selection.
Thank you
One way to determine the 'onseg' status
is to create a temporary Xline over the
selected LINE entity, by its ends,
find the closest point to the temp-xline,
and compare that to the closest of the LINE.
@user_sf wrote:
... I think the problem is that the point that I feed to the statement below doesn't alway precisely lie on a curve. Is there a way to force it to find the closest point to pt on ent curve?
....
I am getting pt in my program through ssget from another line not through user's selection.
....
That's what this line does:
(setq
...
pt (vlax-curve-getClosestPointTo ent pt); force to be ON entity
...
Whatever modification you've done for getting pt from elsewhere, include that line after pt is first set, and it should handle it.
Thank you, Stevor. I don't want to check if it is on the line. I want to put in on the line, something to do with tolerances??? onsnap? smth like that and then find a tangent line to ent at this point.
@stevor wrote:
One way to determine the 'onseg' status is to create a temporary Xline over the selected LINE entity, by its ends, find the closest point to the temp-xline, and compare that to the closest of the LINE.
Or, just compare the results of (vlax-curve-getClosestPointTo) both with and without the optional [extend] argument at the end. As I had it, if the given point is past the end of the Line so that a perpendicular from the point to the Line would miss the end of the Line, it will draw the Xline perpendicular AT the end of the Line, not going through the given point. That can be "fixed" if needed by including the [extend] argument, but it would also require a different way of determining the Line's direction to be perpendicular to, either by also finding the closest point without the [extend] argument or by using the Line's endpoints, because getting the first derivative won't work using a point that's off the end of the Line. Some of that would also be applicable to some other entity types, but not all of the possibilities.
Kent's code will also be affected by the active UCS since the point argument required by vlax-curve-getclosestpointto should be expressed relative to the WCS, not UCS as returned by getpoint. Furthermore, the curve functions will all return WCS points, however, polar/angle/command operate in the UCS.
My code should be compatible with all UCS settings.
Right Kent, vlax-curve-getclosestpointto,
with the optional 3rd argument as T, does the job
in 4 less lines of code, in my version.