Calculating the coordinates of the required point relative to the polyline

Calculating the coordinates of the required point relative to the polyline

Browning_Zed
Advocate Advocate
749 Views
8 Replies
Message 1 of 9

Calculating the coordinates of the required point relative to the polyline

Browning_Zed
Advocate
Advocate

AutoCAD VPort Image.png

 

Greetings to all forum members!

 

I need to determine the coordinates of a point lying relative to the polyline at some distance. To do this, needed certain geometric calculations, which I tried to represent in picture attached to this post. In the picture, each stage of geometric calculations numbered separately. Below I will provide an explanation for each of the steps.


1. For the first stage of calculations, a polyline with the following characteristics is required:
     • not closed
     • contains more than one segment (the number of segments can be any)
     • the first and last segment are not arcs
As the initial data for further calculations, only four coordinates are required: two coordinates of the vertices of the first segment and two coordinates of the vertices of the last segment of the polyline.
2. At this stage, an imaginary XLINE_1 is created, which passes through the start point of the polyline and is perpendicular to the first segment. After that, the condition is checked: if the imaginary XLINE_1 does not intersection the last segment of the polyline, then go to stage 3, if it crosses the last segment, then go to stage 5.
3. Then need to create imaginary XLINE_2 that passes through the endpoint of the polyline and is perpendicular to XLINE_1.
4. Now, at the intersection of XLINE_1 and XLINE_2, the coordinates of the required point will be obtained.
5. At this stage, a condition is presented when the imaginary XLINE_1 intersect the last segment of the polyline, then go to the next stage.
6. In this case, the imaginary XLINE_1 must passing through the end point of the polyline and be perpendicular to the last segment, and the imaginary XLINE_2 must passing through the start point of the polyline and be perpendicular to XLINE_1. At the intersection of XLINE_1 and XLINE_2, the coordinates of the required point will be obtained.

―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――

Thus, the solution to this problem will be to obtain the coordinates of the required point, which will differ depending on the condition - whether or not XLINE_1 intersects the last segment of the polyline.

 

I hope I have not explained my thoughts too chaotically. I would be very grateful for your help in solving this problem.

Thanks in advance.

0 Likes
Accepted solutions (1)
750 Views
8 Replies
Replies (8)
Message 2 of 9

hak_vz
Advisor
Advisor

@Browning_Zed 

I don't have time to create full code for you, but here you have a code you can work with. It even solves some of you cases. I hope you have started learning autolisp, visual lisp so you can write some lines by yourself.

(defun c:moo (
		/ take pointlist2d pick_poly get_intersections create_value_vector mod_vect vect_dot unit_vect 
		e eo coords a b c d xline_1 xline_2ang1 ang2
		)
	(defun take (amount lst / ret)(repeat amount (setq ret (cons (car lst) (take (1- amount) (cdr lst))))))	
	(defun pointlist2d (lst / ret) (while lst (setq	ret (cons (take 2 lst) ret) lst (cddr lst))) (reverse ret))
	(defun pick_poly (msg)
		(setq e (car(entsel msg)))
		(if (and (not e) (= (getvar 'Errno) 7)) (pick_poly msg) e)
	)
	(defun get_intersections	(obj1 obj2 / var)
		(setq var (vlax-variant-value (vla-intersectwith obj1 obj2 1)))
		(if (< 0 (vlax-safearray-get-u-bound var 1))(vlax-safearray->list var))
	)
	(defun create_value_vector (n val / r ) (repeat n (setq r (cons val r))) r)
	(defun mod_vect (v)(sqrt(vect_dot v v)))
	(defun vect_dot (v1 v2)(apply '+ (mapcar '* v1 v2)))
	(defun unit_vect (v)(mapcar '* v (create_value_vector (length v) (/ 1 (mod_vect v)))))
	(setq e (pick_poly "\nSelect pline >"))
	(setq eo (vlax-ename->vla-object e))
	(setq coords (pointlist2d(vlax-get eo 'Coordinates)))
	(setq a (car coords) b (cadr coords) coords (reverse coords))
	(setq d (car coords) c (cadr coords))
	(setq ang1 (angle a b))
	(setq ang2 (- ang1 (* 0.5 PI)))
	(setq xline_1
		(entmakex
			(list
				(cons 0 "XLINE")
				(cons 100 "AcDbEntity")
				(cons 100 "AcDbXline")
				(cons 10 (trans a 1 0))
				(cons 11 (unit_vect(mapcar '- (polar a ang2 10) a)))
			)
		)
	)
	(setq xline_2
		(entmakex
			(list
				(cons 0 "XLINE")
				(cons 100 "AcDbEntity")
				(cons 100 "AcDbXline")
				(cons 10 (trans d 1 0))
				(cons 11 (unit_vect(mapcar '- (polar d ang1 10) d)))
			)
		)
	)
	;Zed, here comes your code for particular cases
	(princ)
)

 

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 3 of 9

Browning_Zed
Advocate
Advocate

Thanks for sharing your code, I'll try to adapt this to my needs.

0 Likes
Message 4 of 9

CADaSchtroumpf
Advisor
Advisor

Or for make directly the required point

((lambda ( / js ent dxf_ent pt_start deriv_start ang_start pt_end deriv_end ang_end pt1 pt2)
	(princ "\nSelect polyline")
	(while (null (setq js (ssget "_+.:E:S" '((0 . "LWPOLYLINE") (-4 . "<AND") (-4 . ">") (90 . 2) (-4 . "<NOT") (-4 . "&") (70 . 121) (-4 . "NOT>") (-4 . "AND>")))))
			(princ "\nOject isn'tvalide")
	)
	(setq
		ent (ssname js 0)
		dxf_ent (entget ent)
		pt_start (vlax-curve-GetPointAtParam ent (vlax-curve-getStartParam ent))
		deriv_start (vlax-curve-getfirstderiv ent (vlax-curve-getStartParam ent))
		ang_start (atan (cadr deriv_start) (car deriv_start))
		pt_end (vlax-curve-GetPointAtParam ent (vlax-curve-getEndParam ent))
		deriv_end (vlax-curve-getfirstderiv ent (vlax-curve-getEndParam ent))
		ang_end (atan (cadr deriv_end) (car deriv_end))
		pt1 (polar pt_start (+ (* 0.5 pi) ang_start) (distance pt_start pt_end))
		pt2 (polar pt_end (+ (* 0.5 pi) ang_end) (distance pt_start pt_end))
	)
	(entmake
		(list
			(cons 0 "POINT")
			(cons 100 "AcDbEntity")
			(assoc 67 dxf_ent)
			(assoc 410 dxf_ent)
			(cons 8 (getvar "CLAYER"))
			(cons 100 "AcDbPoint")
			(cons 10 (inters pt_start pt1 pt_end pt2 nil))
			(assoc 210 dxf_ent)
		)
	)
	(prin1)
))
Message 5 of 9

Browning_Zed
Advocate
Advocate

Many thanks! That's what I need. But there are two points that, if possible, I would like to change.
1. If the condition "XLINE_1 does not intersection last segment" is met, then in your code imaginary XLINE_2 passes perpendicular to the last segment, is it possible for XLINE_2 to pass perpendicular to XLINE_1?
2. If the condition "XLINE_1 does intersection last segment" is met, this works correctly: XLINE_2 passes perpendicular to XLINE_1, but it also passes perpendicular to the first segment, which is not necessary. I also forgot to say one thing: XLINE_1 and XLINE_2 must not intersect any of the polyline segments, and if XLINE_2 is perpendicular to the first segment, an intersection is obtained.

0 Likes
Message 6 of 9

diagodose2009
Collaborator
Collaborator

Please you upload here, a Sample-the-Drawing.dwg.

You reveal a real purpose (commercial purpose, educational purpose, or your business...)

The Sample-the-Drawing.dwg must contain a few team-xline/s.

You draw manually "BEFORE" and "AFTER"

Alles gutes..............

0 Likes
Message 7 of 9

CADaSchtroumpf
Advisor
Advisor
Accepted solution

I corrected the code, hope the result will be as expected ...

((lambda ( / js ent dxf_ent prm_start pt_start deriv_start ang_start prm_end pt_end deriv_end lg pt_prv pt1 ang_end pt2)
	(princ "\nSelect polyline")
	(while (null (setq js (ssget "_+.:E:S" '((0 . "LWPOLYLINE") (-4 . "<AND") (-4 . ">") (90 . 2) (-4 . "<NOT") (-4 . "&") (70 . 121) (-4 . "NOT>") (-4 . "AND>")))))
			(princ "\nOject isn'tvalide")
	)
	(setq
		ent (ssname js 0)
		dxf_ent (entget ent)
		prm_start (vlax-curve-getStartParam ent)
		pt_start (vlax-curve-GetPointAtParam ent prm_start)
		deriv_start (vlax-curve-getfirstderiv ent prm_start)
		ang_start (atan (cadr deriv_start) (car deriv_start))
		prm_end (vlax-curve-getEndParam ent)
		pt_end (vlax-curve-GetPointAtParam ent prm_end)
		deriv_end (vlax-curve-getfirstderiv ent prm_end)
		lg (vlax-curve-getdistatparam ent prm_end)
		pt_prv (vlax-curve-GetPointAtParam ent (1- prm_end))
		pt1 (polar pt_start (+ (* 0.5 pi) ang_start) lg)
		ang_end (angle pt_start pt1)
		pt2 (polar pt_end (+ (* 0.5 pi) ang_end) lg)
	)
	(if
		(or
			(inters pt_start pt1 pt_prv pt_end T)
			(inters pt_start (polar pt_start (- ang_start (* 0.5 pi)) lg) pt_prv pt_end T)
		)
		(setq
			pt2 (polar pt_end (+ (* 0.5 pi) (atan (cadr deriv_end) (car deriv_end))) lg)
			pt1 (polar pt_start (+ (* 0.5 pi) (angle pt_end pt2)) lg)
		)
	)
	(entmake
		(list
			(cons 0 "POINT")
			(cons 100 "AcDbEntity")
			(assoc 67 dxf_ent)
			(assoc 410 dxf_ent)
			(cons 8 (getvar "CLAYER"))
			(cons 100 "AcDbPoint")
			(cons 10 (inters pt_start pt1 pt_end pt2 nil))
			(assoc 210 dxf_ent)
		)
	)
	(prin1)
))
Message 8 of 9

Browning_Zed
Advocate
Advocate

Now it works great! Thank you so much, you helped me a lot.

0 Likes
Message 9 of 9

diagodose2009
Collaborator
Collaborator

Here can you test

0 Likes