Author Topic: -={ Challenge }=- Incircle & Circumcircle of a Triangle  (Read 16695 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
-={ Challenge }=- Incircle & Circumcircle of a Triangle
« on: January 21, 2011, 06:14:58 PM »
A nice, fun one for the weekend!  :-)

The Challenge

Function 1: Incircle

Arguments:
p1,p2,p3  =  three distinct, noncollinear WCS points.

Returns:
list of (<center> <radius>), the center & radius of the Incircle of the triangle defined by p1, p2 & p3.

Function 2: Circumcircle

Arguments:
p1,p2,p3  =  three distinct, noncollinear WCS points.

Returns:
list of (<center> <radius>), the center & radius of the Circumcircle of the triangle defined by p1, p2 & p3.


Diagram:

Incircle is shown in Cyan

Circumcircle is shown in Yellow.


Have fun!

Lee

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #1 on: January 21, 2011, 07:38:44 PM »
Hi, Lee, funny question~
Is this three points 3d points, or only consider the XY plane situation?

If only a XY question, this is my geometry solution:),  and also has some formula solution.(will  post later)

if a 3d question, I will solve it by Barycentric Coordinates later.

Function
Code: [Select]
;;Midpoint of two point
(defun q:geo:mid (p1 p2)
  (mapcar '(lambda (x)(/ x 2.))(mapcar '+ p1 p2))
)
;;2d line midnormal
(defun q:geo:line-midnormal(p1 p2 / p)
  (list (setq p (q:geo:mid p1 p2)) (polar p (+ (angle p1 p2) (/ pi 2.0)) 1.0))
)
;;2d angle bisector
(defun q:geo:angle-bisector(p1 p2 p3)
  (list p1 (polar p1 (/ (+ (angle p1 p2) (angle p1 p3)) 2.0) 1.0))
)
;;2d distance from a point to a line
(defun q:geo:dis-point-to-2dline(p p1 p2)
  (distance p (inters p (polar p (+ (angle p1 p2) (/ pi 2.0)) 1.0) p1 p2 nil))
)

;;Find out the incircle of three point (three distinct, noncollinear WCS points)
(defun q:geo:incircle(p1 p2 p3 / l1 l2 p)
  (setq l1 (q:geo:line-midnormal p1 p2) l2 (q:geo:line-midnormal p1 p3))
  (setq p (inters (car l1) (cadr l1) (car l2) (cadr l2) nil))
  (list p (distance p1 p))
)
;;Find out the circumcircle of three point (three distinct, noncollinear WCS points)
(defun q:geo:circumcircle(p1 p2 p3 / l1 l2 p)
  (setq l1 (q:geo:angle-bisector p1 p2 p3) l2 (q:geo:angle-bisector p2 p3 p1))
  (setq p (inters (car l1) (cadr l1) (car l2) (cadr l2) nil))
  (list p (q:geo:dis-point-to-2dline p p1 p2))
)

Test code
Code: [Select]
;;;;;Test function

(defun c:test(/ p1 p2 p3)
 (setq p1 (getpoint) p2 (getpoint) p3 (getpoint))
 (q:entmake:point (car (q:geo:incircle p1 p2 p3)) (getvar "clayer"))
 (q:entmake:circle (car (q:geo:incircle p1 p2 p3)) (cadr (q:geo:incircle p1 p2 p3)) (getvar "clayer"))
 (q:entmake:point (car (q:geo:circumcircle p1 p2 p3)) (getvar "clayer"))
 (q:entmake:circle (car (q:geo:circumcircle p1 p2 p3)) (cadr (q:geo:circumcircle p1 p2 p3)) (getvar "clayer"))
)
;;entmake point
(defun q:entmake:point(pt layer)
  (entmake (list (cons 0 "POINT")
                 (cons 8 layer);***
(cons 10 pt) ;***
   )
  )
)
;;entmake circle
(defun q:entmake:circle (center rad layer)
  (entmake (list (cons 0 "CIRCLE") ;***
(cons 6 "BYLAYER") (cons 8 layer) (cons 10 center) ;***
(cons 40 rad) ;***
(cons 39 0.0) (cons 210 (list 0.0 0.0 1.0))
   )
  )
)

« Last Edit: January 22, 2011, 12:46:59 AM by qjchen »
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #2 on: January 21, 2011, 07:44:43 PM »
Hi, Lee, funny question~
Is this three points 3d points, or only consider the XY plane situation?

I was only considering the 2D XY-Plane, although the program could be generalised via a change of basis  :-)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #3 on: January 22, 2011, 01:58:29 AM »
I used some of my library functions.
kdub:vec2pts
kdub:enclosedangle_3pts
kdub:midpoint
kdub:asin

;; Points MUST be described antiClockwise.

(setq
      P1 '(0. 0.)
      P2 '(250. 100)
      P3 '(50. 200.)
)
(_InscribedCircleRadius P1 P2 P3)
;;-> ((92.9898 106.531) 64.3758)


(_CircumscribedCircleRadius P1 P2 P3)
 ;;-> ((113.889 77.7778) 137.913)


Routines :
Code: [Select]
;; return <Center>< Radius>
(defun _InscribedCircleRadius
       (P1 P2 P3 / Angp1p2  Enclangp1 Enclangp2)
    ;;codeHimBelonga kdub@theSwamp
  (setq enclAngP1 (kdub:enclosedangle_3pts P1 P2 P3)
        enclAngP2 (kdub:enclosedangle_3pts P2 P3 P1)
        AngP1P2   (angle p1 p2)
  )
  (list (inters P1
                (polar P1 (+ AngP1P2 (* enclAngP1 0.5)) 10)
                P2
                (polar P2 (- AngP1P2 (* enclAngP2 0.5)) 10)
                nil
        )
        (* (distance P1 P2)
           (/ (* (sin (* enclAngP1 0.5)) (sin (* enclAngP2 0.5)))
              (cos (* (- PI enclAngP1 enclAngP2) 0.5))
           )
        )
  )
)

Code: [Select]
;; return <Center>< Radius>
(defun _CircumscribedCircleRadius
       (P1 P2 P3 / Angp1p2 Angp1p3 Enclangp1 Midp1p2 Midp1p3)
  ;;codeHimBelonga kdub@theSwamp
  (setq enclAngP1 (kdub:enclosedangle_3pts P1 P2 P3))
  (list (inters (setq midp1p2 (kdub:midpoint P1 P2))
                (polar midp1p2 (+ (angle p1 p2) (* 0.5 Pi)) 10)
                (setq midp1p3 (kdub:midpoint P1 P3))
                (polar midp1p3 (- (angle p1 p3) (* 0.5 Pi)) 10)
                nil
        )
        (/ (distance P2 P3) (* 2.0 (sin enclAngP1)))
  )
)

Library Stuff :
Code: [Select]
;;;-------------------------------------------------------------
;;
;;; kdub:vec2Pts Returns the single unit vector from p1 to p2
(defun kdub:vec2pts (p1 p2)
  (if (not (equal p1 p2 1e-013))
    (mapcar '(lambda (x) (/ x (distance p1 p2))) (mapcar '- p2 p1))
  )
)
;;;-------------------------------------------------------------
;;
;;; enclosedangle_3pts Returns the angle (in radians) defined by its summit and two points
;;; Returned angle is always positive and less than or equal to pi radians.

;; Using vector calculus
(defun kdub:enclosedangle_3pts (ip p1 p2 / v1 v2)
  (if (and (setq v1 (kdub:vec2pts ip p1)) (setq v2 (kdub:vec2pts ip p2)))
    (cond ((equal v1 v2 1e-013) 0.0)
          ((equal v1 (mapcar '- v2) 1e-013) pi)
          (t (* 2 (kdub:asin (* (distance v1 v2) 0.5))))
    )
  )
)
;;;-------------------------------------------------------------
;;
(defun kdub:midpoint (p0 p1 /)
  (mapcar '(lambda (ord1 ord2) (* (+ ord1 ord2) 0.5)) p0 p1)
)
;;;------------------------------------------------------------------
;;;
;;; arcsine (inverse sine) accepts an argument in the range
;;; -1.0 to 1.0 inclusive, and returns an angle in radians in
;;; the range -pi/2 to pi/2 inclusive.
(defun kdub:asin (num)
  (cond
    ((> (abs num) 1.0)
     (alert (strcat " Arc-sine error in (KDUB:asin ." "\n Spitting the dummy"))
     (exit)
    )
    ((zerop num) 0.0)
    ((= num 1.0) (* 0.5 pi))
    ((= num -1.0) (- (* 0.5 pi)))
    (t (atan num (sqrt (- 1.0 (* num num)))))
  )
)
« Last Edit: January 22, 2011, 02:13:45 AM by Kerry »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #4 on: January 22, 2011, 02:13:15 AM »
for the 3d situation, I use the Barycentric Coordinates to calculate multiple center

based on this pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;Use Barycentric Coordinates to calculate multiple center
;;;http://mathworld.wolfram.com/BarycentricCoordinates.html
;;;http://en.wikipedia.org/wiki/Barycentric_coordinates_(mathematics)#Converting_to_barycentric_coordinates


It could be incircle center, circumcircle center, centroid, symmedian point, orthocenter, Nagel point... the some other center could be write in such way. :)

Thanks Lee, and drive me to learn such a good method~~

Code: [Select]
;;;;vec plus
(defun q:vec:+(v1 v2) (mapcar '+ v1 v2))
;;;;vec substract
(defun q:vec:-(v1 v2) (mapcar '- v1 v2))
;;;;vec plus constant
(defun q:vec:*c(v a)  (mapcar '(lambda(x) (* x a)) v))
;;;;vec dot product
(defun q:vec:dot*(v1 v2) (apply '+ (mapcar '* v1 v2)))
;;;;vec cross product
(defun q:vec:cross*(v1 v2)
  (list (q:det:2 (cadr v1) (caddr v1) (cadr v2) (caddr v2))
        (q:det:2 (caddr v1) (car v1) (caddr v2) (car v2))
        (q:det:2 (car v1) (cadr v1) (car v2) (cadr v2)))
)
;;;;Normalize a vec
(defun q:vec:Norm(v / l)
  (if (not (zerop (setq l (distance '(0 0 0) v))))
  (mapcar '(lambda(x) (/ x l)) v))
)
;;;; Vector Length
(defun q:vec:Length(v) (sqrt (apply '+ (mapcar '(lambda(x) (expt x 2)) v))))

;;;;determinant library
;;;;cal determinant
;;;;|a1 a2|
;;;;|b1 b2|
(defun q:det:2(a1 a2 b1 b2)
  (- (* a1 b2) (* a2 b1))
)


;;;; Geometry code
;;;; qjchen@gmail.com
;;;;http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
;;;; distance of point per to line
(defun q:geo:point-dis-to-line(p p1 p2 / n)
  (setq n (q:vec:Norm (q:vec:- p2 p1)))
  (q:vec:Length (q:vec:- (q:vec:+ p1 (q:vec:*c n (q:vec:dot* (q:vec:- p p1) n))) p))
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;Use Barycentric Coordinates to calculate multiple center
;;;http://mathworld.wolfram.com/BarycentricCoordinates.html
;;;http://en.wikipedia.org/wiki/Barycentric_coordinates_(mathematics)#Converting_to_barycentric_coordinates
(defun q:geo:barycentric-normalize(a b c)
  (mapcar '(lambda(x) (/ x (+ a b c))) (list a b c))
)
;;;;transform from barycentric-to-Cartesian coordinate
(defun q:geo:barycentric-to-Cartesian(tlst P1 P2 P3)
 (q:vec:+  (q:vec:+ (q:vec:*c P1 (car tlst)) (q:vec:*c P2 (cadr tlst))) (q:vec:*c P3 (caddr tlst)))
)
;;Find out the incircle of three point (three distinct, noncollinear WCS points)
;;;; qjchen@gmail.com
(defun q:geo:incircle3d(p1 p2 p3 / a b c p)
  (setq a (distance p2 p3) b (distance p1 p3) c (distance p1 p2))
  (setq p  (q:geo:barycentric-to-Cartesian (q:geo:barycentric-normalize a b c) P1 P2 P3))
  (list p (q:geo:point-dis-to-line p p1 p2))
)
;;Find out the circumcircle of three point (three distinct, noncollinear WCS points)
(defun q:geo:circumcircle3d(p1 p2 p3 / a b c p temp)
  (setq a (distance p2 p3) b (distance p1 p3) c (distance p1 p2))
  (defun temp(a b c) (* a a (+ (* b b) (* c c) (* a (- a)))))
  (setq p  (q:geo:barycentric-to-Cartesian (q:geo:barycentric-normalize (temp a b c) (temp b c a) (temp c a b)) P1 P2 P3))
  (list p (distance p1 p))
)
;;Find out the triangle centroid of three point (three distinct, noncollinear WCS points)
(defun q:geo:centroid3d(p1 p2 p3 / p)
  (q:geo:barycentric-to-Cartesian (q:geo:barycentric-normalize 1.0 1.0 1.0) P1 P2 P3)
)

;;Find out the symmedian point of three point (three distinct, noncollinear WCS points)
(defun q:geo:symmedianpoint3d(p1 p2 p3 / a b c)
  (setq a (distance p2 p3) b (distance p1 p3) c (distance p1 p2))
  (q:geo:barycentric-to-Cartesian (q:geo:barycentric-normalize (* a a) (* b b) (* c c)) P1 P2 P3)
)

;;Find out the orthocenter of three point (three distinct, noncollinear WCS points)
(defun q:geo:orthocenterpoint3d(p1 p2 p3 / a b c temp)
  (setq a (distance p2 p3) b (distance p1 p3) c (distance p1 p2))
  (defun temp(a b c) (* (+ (* a a) (* b b) (* c (- c)))(+ (* c c) (* a a) (* b (- b)))))
  (q:geo:barycentric-to-Cartesian (q:geo:barycentric-normalize (temp a b c) (temp b c a) (temp c a b)) P1 P2 P3)
)

;;Find out the Nagel point of three point (three distinct, noncollinear WCS points)
(defun q:geo:Nagelpoint3d(p1 p2 p3 / a b c temp)
  (setq a (distance p2 p3) b (distance p1 p3) c (distance p1 p2))
  (defun temp(x) (- (/ (+ a b c) 2.0) x))
  (q:geo:barycentric-to-Cartesian (q:geo:barycentric-normalize (temp a) (temp b) (temp c)) P1 P2 P3)
)

Testing code
Code: [Select]
(defun c:test1 (/ p1 p2 p3 res1 res2 res3)
  (command "UCS" "W")
  (setvar "OSMODE" 1)
  (setvar "PDMODE" 2)
  (setq p1 (getpoint)
        p2 (getpoint)
        p3 (getpoint)
  )
  (setvar "OSMODE" 0)
  (setq res1 (q:geo:incircle3d p1 p2 p3))
  (setq res2 (q:geo:circumcircle3d p1 p2 p3))
  (setq res3 (q:geo:orthocenterpoint3d p1 p2 p3))
  (command "UCS" "3" p1 p2 p3)
  (command "POINT" (trans (car res1) 0 1))
  (command "CIRCLE" (trans (car res1) 0 1) (cadr res1))
  (command "POINT" (trans (car res2) 0 1))
  (command "CIRCLE" (trans (car res2) 0 1) (cadr res2))
  (command "POINT" (trans res3 0 1))
  (command "UCS" "W")
  (grdraw (list 0 0 0) res3 1)
)


« Last Edit: January 22, 2011, 06:30:32 AM by qjchen »
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #5 on: January 22, 2011, 04:13:35 AM »
Hi,

Here's a way using vector calculus, 3d working, returning a (center radius normal) list.

EDIT: I renamed (perfixed) the functions and added a 'test' command
Code: [Select]
;; gc:CrossProduct
;; Returns the cross product of v1 v2
(defun gc:CrossProduct (v1 v2)
  (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
(- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
(- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
  )
)

;; gc:GetNormal
;; Returns the unit vector codirectional to v
(defun gc:GetNormal (v)
  ((lambda (l)
     (if (/= 0 l)
       (mapcar (function (lambda (x) (/ x l))) v)
     )
   )
    (distance '(0 0 0) v)
  )
)

;; gc:MidPoint
;; Returns the middle of p1 p2
(defun gc:MidPoint (p1 p2)
  (mapcar (function (lambda (x1 x2) (/ (+ x1 x2) 2.))) p1 p2)
)

;; gc:Inscribe
;; Returns the center radius and normal of the p1 p2 p3 triangle inscribe circle
(defun gc:Inscribe (p1 p2 p3 / v1 v2 n c)
  (setq v1 (gc:GetNormal (mapcar '- p2 p1))
v2 (gc:GetNormal (mapcar '- p3 p1))
n (gc:GetNormal (gc:CrossProduct v1 v2))
  )
  (list
    (setq c (inters
      p1
      (mapcar '+ p1 v1 v2)
      p2
      (mapcar '+ p2 v1 (gc:GetNormal (mapcar '- p2 p3)))
      nil
    )
    )
    (distance '(0. 0. 0.) (gc:CrossProduct (mapcar '- c p1) v1))
    n
  )
)

;; gc:Circumscribe
;; Returns the center radius and normal of the p1 p2 p3 triangle circumscribe circle
(defun gc:Circumscribe (p1 p2 p3 / v1 v2 n m1 m2 c)
  (setq v1 (mapcar '- p2 p1)
v2 (mapcar '- p3 p1)
n  (gc:CrossProduct v1 v2)
m1 (gc:MidPoint p1 p2)
m2 (gc:MidPoint p1 p3)
  )
  (list
    (setq c (inters
      m1
      (mapcar '+ m1 (gc:CrossProduct v1 n))
      m2
      (mapcar '+ m2 (gc:CrossProduct v2 n))
      nil
    )
    )
    (distance c p1)
    (gc:GetNormal n)
  )
)

Testing function:

Code: [Select]
(defun c:test (/ p1 p2 p3 ic cc)
  (and
    (setq p1 (getpoint "\nFirst point: "))
    (setq p2 (getpoint "\nSecond point: "))
    (setq p3 (getpoint "\nThird point: "))
    (setq ic (gc:Inscribe p1 p2 p3))
    (setq cc (gc:Circumscribe p1 p2 p3))
    (entmake
      (list
'(0 . "CIRCLE")
'(62 . 4)
(cons 10 (trans (car ic) 0 (caddr ic)))
(cons 40 (cadr ic))
(cons 210 (caddr ic))
      )
    )
    (entmake
      (list
'(0 . "CIRCLE")
'(62 . 2)
(cons 10 (trans (car cc) 0 (caddr cc)))
(cons 40 (cadr cc))
(cons 210 (caddr cc))
      )
    )
  )
  (princ)
)
« Last Edit: January 22, 2011, 08:00:12 AM by gile »
Speaking English as a French Frog

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #6 on: January 22, 2011, 05:09:46 AM »

Very nice gile
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #7 on: January 22, 2011, 06:25:49 AM »
Hi,

Here's a way using vector calculus, 3d working, returning a (center radius normal) list.

Code: [Select]
;; CrossProduct
;; inscribeCircle
;; Returns the center radius and normal of the inscribe circle of p1 p2 p3
(defun inscribeCircle (p1 p2 p3 / v1 v2 c)
  (setq v1 (Normalize (mapcar '- p2 p1))
v2 (Normalize (mapcar '- p3 p1))
  )
  (list (setq c (inters
  p1
  (mapcar '+ p1 v1 v2)
  p2
  (mapcar '+ p2 v1 (Normalize (mapcar '- p2 p3)))
  nil
)
)
(distance '(0. 0. 0.) (CrossProduct (mapcar '- c p1) v1))
(Normalize (CrossProduct v1 v2))
  )
)

;; circumscribeCircle
;; Returns the center radius and normal of the circumscribe circle of p1 p2 p3
(defun circumscribeCircle (p1 p2 p3 / v1 v2 n m1 m2 c)
  (setq v1 (mapcar '- p2 p1)
v2 (mapcar '- p3 p1)
n  (CrossProduct v1 v2)
m1 (midPt p1 p2)
m2 (midPt p1 p3)
  )
  (list
    (setq c (inters
      m1
      (mapcar '+ m1 (CrossProduct v1 n))
      m2
      (mapcar '+ m2 (CrossProduct v2 n))
      nil
    )
    )
    (distance c p1)
    n
  )
)

Nice code, gile.

I only know how to calculate the angle-bisector by cross.product of normalize vector (p2-p1) and (p3-p1).

but I fail to know that how to calculate the mid-normal of p1 and p2 (in plane p1 p2 p3), you use a normal vector n to ensure the mid-normal vector is in plane (p1 p2 p3), that is a very good method.~~
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #8 on: January 22, 2011, 08:33:18 AM »
my version:
Code: [Select]
(defun v_norm_2v (v1 v2)
 (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
       (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
       (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
 )
)
(defun v_ed (p1 p2 / s)
 (if (/= (setq s (distance p1 p2)))
  (mapcar (function /) (mapcar (function -) p2 p1) (list s s s))
 )
)
(defun test (p1 p2 p3 / v x)
 (setq v  (v_norm_2v (mapcar (function -) (trans p1 1 0) (trans p2 1 0))
                     (mapcar (function -) (trans p1 1 0) (trans p3 1 0))
          )
       p1 (trans p1 1 v)
       p2 (trans p2 1 v)
       p3 (trans p3 1 v)
 )
 (entmakex
  (list '(0 . "circle")
        '(62 . 2)
        (cons 10
              (polar p3
                     (+ (angle p3 p2) (setq x (- (angle p1 p3) (angle p1 p2))) (* pi -0.5))
                     (setq x (/ (distance p2 p3) (sin x) 2.))
              )
        )
        (cons 40 (abs x))
        (cons 210 v)
  )
 )
 (entmakex
  (list '(0 . "circle")
        '(62 . 4)
        (cons 10
              (inters p1
                      (mapcar '+ p1 (v_ed p1 p2) (v_ed p1 p3))
                      p2
                      (mapcar '+ p2 (v_ed p2 p1) (v_ed p2 p3))
                      nil
              )
        )
        (cons 40
              (/ (* (distance p1 p2) (distance p2 p3) (distance p3 p1))
                 (* 2 (abs x) (+ (distance p1 p2) (distance p2 p3) (distance p3 p1)))
              )
        )
        (cons 210 v)
  )
 )
)

Testing:
Code: [Select]
(test (getpoint "\n p1") (getpoint "\r p2") (getpoint "\r p3"))
ps. program does not depend on the current system of coordinates...
« Last Edit: January 22, 2011, 09:14:33 AM by ElpanovEvgeniy »

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #9 on: January 22, 2011, 09:02:41 AM »
Wow!  You guys have taken it much further than I did...  :oops:

My 2D solution...

Code: [Select]
(defun Incircle ( p1 p2 p3 )
  (list
    (inters
      p1 (polar p1 (/ (+ (angle p1 p2) (angle p1 p3)) 2.) 1.)
      p2 (polar p2 (/ (+ (angle p2 p1) (angle p2 p3)) 2.) 1.)
      nil
    )
    ( (lambda ( l ) (/ (* (car l) (cadr l) (abs (sin (- (angle p2 p3) (angle p2 p1))))) (apply '+ l)))
      (mapcar 'distance (list p1 p2 p3) (list p2 p3 p1))
    )     
  )
)

Code: [Select]
(defun Circumcircle ( p1 p2 p3 / _mid )

  (defun _mid ( a b ) (mapcar '(lambda ( a b ) (/ (+ a b) 2.)) a b))
 
  (list
    (setq p
      (inters
        (setq m1 (_mid p1 p2)) (polar m1 (+ (/ pi 2.) (angle p1 p2)) 1.)
        (setq m2 (_mid p2 p3)) (polar m2 (+ (/ pi 2.) (angle p2 p3)) 1.)
        nil
      )
    )
    (distance p p1)
  )
)

Test code:

Code: [Select]
(defun c:test ( / _Circle p1 p2 p3 )

  (defun _Circle ( c r )
    (entmakex
      (list
        (cons 0 "CIRCLE")
        (cons 10 c)
        (cons 40 r)
      )
    )
  )

  (if
    (and
      (setq p1 (getpoint "\nP1: "))
      (setq p2 (getpoint "\nP2: "))
      (setq p3 (getpoint "\nP3: "))
    )
    (progn
      (apply '_Circle (Incircle     p1 p2 p3))
      (apply '_Circle (Circumcircle p1 p2 p3))
    )
  )

  (princ)
)
« Last Edit: January 22, 2011, 09:05:45 AM by Lee Mac »

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #10 on: January 22, 2011, 09:24:36 AM »
Many thanks gile!
I liked your code calculate the bisector!
I will use it often...  :-)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #11 on: January 22, 2011, 09:25:12 AM »
Code: [Select]
(distance '(0. 0. 0.) (gc:CrossProduct (mapcar '- c p1) v1))

Nice method for the Incircle radius!  :-)

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #12 on: January 22, 2011, 09:27:07 AM »
 :-)

after learning from Evgeniy's code, I find he use a new method to find the outcircle center.
Thanks for sharing.

And this first turning 3d=>2d and 2d=>3d can simplify this task.

It is meaningful thing to learn from other's code.

http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #13 on: January 22, 2011, 09:27:35 AM »
Wow!  You guys have taken it much further than I did...  :oops:

My 2D solution...

Now try to catch up...    :?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: -={ Challenge }=- Incircle & Circumcircle of a Triangle
« Reply #14 on: January 22, 2011, 09:57:10 AM »
Nice code, gile.

I only know how to calculate the angle-bisector by cross.product of normalize vector (p2-p1) and (p3-p1).

but I fail to know that how to calculate the mid-normal of p1 and p2 (in plane p1 p2 p3), you use a normal vector n to ensure the mid-normal vector is in plane (p1 p2 p3), that is a very good method.~~

Many thanks gile!
I liked your code calculate the bisector!
I will use it often...  :-)

Code: [Select]
(distance '(0. 0. 0.) (gc:CrossProduct (mapcar '- c p1) v1))

Nice method for the Incircle radius!  :-)


Thanks to all.
qjchen's Barycentric and Evgeniy's trans routes are very interesting too, but I choosed the vector calculus one because of the upper reasons, it allows to solve all these tasks quite easily.

To get the distance from a 3d point to an unbounded 3d line defined by 2 points, here's a 'generic' way

Code: [Select]
;; gc:DistanceTo
;; Returns the distance from pt to p1 p2 line
(defun gc:DistanceTo (pt p1 p2)
  ((lambda (v)
     (/
       (distance '(0. 0. 0.) (gc:CrossProduct (mapcar '- pt p1) v))
       (distance '(0. 0. 0.) v)
     )
   )
    (mapcar '- p2 p1)
  )
)
Speaking English as a French Frog