-- tkz_elements_triangles.lua -- date 2024/07/16 -- version 3.00 -- Copyright 2024 Alain Matthes -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.3 -- of this license or (at your option) any later version. -- The latest version of this license is in -- http://www.latex-project.org/lppl.txt -- and version 1.3 or later is part of all distributions of LaTeX -- version 2005/12/01 or later. -- This work has the LPPL maintenance status “maintained”. -- The Current Maintainer of this work is Alain Matthes. triangle = {} function triangle: new (za, zb ,zc) local type = 'triangle' local circumcenter = circum_center_ (za , zb , zc) local centroid = barycenter_ ( {za,1} , {zb,1} , {zc,1} ) local incenter = in_center_ (za , zb , zc) local orthocenter = ortho_center_ (za , zb , zc) local eulercenter = euler_center_ (za , zb , zc) local spiekercenter = spieker_center_ (za , zb , zc) local c = point.abs(zb-za) local a = point.abs(zc-zb) local b = point.abs(za-zc) local alpha = angle_normalize_(point.arg ((zc-za) / (zb-za))) local beta = angle_normalize_(point.arg ((za-zb) / (zc-zb))) local gamma = angle_normalize_(point.arg ((zb-zc) / (za-zc))) local ab = line : new (za,zb) local ca = line : new (zc,za) local bc = line : new (zb,zc) local o = { pa = za, pb = zb, pc = zc, type = type, circumcenter = circumcenter, centroid = centroid, incenter = incenter, eulercenter = eulercenter, orthocenter = orthocenter, spiekercenter = spiekercenter, a = a, b = b, c = c, ab = ab, ca = ca, bc = bc, alpha = alpha, beta = beta, gamma = gamma} setmetatable(o, self) self.__index = self return o end ----------------------- -- points -- ----------------------- function triangle: trilinear (a,b,c) return barycenter_ ({self.pa,a*self.a},{self.pb,b*self.b},{self.pc,c*self.c}) end function triangle: barycentric (a,b,c) return barycenter_ ({self.pa,a},{self.pb,b},{self.pc,c}) end function triangle: bevan_point () return circum_center_ ( excentral_tr_ ( self.pa , self.pb , self.pc)) end function triangle: mittenpunkt_point () return lemoine_point_ ( excentral_tr_ ( self.pa , self.pb , self.pc)) end function triangle: gergonne_point () return gergonne_point_ ( self.pa , self.pb , self.pc) end function triangle: nagel_point () return nagel_point_ ( self.pa , self.pb , self.pc) end function triangle: feuerbach_point () return feuerbach_point_ ( self.pa , self.pb , self.pc) end function triangle: lemoine_point() return lemoine_point_ ( self.pa , self.pb , self.pc) end function triangle: symmedian_point() return lemoine_point_ ( self.pa , self.pb , self.pc) end function triangle: spieker_center() return spieker_center_ ( self.pa , self.pb , self.pc ) end function triangle: barycenter (ka,kb,kc) return barycenter_ ({self.pa,ka},{self.pb,kb},{self.pc,kc}) end function triangle: base (u,v) -- (ab,ac) base coord u,v return barycenter_ ({self.pa,(1-u-v)},{self.pb,u},{self.pc,v}) end function triangle: euler_points () local H H = ortho_center_ ( self.pa , self.pb , self.pc ) return midpoint_ ( H,self.pa ), midpoint_ ( H,self.pb ), midpoint_ ( H,self.pc ) end function triangle: nine_points () local H,ma,mb,mc,H,ha,hb,hc ma,mb,mc = medial_tr_ ( self.pa , self.pb , self.pc) ha,hb,hc = orthic_tr_ ( self.pa , self.pb , self.pc) H = ortho_center_ ( self.pa , self.pb , self.pc ) return ma,mb,mc, ha,hb,hc, midpoint_ ( H,self.pa ), midpoint_ ( H,self.pb ), midpoint_ ( H,self.pc ) end function triangle : point (t) local t1,t2,p p = (self.a + self.b + self.c) t1 = self.a / p t2 = (self.a + self.b) / p if t<= t1 then return self.ab : point (t/t1) elseif t <= t2 then return self.bc : point ((t*p-self.a)/self.b) else return self.ca : point ((t*p-self.c-self.b)/self.a) end end function triangle : soddy_center () return soddy_center_ (self.pa,self.pb,self.pc) end function triangle : conway_points () local a1,a2,b1,b2,c1,c2 a1 = report_ (self.pb,self.pa,length(self.pb,self.pc),self.pa) a2 = report_ (self.pc,self.pa,length(self.pb,self.pc),self.pa) b1 = report_ (self.pa,self.pb,length(self.pa,self.pc),self.pb) b2 = report_ (self.pc,self.pb,length(self.pa,self.pc),self.pb) c1 = report_ (self.pb,self.pc,length(self.pb,self.pa),self.pc) c2 = report_ (self.pa,self.pc,length(self.pb,self.pa),self.pc) return a1,a2,b1,b2,c1,c2 end ------------------- -- Result -> line ------------------- -- N,H,G,O -- check_equilateral_ (a,b,c) function triangle: euler_line () if not check_equilateral_(self.pa,self.pb,self.pc) then return line : new (self.orthocenter,self.circumcenter) end end function triangle: symmedian_line (n) local a,b,c,l a = self.pa b = self.pb c = self.pc l = self : lemoine_point () if n==1 then return line : new (b,intersection_ll_ (b,l,a,c)) elseif n==2 then return line : new (c,intersection_ll_ (c,l,a,b)) else return line : new (a,intersection_ll_ (a,l,b,c)) end end function triangle: altitude (n) local a,b,c,o,p a = self.pa b = self.pb c = self.pc o = ortho_center_ (a,b,c) if n==1 then p = projection_ (a,c,b) return line : new (b,p) elseif n==2 then p = projection_ (a,b,c) return line : new (c,p) else p = projection_ (b,c,a) return line : new (a,p) end end function triangle: bisector (n) local a,b,c,i a = self.pa b = self.pb c = self.pc i = in_center_ (a,b,c) if n==1 then return line : new (b,intersection_ll_ (b,i,a,c)) elseif n==2 then return line : new (c,intersection_ll_ (c,i,a,b)) else return line : new (a,intersection_ll_ (a,i,b,c)) end end function triangle: bisector_ext(n) -- n =1 swap n=2 2 swap local a,b,c a = self.pa b = self.pb c = self.pc if n==1 then -- ac return line : new (b,bisector_ext_ (b,c,a)) elseif n==2 then -- ab return line : new (c,bisector_ext_ (c,a,b)) else -- bc return line : new (a,bisector_ext_ (a,b,c)) end end function triangle: antiparallel(pt,n) -- n = 1 swap ; n= 2 2 swap local a,b,c,i,u,v,w a = self.pa b = self.pb c = self.pc i = in_center_ (a,b,c) if n==1 then u = symmetry_axial_ (b,i,a) v = symmetry_axial_ (b,i,c) w = ll_from_ ( pt , u , v ) intersection_ll_ (pt,w,a,b) return line : new (intersection_ll_ (pt,w,c,b),intersection_ll_ (pt,w,a,b)) elseif n==2 then u = symmetry_axial_ (c,i,a) v = symmetry_axial_ (c,i,b) w = ll_from_ ( pt , u , v ) intersection_ll_ (pt,w,a,c) return line : new (intersection_ll_ (pt,w,b,c),intersection_ll_ (pt,w,a,c)) else u = symmetry_axial_ (a,i,b) v = symmetry_axial_ (a,i,c) w = ll_from_ ( pt , u , v ) intersection_ll_ (pt,w,b,c) return line : new (intersection_ll_ (pt,w,c,a),intersection_ll_ (pt,w,b,a)) end end ----------------------- --- Result -> circles -- ----------------------- function triangle: euler_circle () return circle : new (euler_center_ ( self.pa , self.pb , self.pc),midpoint_( self.pb , self.pc)) end function triangle: circum_circle() return circle : new (circum_circle_ ( self.pa , self.pb , self.pc), self.pa ) end function triangle: in_circle () local o o = in_center_ ( self.pa , self.pb , self.pc) return circle : new (o, projection_ (self.pb , self.pc,o) ) end function triangle: ex_circle (n) -- n =1 swap n=2 2 swap local a,b,c,o a = self.pa b = self.pb c = self.pc if n==1 then o = ex_center_ (b,c,a) return circle : new (o , projection_ (c,a,o)) elseif n==2 then o = ex_center_ (c,a,b) return circle : new (o , projection_ (a,b,o)) else o = ex_center_ (a,b,c) return circle : new (o , projection_ (b,c,o)) end end function triangle: first_lemoine_circle() local lc,oc lc = self: lemoine_point() oc = self.circumcenter return circle : new( midpoint_ (lc,oc),intersection_ll_ (lc,ll_from_ (lc,self.pa,self.pb),self.pa,self.pc)) end function triangle: second_lemoine_circle() local lc,a,b,c,r,th lc = self: lemoine_point() a = point.abs(self.pc-self.pb) b = point.abs(self.pa-self.pc) c = point.abs(self.pb-self.pa) r = ( a*b*c) / (a*a+b*b+c*c) th = lc + point(r,0) return circle : new (lc, th ) end function triangle: spieker_circle() local ma,mb,mc,sp ma,mb,mc = medial_tr_ ( self.pa , self.pb , self.pc) sp = in_center_ (ma,mb,mc) return circle : new (sp,projection_ (ma,mb,sp)) end function triangle : soddy_circle () local s,i s,i = soddy_center_ (self.pa,self.pb,self.pc) return circle : new ( s , i ) end function triangle : cevian_circle (p) local pta,ptb,ptc pta,ptb,ptc = cevian_ (self.pa,self.pb,self.pc,p) return circle : new (circum_circle_ (pta,ptb,ptc),pta) end function triangle : symmedial_circle () local pta,ptb,ptc,p p = lemoine_point_ ( self.pa , self.pb , self.pc) pta,ptb,ptc = cevian_ (self.pa,self.pb,self.pc,p) return circle : new (circum_circle_ (pta,ptb,ptc),pta) end function triangle : conway_circle () local i,t i = in_center_ (self.pa,self.pb,self.pc) t = report_ (self.pb,self.pa,length(self.pb,self.pc),self.pa) return circle : new (i,t) end function triangle : pedal_circle (pt) local x,y,z,c x = projection_ (self.pb,self.pc,pt) y = projection_ (self.pa,self.pc,pt) z = projection_ (self.pa,self.pb,pt) c = circum_center_ (x,y,z) return circle : new (c,x) end function triangle: bevan_circle () local o,r,s,t o = circum_center_ ( excentral_tr_ ( self.pa , self.pb , self.pc)) r,s,t = excentral_tr_ ( self.pa , self.pb , self.pc) return circle : new (o, r) end ------------------- -- Result -> triangle ------------------- function triangle: orthic() return triangle : new (orthic_tr_ ( self.pa , self.pb , self.pc)) end function triangle: medial() return triangle : new (medial_tr_ ( self.pa , self.pb , self.pc)) end function triangle: incentral() return triangle : new (incentral_tr_ ( self.pa , self.pb , self.pc)) end function triangle: excentral() return triangle : new (excentral_tr_ ( self.pa , self.pb , self.pc)) end function triangle: intouch() return triangle : new (intouch_tr_ ( self.pa , self.pb , self.pc)) end function triangle: contact() return triangle : new (intouch_tr_ ( self.pa , self.pb , self.pc)) end function triangle: extouch() return triangle : new (extouch_tr_ ( self.pa , self.pb , self.pc)) end function triangle: feuerbach() return triangle : new (feuerbach_tr_ (self.pa , self.pb , self.pc)) end function triangle: anti () return triangle : new (anti_tr_ (self.pa,self.pb,self.pc)) end function triangle: tangential () return triangle : new (tangential_tr_ (self.pa,self.pb,self.pc)) end function triangle: cevian (p) return triangle : new (cevian_ (self.pa,self.pb,self.pc,p)) end function triangle: symmedian () local p p = lemoine_point_ ( self.pa , self.pb , self.pc) return triangle : new (cevian_ (self.pa,self.pb,self.pc,p)) end function triangle: symmedial () local p p = lemoine_point_ ( self.pa , self.pb , self.pc) return triangle : new (cevian_ (self.pa,self.pb,self.pc,p)) end function triangle: euler () return triangle : new (euler_points_ (self.pa,self.pb,self.pc) ) end function triangle: pedal (pt) local x,y,z x = projection_ (self.pb,self.pc,pt) y = projection_ (self.pa,self.pc,pt) z = projection_ (self.pa,self.pb,pt) return triangle : new (x,y,z) end function triangle: similar () return triangle : new (similar_ (self.pa,self.pb,self.pc) ) end ------------------- -- Result -> ellipse ------------------- function triangle: steiner_inellipse () return steiner_ (self.pa,self.pb,self.pc) end function triangle: steiner_circumellipse () local e e = steiner_ (self.pa,self.pb,self.pc) return ellipse: radii (e.center,2*e.Rx,2*e.Ry,e.slope ) end function triangle: euler_ellipse () if self : check_acutangle () then local a,b a,b = intersection_lc_ (self.orthocenter,self.circumcenter, self.eulercenter,self.ab.mid) return ellipse: foci (self.orthocenter,self.circumcenter,a) end end ------------------- -- Result -> miscellaneous ------------------- function triangle: get_angle (n) local a,b,c a = self.pa b = self.pb c = self.pc if n==1 then return point.arg ((a-b)/(c-b)) elseif n==2 then return point.arg ((b-c)/(a-c)) else return point.arg ((c-a)/(b-a)) end end function triangle: projection (p) local x,y,z x = projection_ (self.pb,self.pc,p) y = projection_ (self.pa,self.pc,p) z = projection_ (self.pa,self.pb,p) return x,y,z end function triangle: parallelogram () local x = self.pc + self.pa - self.pb return x end function triangle: area () return area_(self.pa,self.pb,self.pc) end function triangle: barycentric_coordinates (pt) return barycentric_coordinates_ (self.pa,self.pb,self.pc,pt) end function triangle: in_out (pt) return in_out_ (self.pa,self.pb,self.pc,pt) end function triangle: check_equilateral () return check_equilateral_ (self.pa,self.pb,self.pc) end function triangle: check_acutangle() local asq = self.a * self.a local bsq = self.b * self.b local csq = self.c * self.c if asq + bsq > csq and bsq + csq > asq and csq + asq > bsq then return true else return false end end return triangle