TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Marc'Antonio Alessi on March 17, 2020, 04:57:53 PM

Title: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 17, 2020, 04:57:53 PM
Maybe the solution is simple, I know : C P1 P2    and I have to calculate: P1o p2o  that is the closest orthogonal point
Title: Re: Geometrical question: closest orthogonal point
Post by: Stefan on March 17, 2020, 05:32:34 PM
In the last picture, isn't P2o = P1o?

Anyway, for P1o alone
Code - Auto/Visual Lisp: [Select]
  1. (setq p01 (polar c (* 0.5 pi (fix (+ 0.5 (/ (angle c p1) pi 0.5)))) (distance c p1)))

Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 17, 2020, 05:56:35 PM
I need to calculate the closest orthogonal point of the closest point to the axis, then the opposite at 90° (sorry for my english).
Title: Re: Geometrical question: closest orthogonal point
Post by: Stefan on March 17, 2020, 06:13:08 PM
What about this
Title: Re: Geometrical question: closest orthogonal point
Post by: MP on March 17, 2020, 06:55:54 PM
If you bisect the angles for vectors C->p1 and C->p2 the resulting vector C->P3 lies in one quadrant (3), said quadrant bounded by it's orthogonal points P1o and P2o. Make sense? Or did I miss your intention?

Title: Re: Geometrical question: closest orthogonal point
Post by: BIGAL on March 17, 2020, 07:59:20 PM
Like MP goggle which quadrant is point in lsp then 0 1 2 or 3 gives ortho angle.
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 18, 2020, 04:36:16 AM
I apologize for the delay (time zone), maybe this:
Code: [Select]
; the angle between the lines never exceeds 180 degrees
(setq CntPnt '(10. 10. 0.) Pnt001 '(208.14 37.20 0.)  Pnt002 '(191.12 -74.84 0.))

Command: (setq Ang001 (angle CntPnt Pnt001)) =>  0.136424
Command: (setq Ang002 (angle CntPnt Pnt002)) =>  5.84512
Command: (setq Deg090 (/ pi 2.))              =>  1.5708

Command: (if (> Ang001 Ang002)
(_>   (setq Ang003 (+ Ang001    (/ (- Ang002 Ang001) 2.00)))
(_>   (setq Ang003 (+ Ang001 pi (/ (- Ang002 Ang001) 2.00)))
(_> )         => 6.13236

(cond
 ( (and (>= Ang003 0)      (>= Deg090        Ang003)) (list 0                   Deg090) )
 ( (and (>= Ang003 Deg090) (>= pi            Ang003)) (list Deg090                  pi) )
 ( (and (>= Ang003 pi)     (>= (+ pi Deg090) Ang003)) (list pi           (+ pi Deg090)) )
 ( T                                                  (list (+ pi Deg090)            0) )
)               =>  (4.71239 0)
the ultimate goal is to draw a clove in the quadrant more occupied.
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 18, 2020, 11:58:00 AM
This works in many conditions but not in all:
Code: [Select]
(defun ALE_Math_OrthoAngles (CntPnt Pnt001 Pnt002 / Ang001 Ang002 Ang003 Deg090)
  (setq
    Deg090 (/ pi 2.)
    Ang001 (angle CntPnt Pnt001)
    Ang002 (angle CntPnt Pnt002)
    Ang003 (+ Ang001 (/ (- Ang002 Ang001) 2.00))
  )
  (cond
    ( (and (>= Ang003 0)      (>= Deg090        Ang003)) (cons 0                   Deg090) )
    ( (and (>= Ang003 Deg090) (>= pi            Ang003)) (cons Deg090                  pi) )
    ( (and (>= Ang003 pi)     (>= (+ pi Deg090) Ang003)) (cons pi           (+ pi Deg090)) )
    ( T                                                  (cons (+ pi Deg090)            0) )
  )
)
Code: [Select]
(defun C:Test_OrthoAngles ( / CntPnt Pnt001 Pnt011 Pnt002 Pnt012 OutLst Dst001 Dst002)
  (setq
    CntPnt (GetPoint "\nC: ")
    Pnt001 (GetPoint "\nP: ")
    Pnt002 (GetPoint "\nP: ")
    Dst001 (distance CntPnt Pnt001)
    Dst002 (distance CntPnt Pnt002)
    OutLst (ALE_Math_OrthoAngles CntPnt Pnt001 Pnt002)
    Pnt011 (polar CntPnt (car OutLst) Dst001)
    Pnt012 (polar CntPnt (cdr OutLst) Dst002)
  ) 
  (entmake (list '(0 . "CIRCLE") (cons 40 20) (cons 10 Pnt011)))
  (entmake (list '(0 . "CIRCLE") (cons 40 20) (cons 10 Pnt012)))
)
Title: Re: Geometrical question: closest orthogonal point
Post by: Dlanor on March 18, 2020, 12:23:52 PM
The two failures are caused by you not allowing for angles either side of 0.0

You need something like this

Code - Auto/Visual Lisp: [Select]
  1.     Ang003 (if (or (and (< 0.0 Ang001 Deg090) (< (* pi 1.5) Ang002 (* pi 2.0)))
  2.                    (and (< 0.0 Ang002 Deg090) (< (* pi 1.5) Ang001 (* pi 2.0)))
  3.                )
  4.              (+ Ang001 (/ (+ (* pi 2.0) (- Ang002 Ang001)) 2.00))
  5.              (+ Ang001 (/ (- Ang002 Ang001) 2.00))
  6.            )
  7.  
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 18, 2020, 04:16:18 PM
The two failures are caused by you not allowing for angles either side of 0.0

You need something like this

Code - Auto/Visual Lisp: [Select]
  1.     Ang003 (if (or (and (< 0.0 Ang001 Deg090) (< (* pi 1.5) Ang002 (* pi 2.0)))
  2.                    (and (< 0.0 Ang002 Deg090) (< (* pi 1.5) Ang001 (* pi 2.0)))
  3.                )
  4.              (+ Ang001 (/ (+ (* pi 2.0) (- Ang002 Ang001)) 2.00))
  5.              (+ Ang001 (/ (- Ang002 Ang001) 2.00))
  6.            )
  7.  
Thanks.  :-)   Do you have an idea also for this?
Title: Re: Geometrical question: closest orthogonal point
Post by: Dlanor on March 18, 2020, 05:41:01 PM
The reason is the same. I cannot test but maybe this does both

Code - Auto/Visual Lisp: [Select]
  1.     Ang003 (if (> pi (abs (- Ang002 Ang001)))
  2.              (+ Ang001 (/ (+ (* pi 2.0) (- Ang002 Ang001)) 2.00))
  3.              (+ Ang001 (/ (- Ang002 Ang001) 2.00))
  4.            )
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 19, 2020, 05:50:06 AM
I implemented most of the MP's suggestion to consider the bisect. It is not very elegant but it works. Thank you.
Code: [Select]
(defun ALE_Math_OrthoAngles (CntPnt Pnt001 Pnt002 / Ang001 Ang002 Ang003 AngFlg Deg090 Deg270)
  (setq
    Deg090 (/ pi 2.)
    Deg270 (+ pi Deg090)
    Ang001 (angle CntPnt Pnt001)
    Ang002 (angle CntPnt Pnt002)
    AngFlg (> (abs (- Ang001 Ang002)) pi)
    Ang003 (if (> Ang001 Ang002)
              (+ (/ (- Ang001 Ang002) 2.) Ang002)
              (+ (/ (- Ang002 Ang001) 2.) Ang001)
           )
  )
  (and AngFlg (setq Ang003 (+ Ang003 pi)))
  (and (> Ang003 (+ pi pi) (setq Ang003 (rem Ang003 (+ pi pi)))))
  (cond
    ( (and (>= Ang003      0) (>= Deg090 Ang003)) (cons 0      Deg090) )
    ( (and (>= Ang003 Deg090) (>= pi     Ang003)) (cons Deg090     pi) )
    ( (and (>= Ang003     pi) (>= Deg270 Ang003)) (cons pi     Deg270) )
    ( T                                           (cons Deg270      0) )
  )
)
Title: Re: Geometrical question: closest orthogonal point
Post by: BIGAL on March 21, 2020, 02:24:14 AM
Lines must be in two adjacent quadrants ? Else multi answers.
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 21, 2020, 07:03:03 AM
Lines must be in two adjacent quadrants ? Else multi answers.
Show me an example. Thanks.
Title: Re: Geometrical question: closest orthogonal point
Post by: T.Willey on March 23, 2020, 03:51:52 PM
If I understand, this should be what you are looking for.  It will return a list of the quadrant angles.

Code - Lisp: [Select]
  1. (defun test ( cpt pt1 pt2 / ang1 ang2 a1 a2 )
  2.     (defun findClosestQuadrantAngle ( ang exclude / a90 a270 )
  3.         (setq a90 (* pi 0.5))
  4.         (setq a270 (* pi 1.5))
  5.         (setq ang (rem ang (* pi 2.)))
  6.         (cond
  7.             ((<= 0.0 ang a90)
  8.                 (if exclude
  9.                     (if (equal exclude 0. 1e-4) a90 0.)
  10.                     (if (<= ang (* pi 0.25)) 0. a90)
  11.                 )
  12.             )
  13.             ((<= a90 ang pi)
  14.                 (if exclude
  15.                     (if (equal exclude a90 1e-4) pi a90)
  16.                     (if (<= ang (* pi 0.75)) a90 pi)
  17.                 )
  18.             )
  19.             ((<= pi ang a270)
  20.                 (if exclude
  21.                     (if (equal exclude pi 1e-4) a270 pi)
  22.                     (if (<= ang (* pi 1.25)) pi a270)
  23.                 )
  24.             )
  25.             (t
  26.                 (if exclude
  27.                     (if (equal exclude a270 1e-4) 0. a270)
  28.                     (if (<= ang (* pi 1.75)) a270 0.0)
  29.                 )
  30.             )
  31.         )
  32.     )
  33.     (setq ang1 (angle cpt pt1))
  34.     (setq a1 (findClosestQuadrantAngle ang1 nil))
  35.     (setq ang2 (angle cpt pt2))
  36.     (setq a2 (findClosestQuadrantAngle ang2 a1))
  37.     (list a1 a2)
  38. )
  39.  
Title: Re: Geometrical question: closest orthogonal point
Post by: Lee Mac on March 23, 2020, 04:04:38 PM
Which points should be returned for a scenario in which each given point lies equidistant within each quadrant? e.g.:

(http://lee-mac.com/swamp/quad.png)
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 23, 2020, 04:45:33 PM
If I understand, this should be what you are looking for.  It will return a list of the quadrant angles.

Code - Lisp: [Select]
  1. ....
  2.  
I have tried your version, can you tell me in which situations does it return a different result?
Thanks.
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 23, 2020, 04:53:03 PM
Which points should be returned for a scenario in which each given point lies equidistant within each quadrant? e.g.:

(http://lee-mac.com/swamp/quad.png)
Which points should be returned for a scenario in which each given point lies equidistant within each quadrant? e.g.:


The points returned have no valid logic, they mainly depend on how this is written:

Code: [Select]
  (cond
    ( (and (>= Ang003      0) (>= Deg090 Ang003)) (cons 0      Deg090) )
    ( (and (>= Ang003 Deg090) (>= pi     Ang003)) (cons Deg090     pi) )
    ( (and (>= Ang003     pi) (>= Deg270 Ang003)) (cons pi     Deg270) )
    ( T                                           (cons Deg270      0) )
  )

Edit: maybe this is better:
  (cond
    ( (and (> Ang003      0) (>= Deg090 Ang003)) (cons 0      Deg090) )
    ( (and (> Ang003 Deg090) (>= pi     Ang003)) (cons Deg090     pi) )
    ( (and (> Ang003     pi) (>= Deg270 Ang003)) (cons pi     Deg270) )
    ( T                                          (cons Deg270      0) )
  )


In my scenario I don't have this problem but if you have a suggestion I will be happy to adopt it.
Thank you
Title: Re: Geometrical question: closest orthogonal point
Post by: T.Willey on March 23, 2020, 06:14:02 PM
If I understand, this should be what you are looking for.  It will return a list of the quadrant angles.

Code - Lisp: [Select]
  1. ....
  2.  
I have tried your version, can you tell me in which situations does it return a different result?
Thanks.

Here are returned results (no image)
Quote
Command: (test (getpoint) (getpoint) (getpoint))
(0.0 4.71239)

Command: (test (getpoint) (getpoint) (getpoint))
(4.71239 3.14159)

Command: (test (getpoint) (getpoint) (getpoint))
(0.0 4.71239)

You can see that they return different results for where points are picked.  My code does not allow for the two returned angles to be the same value, so if they were going to be the same value, it returns the other angle associated with that quadrant.

Quote
Command: (test (getpoint) (getpoint) (getpoint))
(3.14159 1.5708)

This is the result for picking the same point in the second (top-left) quadrant.  You get the Pi (180 degrees) and Pi/2 (90 degrees).

Hope that makes sense.
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 24, 2020, 04:43:54 AM
@T.Willey these are my results:
Title: Re: Geometrical question: closest orthogonal point
Post by: T.Willey on March 24, 2020, 10:19:47 AM
Is that not was is desired, Marc?  Did I not understand correctly?
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 24, 2020, 11:14:43 AM
Is that not was is desired, Marc?  Did I not understand correctly?
Yes that's what I wanted to achieve. What I don't understand is the difference or advantage of your version which is much more complicated.
Thanks for your patience.  :-)
Edit: Maybe I understood: the correct sequence based on the selected points ... Yes it is a more appropriate result!
Title: Re: Geometrical question: closest orthogonal point
Post by: T.Willey on March 24, 2020, 12:51:52 PM
I don't think mine is very complicated.  I test to see which quadrant the point lies, then see if it's greater than the 45 degree line of said quadrant and return the appropriate angle.  But for the second angle I make sure that if they are in the same quadrant, you get the second angle of the quadrant so that the same angle is not returned for both.  You're welcome.  This is a place of learning, so asking why one coded it a certain way is fine.  I hope my explanation make sense to you (though it looks like you figured it out before I posted this message).
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 24, 2020, 01:19:04 PM
I don't think mine is very complicated.  I test to see which quadrant the point lies, then see if it's greater than the 45 degree line of said quadrant and return the appropriate angle.  But for the second angle I make sure that if they are in the same quadrant, you get the second angle of the quadrant so that the same angle is not returned for both.  You're welcome.  This is a place of learning, so asking why one coded it a certain way is fine.  I hope my explanation make sense to you (though it looks like you figured it out before I posted this message).
Ok, thanks for the explanation, I have to understand if for my use it is a useful twining. Basically I have to draw an arc in the quadrant where the angle bisector lies (which is always less than 180 degrees).  :-)
Title: Re: Geometrical question: closest orthogonal point
Post by: Lee Mac on March 24, 2020, 02:57:52 PM
Assuming I've understood the requirements, here's my suggestion:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( c p q / a b d )
  2.     (setq a (angle '(0 0) (mapcar '+ (mapcar '- p c) (mapcar '- q c)))
  3.           b (+ (if (< 0 (sin a)) 0 pi) (if (< 0 (* (sin a) (cos a))) 0 (/ pi 2)))
  4.           d (distance c p)
  5.     )
  6.     (list (polar c b d) (polar c (+ b (/ pi 2)) d))
  7. )

A program to test:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / c p q )
  2.     (if (and (setq c (getpoint "\nCentre: "))
  3.              (setq p (getpoint c "\nP1: "))
  4.              (setq q (getpoint c "\nP2: "))
  5.         )
  6.         (foreach x (foo c p q) (entmake (list '(0 . "POINT") (cons 10 (trans x 1 0)))))
  7.     )
  8.     (princ)
  9. )

Assumes (= (distance c p) (distance c q)) per the images.
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 24, 2020, 05:32:50 PM
Assuming I've understood the requirements, here's my suggestion:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( c p q / a b d )
  2.     (setq a (angle '(0 0) (mapcar '+ (mapcar '- p c) (mapcar '- q c)))
  3.           b (+ (if (< 0 (sin a)) 0 pi) (if (< 0 (* (sin a) (cos a))) 0 (/ pi 2)))
  4.           d (distance c p)
  5.     )
  6.     (list (polar c b d) (polar c (+ b (/ pi 2)) d))
  7. )

A program to test:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / c p q )
  2.     (if (and (setq c (getpoint "\nCentre: "))
  3.              (setq p (getpoint c "\nP1: "))
  4.              (setq q (getpoint c "\nP2: "))
  5.         )
  6.         (foreach x (foo c p q) (entmake (list '(0 . "POINT") (cons 10 (trans x 1 0)))))
  7.     )
  8.     (princ)
  9. )

Assumes (= (distance c p) (distance c q)) per the images.
Thanks Lee, it seem very good for my needs and can be simply:
Code: [Select]
(defun foo2 ( c p q / a b)
    (setq a (angle '(0 0) (mapcar '+ (mapcar '- p c) (mapcar '- q c)))
          b (+ (if (< 0 (sin a)) 0 pi) (if (< 0 (* (sin a) (cos a))) 0 (/ pi 2)))
    )
    (cons b (+ b (/ pi 2)))
)
Grazie.  :-)
Title: Re: Geometrical question: closest orthogonal point
Post by: Lee Mac on March 24, 2020, 05:40:06 PM
Alternatively, just -
Code - Auto/Visual Lisp: [Select]
  1. (defun foo3 ( c p q / a )
  2.     (setq a (* (/ pi 2) (fix (/ (angle '(0 0) (mapcar '+ (mapcar '- p c) (mapcar '- q c))) (/ pi 2)))))
  3.     (cons a (+ a (/ pi 2)))
  4. )
Title: Re: Geometrical question: closest orthogonal point
Post by: Marc'Antonio Alessi on March 24, 2020, 06:46:24 PM
Alternatively, just -
Code - Auto/Visual Lisp: [Select]
  1. (defun foo3 ( c p q / a )
  2.     (setq a (* (/ pi 2) (fix (/ (angle '(0 0) (mapcar '+ (mapcar '- p c) (mapcar '- q c))) (/ pi 2)))))
  3.     (cons a (+ a (/ pi 2)))
  4. )
More succinct than that I think is not possible!    8-)   Notte.