Author Topic: How to determine side of line when mouse move ?  (Read 3844 times)

0 Members and 1 Guest are viewing this topic.

kruuger

  • Swamp Rat
  • Posts: 637
How to determine side of line when mouse move ?
« on: February 21, 2011, 02:58:36 AM »
Hello Everyone,

I wrote a small routine. It is outside corner millwork connection (0.75 X 0.75 panels).
Program is working but joint preview (grdraw) is not shown correct in 3rd and 4th quarter (see picture)

Any tips how to wrote routine to indicates correct side of line when we move cursor (between two point).
Also any suggestion regarding code are welcome.
kruuger

« Last Edit: February 21, 2011, 03:31:18 AM by kruuger »

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: How to determine side of line when mouse move ?
« Reply #1 on: February 21, 2011, 06:41:42 PM »
Hi Kruuger,

How about something along these lines:

Code: [Select]
(defun test ( p1 p3 / a1 f1 p2 q1 q2 q3 q4 ) (setq a1 (angle p1 p3))

  (while (= 5 (car (setq p2 (grread t 13 0)))) (redraw)
    (setq p2 (cadr p2)
          f1 (if (< (sin (- (angle p1 p3) (angle p1 p2))) -1e-14) + -)
          q1 (polar p1 a1 0.09375)
          q2 (polar q1 (f1 a1 (* 0.25 pi)) 0.3750)
          q3 (polar q2 (f1 a1 (* 1.75 pi)) 0.1875)
          q4 (polar q3 (f1 a1 (* 1.25 pi)) 0.1875)
    )
    (grvecs (list -1 p1 q1 q1 q2 q2 q3 q3 q4 q4 p3))
  )
  (redraw) (if (= 3 (car p2)) (list p1 q1 q2 q3 q4 p3))
)

Test Function:
Code: [Select]
(defun c:test ( / p1 p2 )
  (if
    (and
      (setq p (getpoint "\nP1: "))
      (setq q (getpoint "\nP2: " p))
    )
    (test p q)
  )
)

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: How to determine side of line when mouse move ?
« Reply #2 on: February 21, 2011, 06:47:22 PM »
Code: [Select]
(defun AT:TriangleArea (a b c)
  ;; Returns area of three provided points
  ;; If returned value is negative, last point (c) exists on right side of a-b vector
  ;; Alan J. Thompson, 06.09.10
  (/ (- (* (- (car b) (car a)) (- (cadr c) (cadr a)))
        (* (- (cadr b) (cadr a)) (- (car c) (car a)))
     )
     2.
  )
)

or Giles clockwise routine:

Code: [Select]
;; Clockwise-p (gile)
;; evaluates if p1, p2, p3 are clockwise

(defun clockwise-p (p1 p2 p3)
  (< (sin (- (angle p1 p3) (angle p1 p2))) -1e-14)
)
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

hermanm

  • Guest
Re: How to determine side of line when mouse move ?
« Reply #3 on: February 21, 2011, 08:47:24 PM »
Code: [Select]
;;--------------------- aboveline ---------------------------------------
;;      Purpose: given 2D points p1,p2,p3
;;               determines if p3 lies above or below the line defined
;;               by p1,p2
;;      Needs: two points p1,p2 to determine the line
;;             point p3 to test
;;             fuzz to determine required proximity to line
;;      Returns: 1 if p3 is above the line
;;               0 if on the line
;;              -1 if below the line
;;               nil if the line is vertical or p1,p2 are coincident
;;----------------------------------------------------------------
(defun aboveline (p1 p2 p3 fuzz / m ret y3 yprime)
  (if (= (car p1) (car p2)) (setq ret nil)
    (progn
      (setq m (/ (- (cadr p2) (cadr p1)) (- (car p2) (car p1)))
            yprime (+ (cadr p1) (* m (- (car p3) (car p1))))
            y3 (cadr p3)
      )
      (cond ((equal y3 yprime fuzz) (setq ret 0))
            ((> y3 yprime) (setq ret 1))
            ((< y3 yprime) (setq ret -1))
      );cond
    );progn
  );if
  ret
);aboveline

;;--------------------- rightofline ---------------------------------------
;;      Purpose: given 2D points p1,p2,p3
;;               determines if p3 lies right or left of the line defined
;;               by p1,p2
;;      Needs: two points p1,p2 to determine the line
;;             point p3 to test
;;             fuzz to determine required proximity to line
;;      Returns: 1 if p3 is right of the line
;;               0 if on the line
;;              -1 if left of the line
;;               nil if the line is horizontal or p1,p2 are coincident
;;----------------------------------------------------------------
(defun rightofline (p1 p2 p3 fuzz / m ret x3 xprime)
  (if (= (car p1) (car p2)) (setq ret nil)
    (progn
      (setq m (/ (- (cadr p2) (cadr p1)) (- (car p2) (car p1)))
            xprime (+ (car p1) (/ (- (cadr p3) (cadr p1)) m))
            x3 (car p3)
      )
      (cond ((equal x3 xprime fuzz) (setq ret 0))
            ((> x3 xprime) (setq ret 1))
            ((< x3 xprime) (setq ret -1))
      );cond
    );progn
  );if
  ret
);rightofline


kruuger

  • Swamp Rat
  • Posts: 637
Re: How to determine side of line when mouse move ?
« Reply #4 on: February 22, 2011, 12:09:21 PM »
thanks guys for your codes.
all of them can be used with my routine. :-)

there is one problem. i can't understand codes in 100%  :-(
can you gave some link where i can read about your methods.

thx again
kruuger



Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: How to determine side of line when mouse move ?
« Reply #5 on: February 22, 2011, 03:32:11 PM »
To understand how my code works, consider this function to return the angle to the left of three points:

Code: [Select]
(defun LM:GetLeftAngle ( p1 p2 p3 )
  (rem (+ pi pi (- (angle p2 p1) (angle p2 p3))) (+ pi pi))
)

Now, to determine whether such three points are clockwise/anticlockwise we just have to test whether the 'left' angle (as returned by the above) is greater than/less than pi. Notice that sin returns positive for angles 0 < x < pi and negative for those pi < x < 2pi

kruuger

  • Swamp Rat
  • Posts: 637
Re: How to determine side of line when mouse move ?
« Reply #6 on: February 22, 2011, 04:41:43 PM »
To understand how my code works, consider this function to return the angle to the left of three points:

Code: [Select]
(defun LM:GetLeftAngle ( p1 p2 p3 )
  (rem (+ pi pi (- (angle p2 p1) (angle p2 p3))) (+ pi pi))
)

Now, to determine whether such three points are clockwise/anticlockwise we just have to test whether the 'left' angle (as returned by the above) is greater than/less than pi. Notice that sin returns positive for angles 0 < x < pi and negative for those pi < x < 2pi
uff, i got this. what's still bother me is -1e-14 (seams to work with 0) and alanjt & hermanm code. we divide, subtract some value and get direction  :|

thanks Lee
kruuger

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: How to determine side of line when mouse move ?
« Reply #7 on: February 22, 2011, 05:21:34 PM »

chlh_jd

  • Guest
Re: How to determine side of line when mouse move ?
« Reply #8 on: February 23, 2011, 12:15:35 AM »
Hi,
Here's another way
Code: [Select]
;;;get distance of pt & Vector(pt1->pt2),if return d >0 then the point is at right side of the vector, if <0 at letf side ,if =0 in it
;;;it can be used in Calculating the Convex hull of points
(defun ss-get-d (pt pt1 pt2 / A B C D)
  (setq A (- (cadr pt2) (cadr pt1))
B (- (car pt1) (car pt2))
C (- (* (car pt2) (cadr pt1)) (* (car pt1) (cadr pt2)))
  )
  (if (> (+ (* A A) (* B B)) 0)
    (setq d (* (/ 1 (sqrt (+ (* A A) (* B B))))
      (+ (* (car pt) A) (* (cadr pt) B) C)
   )
    )
    (setq d 0)
  )
  d
)
Use trans fun method
Code: [Select]
(defun ss-get-da (pt pt1 pt2)
  (car (trans pt 0 (mapcar '- pt1 pt2)))
  )
« Last Edit: February 23, 2011, 12:30:45 AM by chlh_jd »

kruuger

  • Swamp Rat
  • Posts: 637

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: How to determine side of line when mouse move ?
« Reply #10 on: February 23, 2011, 03:30:06 PM »
Use trans fun method
Code: [Select]
(defun ss-get-da (pt pt1 pt2)
  (car (trans pt 0 (mapcar '- pt1 pt2)))
  )

A nice method, I think perhaps:

Code: [Select]
(defun LM:Clockwise-p ( p1 p2 p3 )
  ( (lambda ( n ) (< (- (car (trans p2 0 n)) (car (trans p1 0 n))) -1e-14)) (mapcar '- p1 p3))
)

Since the normal is defined relative to the origin  :-)