summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/tkz/tkz-elements/latex/tkz_elements_functions_circles.lua
blob: 33477340d3d8f9373af389fbd41dc9509aa0e928 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
-- tkz_elements_functions_circles.lua
-- date 2024/01/16
-- version 1.82c
-- 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.

--  define a circle by the center and a radius

-- function circle_cr ( c, r )
--     return c +  point(r,0)
-- end

function midarc_ (o,a,b) -- a -> b
   local phi = 0.5 * get_angle_ ( a,o,b )
   return rotation_ (o,phi,b)
end

function tangent_from_ (c,p,pt)
  local o
   o  = midpoint_ ( c,pt )
 return  intersection_cc_ (o,c,c,p)
end

function tangent_at_ (a,p)
   return rotation_ (p,math.pi/2,a),rotation_ (p,-math.pi/2,a)
end
 
function orthogonal_from_ (a,b,p)
    return tangent_from_ (a,b,p)
end

function orthogonal_through_ (a,b,x,y)
    local d,z
   d =  1/point.mod(x-a)
   z = a +(b-a)*d
   return circum_center_ (x,y,z)
end

 
function inversion_ (c,p,pt)
  local ry = point.abs(c-p)
  local d  = point.abs(c-pt)
  local r  = (ry*ry)/d
  return c+polar_ (r,point.arg(pt-c))
end

function circles_position_ (c1,r1,c2,r2)
   local d,max,min,epsilon
   epsilon  = 10^(-12)
   d        = point.mod(c1-c2)
   max      = r1+r2
   min      = math.abs ( r1 - r2)
   if d > max then return "outside"
      elseif math.abs(d - max) < epsilon then return "outside tangent" -- epsilon
      elseif math.abs(d - min) < epsilon then return "inside tangent" -- epsilon
      elseif d < min then return "inside"
      else return "intersect"
   end
end
 
function radical_axis_ (c1,p1,c2,p2)
   local ci,cj
   r1 = point.abs(c1-p1)
   r2 = point.abs(c2-p2)
   d  = point.abs(c1-c2)
   h  = (r1*r1-r2*r2+d*d)/(2*d)
   ck = radical_center_ (c1,p1,c2,p2)
   cj = rotation_ (ck,-math.pi/2,c1)
   ci = symmetry_ (ck,cj)
   return cj,ci
end

function radical_center_ (c1,p1,c2,p2)
   local d,r1,r2,h
   r1 = point.abs(c1-p1)
   r2 = point.abs(c2-p2)
   d  = point.abs(c1-c2)
   h  = (r1*r1-r2*r2+d*d)/(2*d)
   return h*(c2-c1)/d+c1
end

-- version 1.60 center pour deux cercles ?
function radical_center3 (C1,C2,C3)
   local t1,t2,t3,t4
   t1,t2 = radical_axis_ (C1.center,C1.through,C2.center,C2.through)
   if C3 == nil then
    return  intersection_ll_ (t1,t2,C1.center,C2.center)
   else
   t3,t4 = radical_axis_ (C3.center,C3.through,C2.center,C2.through)
return intersection_ll_ (t1,t2,t3,t4)
end
end


function south_pole_ (c,p)
   local r
   r = point.abs (c-p)
   return c - point (0,r)
 end

function north_pole_ (c,p)
   local r
   r = point.abs (c-p)
   return c + point (0,r)
end

function antipode_ (c,pt)
   return 2 * c - pt
end

function internal_similitude_ (c1,r1,c2,r2)
  return barycenter_ ({c2,r1},{c1,r2})
end

function  external_similitude_ (c1,r1,c2,r2)
  return  barycenter_ ({c2,r1},{c1,-r2})
end

function circlepoint_ (c,t,k)
   local phi = 2*k* math.pi
   return rotation_ (c,phi,t) 
end
 
-- version 1.60 new
function midcircle_(C1,C2)
   local state,r,s,t1,t2,T1,T2,p,a,b,c,d,Cx,Cy,i,j
   state =  circles_position_(C1.center,C1.radius,C2.center,C2.radius)
   i = barycenter_ ({C2.center,C1.radius},{C1.center,-C2.radius})
   j = barycenter_ ({C2.center,C1.radius},{C1.center,C2.radius})
   t1,t2 = tangent_from_ (C1.center,C1.through,i)
   T1,T2 = tangent_from_ (C2.center,C2.through,i)
      
   if (state == 'outside') or (state == 'outside tangent')then
         p = math.sqrt(point.mod(i-t1)*point.mod(i-T1))
   return circle  : radius (i,p)
   elseif state == 'intersect' then
        r,s = intersection (C1,C2)
   return circle  : radius (i,point.mod(r-i)) , circle  : radius (j,point.mod(r-j))
   elseif (state == 'inside') or (state == 'inside tangent') then
      a,b = intersection_lc_ (C1.center,C2.center,C1.center,C1.through)
      c,d = intersection_lc_ (C1.center,C2.center,C2.center,C2.through)
       
      if C1.radius < C2.radius then 
         z.u, z.v, z.r, z.s = a, b, c, d
      else
         z.u, z.v, z.r, z.s = c, d, a, b
      end
      
      if  (in_segment_ (z.s,z.v,z.u) == true) 
      then 
      Cx = circle  :  diameter (z.r,z.v)
      Cy = circle  :  diameter (z.u,z.s)
      else
      Cx = circle  :  diameter (z.s,z.v)
      Cy = circle  :  diameter (z.u,z.r)
      end
      if (Cx.radius) < (Cy.radius) then
         return Cy : orthogonal_from (j) 
      else
         return Cx : orthogonal_from (j)
 end
 end
end