-- tkz_elements_lines.lua
-- date 2023/11/10
-- version 1.20b
-- Copyright 2023  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.

-- -------------------------------------------------------------------------
--                           Lines
-- -------------------------------------------------------------------------
line = {}
function line: new(za, zb)
    local type = 'line'
    local mid = (za+zb)/2
    local north_pa = rotation_ (za,math.pi/2,zb)
    local south_pa = rotation_ (za,-math.pi/2,zb)
    local north_pb = rotation_ (zb,-math.pi/2,za)
    local south_pb = rotation_ (zb,math.pi/2,za)
    local west = rotation_ (za,math.pi/2,north_pa)
    local east = rotation_ (zb,math.pi/2,south_pb)
    local slope = point.arg(zb-za)
    local length = point.mod(zb-za)
    local new_line = {pa = za, pb = zb,
    north_pa = north_pa,south_pa = south_pa,west = west,east = east,
    north_pb = north_pb,south_pb = south_pb,
    slope = slope,mid = mid,type = type,length = length}
    setmetatable(new_line, {__index = line})
    return new_line
end

-------------------
-- Result -> real
-------------------
function line: distance (pt)   
    return point.mod(projection(self,pt)-pt)
end

function line: slope ()
   return slope_(self.pa,self.pb)
end
-------------------
-- Result -> boolean
-------------------
function line: in_out (pt)
    local sc,epsilon
    epsilon = 10^(-12)
    sc = math.abs ((pt-self.pa)^(pt-self.pb))
    if sc <= epsilon
     then
       return true
    else
       return false
    end
end

-------------------
-- Result -> point
-------------------
function line: translation ( pt )
    return translation_ ( self.pb-self.pa,pt )
end

function line: set_translation ( ...)
    return set_translation_ ( self.pb-self.pa,... )
end

function line: projection ( pt )
    return  projection_ ( self.pa,self.pb,pt )
end

function line: set_projection (...)
	local tp = table.pack(...)
	local i
    local t = {}
	for i=1,tp.n do
        table.insert( t , projection_ (self.pa,self.pb , tp[i])  ) 
	end
  return table.unpack ( t )
end

function line: symmetry_axial ( pt )
    return  symmetry_axial_ ( self.pa,self.pb,pt )
end

function line: set_symmetry_axial (...)
	local tp = table.pack(...)
	local i
    local t = {}
	for i=1,tp.n do
        table.insert( t , symmetry_axial_ (self.pa,self.pb , tp[i])  ) 
	end
  return table.unpack ( t )
end


function line: barycenter (ka,kb)
    return barycenter_({self.pa,ka},{self.pb,kb})
end

function line: point (t) --  t=o A  t=1 B  t = AM / AB 
    return barycenter_({self.pa,1-t},{self.pb,(t)})
end

function line: midpoint ()
    return (self.pa+self.pb)/2
end

function line: harmonic_int (pt)
    return div_harmonic_int_(self.pa,self.pb,pt)
end

function line: harmonic_ext (pt)
    return div_harmonic_ext_(self.pa,self.pb,pt)
end

function line: harmonic_both (k)
    return div_harmonic_both_(self.pa,self.pb,k)
end

function line: gold_ratio()
   return self.pa + (self.pb-self.pa)*tkzinvphi
end

function line: normalize ()
   return  self.pa+(self.pb-self.pa)/point.mod(self.pb-self.pa)
end

function line: normalize_inv ()
   return normalize_ (self.pb,self.pa)
end
-------------------
-- Result -> line
-------------------
function line: ll_from ( pt )
	return line : new (pt,pt+self.pb-self.pa) 
end

function line: ortho_from ( pt )
	return  line : new (pt,pt+(self.pb-self.pa)*point(0,1))
end

function line: mediator () 
   local m
   m = midpoint_ (self.pa,self.pb)
  return line : new (m,rotation_ (m,math.pi/2,self.pb)) 
end
-------------------
-- Result -> circle
-------------------
function line: circle ()   
    return circle : new (self.pa,self.pb)
end

function line: circle_swap ()   
    return circle : new (self.pb,self.pa)
end

----------------------
-- Result -> triangle
----------------------
function line: equilateral ()
  return triangle : new (self.pa,self.pb,rotation_ (self.pa,math.pi/3,self.pb))
end

function line: isosceles (phi)
    local pta,ptb
    pta = rotation_ (self.pa,phi,self.pb)
    ptb = rotation_ (self.pb,-phi,self.pa)
  return triangle : new (self.pa,self.pb, intersection_ll_ (self.pa,pta,self.pb,ptb ))
  
end

function line: gold ()
    local pt
    pt = rotation_ (self.pa,math.pi/2,self.pb)
     return triangle : new (self.pa,self.pb, self.pa + (pt-self.pa) * tkzinvphi)
end

function line: euclide ()
     return triangle : new (self.pa,self.pb, rotation_ (self.pa,math.pi/5,self.pb))
  end

function line: golden ()
    local pt
    pt = rotation_ (self.pa,2*math.pi/5,self.pb)
    return triangle : new (self.pa,self.pb, self.pa + (pt-self.pa) * tkzphi)
end
------------------------------
-- Result -> couple of points
------------------------------
function line: square ()
   return rotation_ (self.pb,-math.pi/2,self.pa), rotation_ (self.pa,math.pi/2,self.pb)
end

return line