Author Topic: Projecting points on polylines and determining side  (Read 5047 times)

0 Members and 1 Guest are viewing this topic.

XXL1966

  • Guest
Projecting points on polylines and determining side
« on: May 04, 2013, 01:12:33 PM »
Hello,

i need a function that projects points on a polyline within a certain distance and determine the side of the points on the polyline.

The first step is easy by using the vlax-curve-getClosestPointTo, next compute the distance between point and projection and compare with given distance. As for the side. Is there a ready to use function in (v)lisp to do this ? For a straight segmented polyline i could determine the segment the point is projected on (but how ?) and then compute the area of the triangle between segment and projection point (area will be + or -).

Just curious if anyone else already solved this problem or maybe knows an easy way to do this...

thanks !

 

jvillarreal

  • Bull Frog
  • Posts: 332
Re: Projecting points on polylines and determining side
« Reply #1 on: May 04, 2013, 01:17:00 PM »

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Projecting points on polylines and determining side
« Reply #2 on: May 04, 2013, 01:26:17 PM »
For straight segments you can also test the whether the sine of the angle between the segment and given point is positive or negative:

Code - Auto/Visual Lisp: [Select]
  1. (sin (- (angle <segment-start> <given-point>) (angle <segment-start> <segment-end>)))

If the above is positive, the point lies to the left of the segment; if negative, to the right.

XXL1966

  • Guest
Re: Projecting points on polylines and determining side
« Reply #3 on: May 04, 2013, 01:32:37 PM »
thx for the fast replies. But i still need the segment the point is projected on, this doesn't result from vlax-curve-getClosestPointTo. Is there a VLISP function that results the segment with a given point (result of vlax-curve-getClosestPointTo) on the curve ?

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Projecting points on polylines and determining side
« Reply #4 on: May 04, 2013, 01:43:19 PM »
But i still need the segment the point is projected on, this doesn't result from vlax-curve-getClosestPointTo. Is there a VLISP function that results the segment with a given point (result of vlax-curve-getClosestPointTo) on the curve ?

Retrieving the segment is relatively easy:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / en pa pt )
  2.     (if
  3.         (and
  4.             (setq pt (getpoint "\nPoint: "))
  5.             (setq en (car (entsel "\nPolyline: ")))
  6.             (= "LWPOLYLINE" (cdr (assoc 0 (entget en))))
  7.         )
  8.         (progn
  9.             (setq pt (vlax-curve-getclosestpointto en (trans pt 1 0))
  10.                   pa (vlax-curve-getparamatpoint en pt)
  11.             )
  12.             (entmake (list '(0 . "POINT") (cons 10 (vlax-curve-getpointatparam en (fix pa)))))
  13.             (entmake (list '(0 . "POINT") (cons 10 (vlax-curve-getpointatparam en (1+ (fix pa))))))
  14.         )
  15.     )
  16.     (princ)
  17. )

XXL1966

  • Guest
Re: Projecting points on polylines and determining side
« Reply #5 on: May 04, 2013, 01:59:27 PM »
thx !

will have a look into this VLAX functions.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Projecting points on polylines and determining side
« Reply #6 on: May 04, 2013, 03:45:36 PM »
Here is a quick draft of a possible program for this task:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:sidetest( / en p1 p2 pa pt )
  2.     (if
  3.         (and
  4.             (setq pt (getpoint "\nPoint to test: "))
  5.             (setq en (car (entsel "\nLWPolyline: ")))
  6.             (= "LWPOLYLINE" (cdr (assoc 0 (entget en))))
  7.         )
  8.         (progn
  9.             (setq p1 (vlax-curve-getclosestpointto en (trans pt 1 0))
  10.                   pa (vlax-curve-getparamatpoint en p1)
  11.             )
  12.             (if (equal '(0.0 0.0 0.0) (vlax-curve-getsecondderiv en pa) 1e-8)
  13.                 (setq p1 (vlax-curve-getpointatparam en (fix pa))
  14.                       p2 (vlax-curve-getpointatparam en (1+ (fix pa)))
  15.                 )
  16.                 (setq p2 (mapcar '+ p1 (vlax-curve-getfirstderiv en pa)))
  17.             )
  18.             (alert (strcat "\nPoint is on " (whichside? pt p1 p2) " of polyline."))
  19.         )
  20.     )
  21.     (princ)
  22. )
  23.  
  24. (defun whichside? ( givenpoint point1 point2 )
  25.     (if (minusp (sin (- (angle point1 givenpoint) (angle point1 point2))))
  26.         "RIGHT"
  27.         "LEFT"
  28.     )
  29. )

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Projecting points on polylines and determining side
« Reply #7 on: May 04, 2013, 04:01:41 PM »
            (entmake (list '(0 . "POINT") (cons 10 (vlax-curve-getpointatparam en (fix pa)))))
            (entmake (list '(0 . "POINT") (cons 10 (vlax-curve-getpointatparam en (1+ (fix pa))))))

Bad programmer, bad.

XXL1966

  • Guest
Re: Projecting points on polylines and determining side
« Reply #8 on: May 05, 2013, 05:18:39 AM »
ah, the master pops up everywhere ;-)

with quirky polylines you mean like having identical vertices etc ?

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Projecting points on polylines and determining side
« Reply #9 on: May 05, 2013, 09:09:21 AM »
with quirky polylines you mean like having identical vertices etc ?

Lee's code assumes that vertex parameters are (consecutive) integers, which is not guaranteed.

TheMaster

  • Guest
Re: Projecting points on polylines and determining side
« Reply #10 on: May 09, 2013, 10:26:34 PM »
Actually, I think that code may have a more significant problem with edge-cases involving polyines that are not parallel to the UCS XY plane.

Code: [Select]
(vlax-curve-getParamAtPoint (vlax-curve-getClosestPointTo (cadr (entsel "\nPick polyline: "))))

will not necessarily give the correct result if the polyline is not in the XY plane of the current UCS.

The pick point returned by (entsel) is always in the UCS XY plane, making it view-dependent, which means that it may only appear to be closer to the desired vertex in the current view projection, but can actually be closer to another vertex.

AFAIK, the correct and only completely-reliable way to acquire a vertex is via (ssget ":S") and (ssnamex)