Jump to content

Position of point with respect to a line


aloy

Recommended Posts

Hello everybody,

 

I have three points A(x1,y1), B(x2, y2) and C(x3, y3). How can I find which side C is when looked from A to B. That is whether point C is on the left or right of line AB by a calculation with the coordinates of the three points.

 

Thanks in advance.

 

Aloy

Link to comment
Share on other sites

  • Replies 23
  • Created
  • Last Reply

Top Posters In This Topic

  • aloy

    13

  • Lee Mac

    4

  • Tharwat

    3

  • BIGAL

    2

Top Posters In This Topic

Posted Images

Hi Aloy,

 

Please try this.

(and (setq a (getpoint "\nSpecify point A :"))
    (setq b (getpoint "\nSpecify point B :" a))
    (setq c (getpoint "\nSpecify point C :"))
    (alert (strcat "Point resides on the " (if (minusp (sin (- (angle a b) (angle a c)))) "Left" "Right") " Side."))
    )

Link to comment
Share on other sites

Thanks Tharwat. Actually I wanted the three points to be assigned by a program to handle area calculations automatically for cut and fills in earthworks. I think I can make use of the last line.

Thanks again.

 

Aloy

Link to comment
Share on other sites

There is a also a vector answer similar to Tharwat solution I know I used it but am struggling to find it, uses x & y

 

Found an example it returns a + or - answer. Now to find my lisp version.

 

(p2.X-p1.X)*(p3.Y-p1.Y)-(p2.Y-p1.Y)*(p3.X-p1.X)

Link to comment
Share on other sites

Thanks Tharwat. Actually I wanted the three points to be assigned by a program to handle area calculations automatically for cut and fills in earthworks. I think I can make use of the last line.

Thanks again.

 

Aloy

 

You are welcome Aloy and good luck.

Link to comment
Share on other sites

Hi Bigal,

I found similar vector cross product thing when I searched. But I thought it is too long. Besides it involves determinants and transpose etc. Thanks for pointing out.

 

Aloy

Link to comment
Share on other sites

Hi Tharwat,

It works very nicely. I will post the code and the drawing that was generated for working out the areas of cuts and fills auomatically.

 

Here x2 is point of intersection at the end of cut or fill, q3 is A, q4 is B and pz is C. It gave me the sum of two cuts and one fill. You saved lot of time for me.

 

Aloy

(if x2 (progn (setq i2 (angle q3 q4)) (setq i3(angle q3 pz))))    
   (if (and x2 (and (> (sin (- i2 i3)) 0.0))) (setq fill (+ fill a)))
   (if (and x2 (and (< (sin (- i2 i3)) 0.0))) (setq cut (+ cut a)))

earthwork.jpg

Link to comment
Share on other sites

Here's another way, using the vector cross product:

(defun c:test ( / a b c )
   (if (and (setq a (getpoint "\n1st point of line: "))
            (setq b (getpoint "\n2nd point of line: " a))
            (setq c (getpoint "\nPoint to test: "))
       )
       (LM:clockwise-p a c b)
   )
)

;; Clockwise-p - Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented

(defun LM:clockwise-p ( a b c )
   (apply '> (mapcar '* (mapcar '- c a) (reverse (mapcar '- b a '(0 0)))))
)

Link to comment
Share on other sites

give this a try

;determines the orientation on the basis of pointaxis P1 -> P2
;Points in current UCS
;example function:

;(setq
;  pt1 (getpoint "\nfirst point: ")
;  pt2 (getpoint "\nsecond point: " pt1)

;(while
;  (/= (car (setq pt3 (grread 'T 1 0))) 3)
;  (if (leftright-p pt1 pt2 (cadr pt3))
;    (princ "\nyou are left: ")
;    (princ "\nyou are right: ")
;  )

;returns T=left nil=right

(defun leftright-p
 ( pt1 pt2 pt3 /
   area
 )
 (setq area
   (+
     (- (* (car pt1) (cadr pt2)) (* (cadr pt1) (car pt2)))
     (- (* (cadr pt1) (car pt3)) (* (car pt1) (cadr pt3)))
     (- (* (car pt2) (cadr pt3)) (* (car pt3) (cadr pt2)))
   )
 )
 (and
   (> area 0)
   (not (equal area 0 0.0000001))
 )
)

Link to comment
Share on other sites

My $0.05

left or right of line AB ?

 

Its important that the answers above are for two points hence implying a direction.

 

Is the point left or right of a line ? This is dependant on the drawn direction of the line, hence an easy way around this if required for a "line" answer is to pick an implied pt nera the end and swap the two points to get the correct direction if required. This method only requires 1 pick.

Link to comment
Share on other sites

Hi Bigal

 

Your solution seem to make it possible for me to use the method suggested by Lee Mac. That is, if in the first pass it returns T then the third point is on left and if after reversing the direction it returns T then the point is on the right. I cannot use a nil value as I have to combine with another test (the value of x2 as in my previous post) which may yield nil. I will test this method using Lee Mac method and post the full details of what I am going to do with the solution.

Thanks.

Aloy

Link to comment
Share on other sites

LM,

I have assigned points p, q and r which exist in the program as follows:

 

(defun c:test ( / a b c )
   (if (and (setq a p)
            (setq b q)
            (setq c r)
       )
       (LM:clockwise-p a c b)
   )
)

;; Clockwise-p - Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented

(defun LM:clockwise-p ( a b c )
   (apply '> (mapcar '* (mapcar '- c a) (reverse (mapcar '- b a '(0 0)))))
)

It gives me T

How to make it return nil when p and q are swapped?.

Thanks.

Aloy

Link to comment
Share on other sites

How to make it return nil when p and q are swapped?

 

I'm not sure that I understand your question - observe the following:

_$ (setq p '(0 0))
(0 0)
_$ (setq q '(0 2))
(0 2)
_$ (setq r '(1 1))
(1 1)

_$ (LM:clockwise-p p r q)
nil
_$ (LM:clockwise-p q r p)
T

Link to comment
Share on other sites

Hi LM,

I tried the following to get T when it is both clockwise and anti-clockwise using your code:

(defun test1 ( / a b c )
   (if (and (setq a p)
            (setq b q)
            (setq c r)
       )
       (LM:clockwise-p a c b)
   )
)

;; Clockwise-p - Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented

(defun LM:clockwise-p ( a b c )
   (apply '> (mapcar '* (mapcar '- c a) (reverse (mapcar '- b a))))
)

When anti-clockwise:

(defun test2 ( / a b c )
   (if (and (setq a p)
            (setq b q)
            (setq c r)
       )
       (LM:anti-clockwise-p a b c)
   )
)

;;Anti- Clockwise-p 
;; Returns T if p1,p2,p3 are anti-clockwise oriented

(defun LM:anti-clockwise-p ( a b c )
   (apply '> (mapcar '* (mapcar '- c a) (reverse (mapcar '- b a))))
)

I used the following code to get the same result as using the sin formula as above post:

(if (and x (test2)) (setq fill(+ fill a)))

(if (and x (test1)) (setq cut(+ cut a)))

 

In this case x is the point of intersection if it exist and 'a' is the area returned by autocad area command.

The '(0 0) was not necessary

Link to comment
Share on other sites

Hi Paulhein,

This code does not work in my case. Please follow the suggested code by Lee Mac and my suggestions there to in my latest post.

 

Thanks for trying to help.

Aloy

Link to comment
Share on other sites

Hi LM,

I tried the following to get T when it is both clockwise and anti-clockwise using your code:

(defun test1 ( / a b c )
   (if (and (setq a p)
            (setq b q)
            (setq c r)
       )
       (LM:clockwise-p a c b)
   )
)

;; Clockwise-p - Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented

(defun LM:clockwise-p ( a b c )
   (apply '> (mapcar '* (mapcar '- c a) (reverse (mapcar '- b a))))
)

When anti-clockwise:

(defun test2 ( / a b c )
   (if (and (setq a p)
            (setq b q)
            (setq c r)
       )
       (LM:anti-clockwise-p a b c)
   )
)

;;Anti- Clockwise-p 
;; Returns T if p1,p2,p3 are anti-clockwise oriented

(defun LM:anti-clockwise-p ( a b c )
   (apply '> (mapcar '* (mapcar '- c a) (reverse (mapcar '- b a))))
)

 

Hi Aloy,

 

Please excuse my frustration, but either you have misunderstood my code, or have misunderstood the example I provided in my earlier post.

 

I would suggest that you cease modifying the function and revisit the example I posted above.

 

The '(0 0) was not necessary

 

Yes it is. If 3D points are supplied, the function will perform incorrectly without this expression.

Link to comment
Share on other sites

Hi Lee Mac,

But for my purpose I need a T or a value other than nil when the point is on the other side. When the return value is nil I am unable to combine with another variable whose value will be T or nil. However I found a way of using your code for that purpose. Sorry about the '(0 0) point; I was dealing only with 2D as in calculation of earthworks using a cross section in old fashion way. Checking this value is an automated process ( the ground levels are also picked along horizontal alignment as well as cross sections from a TIN surface automatically). I will use the 'sin' method instead of modifying your code though both seem equally fast when handling many sections at a time.

Regards,

Aloy

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...