aloy Posted September 12, 2017 Share Posted September 12, 2017 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 Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 12, 2017 Share Posted September 12, 2017 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.")) ) Quote Link to comment Share on other sites More sharing options...
aloy Posted September 12, 2017 Author Share Posted September 12, 2017 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 Quote Link to comment Share on other sites More sharing options...
BIGAL Posted September 12, 2017 Share Posted September 12, 2017 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) Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 12, 2017 Share Posted September 12, 2017 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. Quote Link to comment Share on other sites More sharing options...
aloy Posted September 12, 2017 Author Share Posted September 12, 2017 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 Quote Link to comment Share on other sites More sharing options...
aloy Posted September 12, 2017 Author Share Posted September 12, 2017 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))) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 12, 2017 Share Posted September 12, 2017 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))))) ) Quote Link to comment Share on other sites More sharing options...
aloy Posted September 13, 2017 Author Share Posted September 13, 2017 Thanks LM. I will try this also. I am sure it would work. Pretty difficult to understand the last line though. Quote Link to comment Share on other sites More sharing options...
poulhein Posted September 13, 2017 Share Posted September 13, 2017 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)) ) ) Quote Link to comment Share on other sites More sharing options...
BIGAL Posted September 14, 2017 Share Posted September 14, 2017 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. Quote Link to comment Share on other sites More sharing options...
aloy Posted September 15, 2017 Author Share Posted September 15, 2017 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 Quote Link to comment Share on other sites More sharing options...
aloy Posted September 15, 2017 Author Share Posted September 15, 2017 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 Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted September 15, 2017 Share Posted September 15, 2017 (not(LM:clockwise-p a c b)) ? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 15, 2017 Share Posted September 15, 2017 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 Quote Link to comment Share on other sites More sharing options...
aloy Posted September 16, 2017 Author Share Posted September 16, 2017 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 Quote Link to comment Share on other sites More sharing options...
aloy Posted September 16, 2017 Author Share Posted September 16, 2017 Hi hanhphuc, Your line does not work as it return T even when points do not exist. Thanks. Aloy Quote Link to comment Share on other sites More sharing options...
aloy Posted September 16, 2017 Author Share Posted September 16, 2017 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 Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 16, 2017 Share Posted September 16, 2017 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. Quote Link to comment Share on other sites More sharing options...
aloy Posted September 16, 2017 Author Share Posted September 16, 2017 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 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.