(* Mathematica Package *)

(* Created by the Wolfram Workbench 26 mars 2007 *)

BeginPackage["geoplan`"]
(* Exported symbols added here with SymbolName::usage *) 


Pt::usage="Pt[x,y] definit un point de coordonnees (x,y)"
Droite::usage="Droite[equation] definit une droite par son equation cartesienne"
Systeme::usage="Systeme[d1,d2] definit un systeme de deux equations de droites"
Resoudre::usage=" Resoudre[sys] donne la solution du systeme forme par deux droites"
Pente::usage="Pente[droite] donne la pente de la droite"
TermeIndependant::usage="TermeIndependant[droite] donne le TermeIndependant c de la droite a x + b y + c = 0"
ParalleleQ::usage="ParalleleQ[d1,d2] teste le parallelisme des droites d1 et d2"
EgalesQ::usage="EgalesQ[d1,d2] teste l egalite des droites d1 et d2"
Parallele::usage="Parallele[droite,point] donne la droite parallele a droite et passant par point"
PerpendiculaireQ::usage="PerpendiculaireQ[d1,d2] teste la perpendicularite des droites d1 et d2"
Perpendiculaire::usage="Perpendiculaire[droite,point] donne la droite perpendiculaire a droite et passant par point"
ProduitScalaire::usage="ProduitScalaire[A,B] calcule le produit scalaire des points A et B"
Fonction::usage="Fonction[droite] redonne l equation de la droite sous la forme y = m x + p si possible"

Begin["`Private`"]
(* Implementation of the package *)

	Pt/:	Pt[{a_,b_}] := Pt[a,b]
	Pt/:	Pt[a_,b_] + Pt[c_,d_] := Pt[a+c,b+d]
	Pt/:	Dot[Pt[a_,b_] , Pt[x_,d_]] := Dot[{a,b},{c,d}]
	Pt/:	Times[r_ , Pt[a_,b_]] := Pt[Times[r,{a,b}]]
	Pt/:	Times[Pt[a_,b_] , Pt[d_,e_]] := Pt[Times[{a,b},{d,e}]]
	Pt/:    Format[Pt[a_,b_]]:=SequenceForm["(",a," , ",b,")"]
	
	Pt[Global`x,a_ Global`x + b_]:=Droite[Global`y==a Global`x + b]

ProduitScalaire[Pt[a_,b_],Pt[d_,e_]] := Simplify[Dot[{a,b},{d,e}]]
ProduitScalaire[a_List,b_List] := Dot[a,b]
ProduitScalaire[a_Symbol,b_Symbol]:=StringForm["`1` \[FilledSmallCircle] `2`",OverVector[a],OverVector[b]] 
    
    
Norme[Pt[a_,b_]] := Simplify[Sqrt[a^2 + b^2]]

Format[Systeme[d1_Droite,d2_Droite]] := HoldForm[Piecewise[{{d1, ""}, {d2, ""}}]]

Resoudre[{eq1_, eq2_}] :=  Block[{sol}, 
	sol = ToRules[Reduce[{eq1, eq2}, {Global`x, Global`y}]];
	If[sol,Droite[eq1],Global`\[EmptySet],Simplify[Pt[Global`x /. sol, Global`y /. sol]]]
	]

Resoudre[Systeme[d1_,d2_]] :=  Block[{sol,regle}, 
	sol = Reduce[{d1[[1]], d2[[1]]}, {Global`x, Global`y}];
	If[sol==False,Return[Global`\[EmptySet]]];
	If[Head[sol]==Equal,Return[d1]];
	regle=ToRules[sol];
	If[Head[sol]==Or,regle={ToRules[sol]};Return[Simplify[Pt[Global`x , Global`y]/.regle ]]];
	Simplify[Pt[Global`x , Global`y ]//.regle]
	]

Pt/:Element[Pt[xa_,ya_],Droite[eq_]]:=Simplify[eq/.{Global`x->xa,Global`y->ya}]/.{True->"Vrai",False->"Faux"}

SetAttributes[Droite,Orderless]
Droite[Pt[a_,b_],Pt[c_,d_]]:=Droite[Reduce[Simplify[(Global`y-b)(c-a)==(Global`x-a)(d-b)],Global`y]]
Format[Droite[eq_Equal]]:=eq

Fonction[Droite[eq_Equal]]:= Droite[Reduce[eq,Global`y]]



Pente[Droite[equ_Equal]]:=Block[{e,coeffx,coeffy},
	e=equ[[1]]-equ[[2]];
	coeffx=Coefficient[e,Global`x,1];
	coeffy=Coefficient[e,Global`y,1];
	If[coeffy!=0,-coeffx/coeffy,Infinity,-coeffx/coeffy]
	]
	
	(*forme ax + by + c ==0 *)
TermeIndependant[Droite[equ_Equal]]:=Block[{e,ci},
	e=equ[[1]]-equ[[2]];
	ci=Coefficient[Coefficient[e,Global`x,0],Global`y,0]
	]

ParalleleQ[d1_Droite,d2_Droite]:=Reduce[Simplify[Pente[d1]==Pente[d2]]]/.{True->"Vrai",False->"Faux"}

EgalesQ[d1_Droite,d2_Droite]:=Simplify[Simplify[Pente[d1]==Pente[d2]] && Simplify[TermeIndependant[d1]==TermeIndependant[d2]]]


Parallele[Droite[equ_],Pt[xa_,xb_]]:=Block[{e,coeffx,coeffy,ci},
	e=equ[[1]]-equ[[2]];
	coeffx=Coefficient[e,Global`x,1];
	coeffy=Coefficient[e,Global`y,1];
	ci=coeffx* Global`x + coeffy* Global`y /.{Global`x->xa,Global`y->xb};
	e=coeffx Global`x + coeffy Global`y-ci==0;
	Droite[Reduce[e,Global`y]]
	]
	
(* angle *)

PerpendiculaireQ[d1_Droite,d2_Droite]:=Reduce[Or[Pente[d1]==Infinity && Pente[d2]==0,Simplify[Pente[d1]*Pente[d2]==-1]]]/.{True->"Vrai",False->"Faux"}
SetAttributes[PerpendiculaireQ, Orderless]


Perpendiculaire[Droite[equ_],Pt[xa_,xb_]]:=Block[{e,coeffx,coeffy,ci},
	e=equ[[1]]-equ[[2]];
	coeffx=Coefficient[e,Global`x,1];
	coeffy=Coefficient[e,Global`y,1];
	ci=-coeffy* Global`x + coeffx* Global`y /.{Global`x->xa,Global`y->xb};
	e=-coeffy Global`x + coeffx Global`y-ci==0;
	Droite[Reduce[e,Global`y]]
	]
	
	
End[]

EndPackage[]

