perpendicular from entity of given length

perpendicular from entity of given length

Anonymous
Not applicable
1,245 Views
7 Replies
Message 1 of 8

perpendicular from entity of given length

Anonymous
Not applicable

Hello,

 

as the title suggests, I have the following problem:

 

Given an entity E (in most cases a pline), a point P on E, and a number d, draw a line L of length d which starts at point P and is perpendicular to E, i.e. perpendicular to the tangent vector to E at P.

 

Now, I solved this problem a bit dirty: simply offset E by a distance d, which gives E', and find the closest point on E' to the point P. Call that point P'. Then the line along P and P' is the sought line L.

 

The problem with this is that I'm creating these auxiliary offset lines with "command", and in general I don't want them to be visible. So I did a ton of google-ing, but didn't find how I could offset lines with entmake, for example (I assume entmake can simply create an entity and add it to the drawing database without actually displaying it? Perhaps I'm wrong). Also, this while procedure seems a bit dirty and I wonder if there is a more clean, straightforward way to do this. I also tried to set the color of the offset lines to the background color, tried to adjust transparency, etc., but still these lines are recognizable - perhaps there don't exist invisible lines (colorwise) at all?

 

Any suggestions are highly appreciated, as usual.

0 Likes
Accepted solutions (1)
1,246 Views
7 Replies
Replies (7)
Message 2 of 8

ВeekeeCZ
Consultant
Consultant
Accepted solution

Some hints for you...

 

(vl-load-com)

(setq ensel (entsel "Select curve:" ))

(setq curve (car ensel)
      pt (cadr ensel)
      pt (vlax-curve-getClosestPointTo curve pt)
      param (vlax-curve-getParamAtPoint curve pt)
      ang (angle (vlax-curve-getFirstDeriv curve param) '(0 0 0)))

(setq perpendicularAng (+ ang (* 0.5 pi))) ; or negative

 

And those used in my routine. Not sure if this helps... it's a little different (you can pre-select the object, or not...). A distance and direction are fixed.

Spoiler
(defun c:AK ( / ss en pt ang)  				; 
  (if (and (setq pt (cond ((getpoint (if (and (setq ss (ssget "_I" '((0 . "*LINE,ARC,CIRCLE,ELLIPSE,RAY"))))
					      (= 1 (sslength ss))
					      (ssget "_P" '((0 . "*LINE,ARC")))
					      (setq en (ssname ss 0)))
				       "\nSpecify a point <middle>: "
				       (progn
					 (initget 1)
					 "\nSpecify a point: "))))
			  ((trans (vlax-curve-getClosestPointTo en (mapcar '(lambda (a b) (/ (+ a b) 2.))
									   (vlax-curve-getStartPoint en)
									   (vlax-curve-getEndPoint   en))) 0 1))))
	   (or en
	       (setq ss (ssget "_C"
			       (polar pt (* 1.25 pi) 0.01)
			       (polar pt (* 0.25 pi) 0.01)
			       '((0 . "*LINE,ARC,CIRCLE,ELLIPSE,RAY")))
		     en (cond ((and ss
				    (= 1 (sslength ss)))
			       (ssname ss 0))
			      ((car (entsel "\nSelect a line: "))))))
	   (setq ang (- (angle '(0 0 0)
			       (vlax-curve-getFirstDeriv en (vlax-curve-getParamAtPoint en (vlax-curve-getClosestPointTo en (trans pt 1 0)))))
			(angle '(0 0 0)
			       (getvar 'UCSXDIR)))))
	   
    (vl-cmdf "_.LINE"
	     "_non" pt
	     "_non" (polar pt (+ ang (* pi 0.5)) 10.)
	     ""))
  (princ)
)

 

Message 3 of 8

Anonymous
Not applicable

Nice idea, I'll try to fit it into my routine. Thanks!

0 Likes
Message 4 of 8

Anonymous
Not applicable

Another question regarding programming style.

 

I see you use "vl-cmdf" instead of command, and you also use "_non" in the command. Would you also advice in general to always use vl-cmdf? As I read, this enforces the command not to be entered before the arguments are evaluated. i.e., the result is the elimination of possible partial entities drawn.

 

Also "_non", as I read, is used as a osnap elimination. I do that so that I get the environment variables before running a script, and then set them back to the old values after execution. The advantage of your method would no to mess with environment variable settings - since the script may return an error before it got a chance to restore old values, hence leaving the falues fiddled with.

 

Am I correct on the statements above?

0 Likes
Message 5 of 8

dgorsman
Consultant
Consultant

Math is your friend, especially vector math in this case.  You can use it to calculate points and directions without having to create construction entities.  Even if you use the curve helper functions understanding how to do the calculations will have benefits later on.

 

Given a linear entity E with points A and B, it can be described as vector AB (skipping some of the proper notation, as its not supported in this forum).  You want another vector of length d which is perpendicular to a point P on AB.  This can be done with a vector cross product of the vector AB and another vector (probably a normal vector); from there the resultant vector can be scaled to length d, then applied as an offset to point P.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 6 of 8

ВeekeeCZ
Consultant
Consultant

@Anonymous wrote:

...Would you also advice in general to always use vl-cmdf? As I read, this enforces the command not to be entered before the arguments are evaluated. i.e., the result is the elimination of possible partial entities drawn.

 

...

I think it's the case of habbit. Yes, vl-cmdf can prevent some errors. 

 

 


@Anonymous wrote:

 

... 

Also "_non", as I read, is used as a osnap elimination. I do that so that I get the environment variables before running a script, and then set them back to the old values after execution. The advantage of your method would no to mess with environment variable settings - since the script may return an error before it got a chance to restore old values, hence leaving the falues fiddled with.

 


Yes. Using "_non" is simpler, no worry about restoring old values.

If you change OSMODE system variable then you ALWAYS  need to have *error* trap!

 

By the way: In Autocad is a difference between "Environment variable", see HERE and "System variable". Mostly we use system variables (as 'OSMODE).

Message 7 of 8

Kent1Cooper
Consultant
Consultant

You may be able to use some of what's in MarkMIdPoints.lsp, available here.  One of its options is to draw Lines perpendicular to whatever object you're marking.  The code to do that part from a given point could be altered easily enough to make them go in one direction from there, rather than both ways.

 

As for making them invisible, make a separate Layer for them, and turn it off.  The current Layer can be off [though not frozen], and you [or a routine] can draw things on it anyway.

Kent Cooper, AIA
0 Likes
Message 8 of 8

Anonymous
Not applicable

Thanks for the useful tips.

0 Likes