Exploring Analyic Geometry with Mathematica®

Home Contents Commands Packages Explorations Reference
Tour Lines Circles Conics Analysis Tangents

D2DGeometry2D

The package D2DGeometry2D provides geometric query functions.

Initialization

BeginPackage["D2DGeometry2D`",{"D2DCircle2D`", "D2DExpressions2D`", "D2DLine2D`", "D2DMaster2D`", "D2DPoint2D`", "D2DQuadratic2D`"}];

D2DGeometry2D::usage=
   "D2DGeometry2D is a package providing various geometric queries.";

IsCoincident2D::usage=
   "IsCoincident2D[obj1,obj2] returns 'True' if the two objects are coincident; IsCoincident2D[obj_List] returns 'True' if any pair of objects in the list is coincident (coordinates, points, lines, circles or quadratics).";

IsCollinear2D::usage=
   "IsCollinear2D[point,point,point] returns 'True' if the three points are collinear; IsCollinear2D[pt_List] returns 'True' if any triple of points in the list are collinear.";

IsConcentric2D::usage=
   "IsConcentric2D[circle,circle] returns 'True' if the two circles are concentric; IsConcentric2D[cir_List] returns 'True' if any pair of circles in the list are concentric.";

IsConcurrent2D::usage=
   "IsConcurrent2D[line,line,line] returns 'True' if the three lines are concurrent; IsConcurrent2D[ln_List] returns 'True' if any triple of lines in the list is concurrent.";

IsOn2D::usage=
   "IsOn2D[point,line | circle | quad] returns 'True' if the point is on the line, circle or quadratic.";

IsParallel2D::usage=
   "IsParallel2D[line,line] returns 'True' if two lines are parallel; IsParallel2D[ln_List] returns 'True' if any pair of lines in a list is parallel.";

IsTripleParallel2D::usage=
   "IsTripleParallel2D[line,line,line] returns 'True' if three lines are parallel; IsTripleParallel2D[ln_List] returns 'True' if any triple of lines in a list is parallel.";

IsPerpendicular2D::usage=
   "IsPerpendicular2D[line,line] returns 'True' if two lines are perpendicular; IsPerpendicular2D[ln_List] returns 'True' if any pair of lines in a list is perpendicular.";

IsTangent2D::usage=
   "IsTangent2D[line,circle] returns 'True' if a line is tangent to a circle; IsTangent2D[circle,circle] returns 'True' if two circles are tangent to each other; IsTangent2D[line,quad] returns 'True' if a line is tangent to a quadratic.";

Begin["`Private`"];

Utilities

Combinations

The private functions PairQ$2D, Pairs$2D, TripleQ$2D and Triples$2D are used apply queries over lists of objects.

Pairs$2D[{a_,b_}] := {{a,b}};
Pairs$2D[{a_,b_,c__}] :=
   Flatten[{Map[{a,#}&,{b,c}],Pairs$2D[{b,c}]},1];
Pairs$2D[L_List /; Length[L]<2] := L;

Triples$2D[{a_,b_,c_}] := {{a,b,c}};
Triples$2D[{a_,b_,c_,d__}] :=
   Flatten[{Map[({a,#[[1]],#[[2]]})&,Pairs$2D[{b,c,d}]],
            Triples$2D[{b,c,d}]},1];
Triples$2D[L_List /; Length[L]<3] := L;

PairQ$2D[L:{a_,b__},func_] :=
   MemberQ[Map[func[#[[1]],#[[2]]]&,
               Pairs$2D[L]],
           True];
PairQ$2D[{___},func_] := False;

TripleQ$2D[L:{a_,b_,c__},func_] :=
   MemberQ[Map[func[#[[1]],#[[2]],#[[3]]]&,
               Triples$2D[L]],
           True];
TripleQ$2D[{___},func_] := False;

Coincident Queries

Two Coordinates

Format: IsCoincident2D[coords,coords]
Returns True if two coordinates are coincident; otherwise, returns False.

IsCoincident2D[{x1_?IsScalar2D,y1_?IsScalar2D},
               {x2_?IsScalar2D,y2_?IsScalar2D}] :=
   IsZero2D[x1-x2] && IsZero2D[y1-y2];

Two Points

Format: IsCoincident2D[point,point]
Returns True if two points are coincident; otherwise, returns False.

IsCoincident2D[Point2D[{x1_,y1_}],Point2D[{x2_,y2_}]] :=
   IsZero2D[x1-x2] && IsZero2D[y1-y2];

Two Lines

Format: IsCoincident2D[line,line]
Returns True if two lines are coincident; otherwise, returns False.

IsCoincident2D[Line2D[a1_,b1_,c1_],Line2D[a2_,b2_,c2_]] :=
   IsZero2D[{Det[{{ a1, b1},{ a2, b2}}],
             Det[{{-c1, b1},{-c2, b2}}],
             Det[{{ a1,-c1},{ a2,-c2}}]},And]

Two Circles

Format: IsCoincident2D[circle,circle]
Returns True if two circles are coincident; otherwise, returns False.

IsCoincident2D[Circle2D[{h1_,k1_},r1_],Circle2D[{h2_,k2_},r2_]] :=
   IsCoincident2D[{h1,k1},{h2,k2}] && IsZero2D[r1-r2];

Two Quadratics

Format: IsCoincident2D[quad,quad]
Returns True if two quadratics are coincident; otherwise, returns False.

IsCoincident2D[Q1:Quadratic2D[a1_,b1_,c1_,d1_,e1_,f1_],
               Q2:Quadratic2D[a2_,b2_,c2_,d2_,e2_,f2_]] :=
   Module[{k1,k2},
      {k1}=Select[List @@ Q1,Not[IsZero2D[#]]&,1];
      {k2}=Select[List @@ Q2,Not[IsZero2D[#]]&,1];
      IsZero2D[Map[Simplify[Expand[N[#]]]&,
                {a1*k2-a2*k1,b1*k2-b2*k1,c1*k2-c2*k1,
                 d1*k2-d2*k1,e1*k2-e2*k1,f1*k2-f2*k1}],
               And] ];

List of Objects

Format: IsCoincident2D[objList]
Returns True if any pair of objects (points, lines, circles or quadratics) in a list are coincident; otherwise, returns False.

IsCoincident2D[obj_List] := PairQ$2D[obj,IsCoincident2D];

Collinear Queries

Three Points

Format: IsCollinear2D[point,point,point]
Returns True if three points are collinear; otherwise, returns False.

IsCollinear2D[Point2D[{x1_,y1_}],Point2D[{x2_,y2_}],Point2D[{x3_,y3_}]] :=
   IsZero2D[Det[{{x1,y1,1},{x2,y2,1},{x3,y3,1}}]];

List of Points

Format: IsCollinear2D[ptsList]
Returns True if any combination of three points in a list are collinear; otherwise, returns False.

IsCollinear2D[pts_List] := TripleQ$2D[pts,IsCollinear2D];

Concentric Queries

Two Circles

Format: IsConcentric2D[circle,circle]
Returns True if two circles are concentric; otherwise, returns False.

IsConcentric2D[Circle2D[{h1_,k1_},r1_],Circle2D[{h2_,k2_},r2_]] :=
   IsCoincident2D[{h1,k1},{h2,k2}];

List of Circles

Format: IsConcentric2D[cirList]
Returns True if any combination of two circles in a list are concentric; otherwise, returns False.

IsConcentric2D[cir_List] := PairQ$2D[cir,IsConcentric2D];

Concurrent Queries

Three Lines

Format: IsConcurrent2D[line,line,line]
Returns True if three given lines are concurrent; otherwise, returns False.  Coincident and parallel lines are not considered to be concurrent and will return False.

IsConcurrent2D[L1:Line2D[a1_,b1_,c1_],L2:Line2D[a2_,b2_,c2_],
               L3:Line2D[a3_,b3_,c3_]] :=
   IsZero2D[Det[{{a1,b1,c1},{a2,b2,c2},{a3,b3,c3}}]] &&
   Not[IsParallel2D[L1,L2]] && Not[IsParallel2D[L2,L3]] &&
   Not[IsParallel2D[L2,L3]];

List of Lines

Format: IsConcurrent2D[lnsList]
Returns True if any combination of three lines in a list are concurrent; otherwise, returns False.  Coincident and parallel lines are not considered to be concurrent and will return False.

IsConcurrent2D[lns_List] := TripleQ$2D[lns,IsConcurrent2D];

On Queries

Point On Line

Format: IsOn2D[point,line]
Returns True if a point is on a line; otherwise, returns False.

IsOn2D[Point2D[{x1_,y1_}],Line2D[a2_,b2_,c2_]] := IsZero2D[a2*x1+b2*y1+c2];

Point On Circle

Format: IsOn2D[point,circle]
Returns True if a point is on a circle; otherwise, returns False.

IsOn2D[Point2D[{x1_,y1_}],Circle2D[{h2_,k2_},r2_]] :=
   IsZero2D[(x1-h2)^2+(y1-k2)^2-r2^2];

Point On Quadratic

Format: IsOn2D[point,quad]
Returns True if a point is on a quadratic; otherwise, returns False.

IsOn2D[Point2D[{x_,y_}],Quadratic2D[a_,b_,c_,d_,e_,f_]] :=
   IsZero2D[a*x^2+b*x*y+c*y^2+d*x+e*y+f];

Parallel Queries

Two Lines

Format: IsParallel2D[line,line]
Returns True if two lines are parallel, otherwise, returns False.

IsParallel2D[Line2D[a1_,b1_,c1_],Line2D[a2_,b2_,c2_]] :=
   IsZero2D[a1*b2-a2*b1];

List of Lines (by Pairs)

Format: IsParallel2D[lnsList]
Returns True if any combination of two lines in a list are parallel; otherwise, returns False.

IsParallel2D[lns_List] := PairQ$2D[lns,IsParallel2D];

Three Lines

Format: IsTripleParallel2D[line,line,line]
Returns True if three lines are mutually parallel; otherwise, returns False.

IsTripleParallel2D[Line2D[a1_,b1_,c1_],
                   Line2D[a2_,b2_,c2_],
                   Line2D[a3_,b3_,c3_]] :=
   IsZero2D[a1*b2-a2*b1] && IsZero2D[a2*b3-a3*b2];

List of Lines (by Triples)

Format: IsTripleParallel2D[lnsList]
Returns True if any combination of three lines in a list is parallel; otherwise, returns False.

IsTripleParallel2D[lns_List] := TripleQ$2D[lns,IsTripleParallel2D];

Perpendicular Queries

Two Lines

Format: IsPerpendicular2D[line,line]
Returns True if two lines are perpendicular; otherwise, returns False.

IsPerpendicular2D[Line2D[a1_,b1_,c1_],Line2D[a2_,b2_,c2_]] :=
   IsZero2D[a1*a2+b1*b2];

List of Lines

Format: IsPerpendicular2D[lnsList]
Returns True if any combination of two lines in a list is perpendicular; otherwise, returns False.

IsPerpendicular2D[lns_List] := PairQ$2D[lns,IsPerpendicular2D];

Tangent Queries

Line and Circle

Format: IsTangent2D[line,circle]
Returns True if a line is tangent to a circle; otherwise, returns False.

IsTangent2D[Line2D[A1_,B1_,C1_],Circle2D[{h_,k_},r_]] :=
  IsZero2D[r^2*(A1^2+B1^2)-(C1+A1*h+B1*k)^2];

Two Circles

Format: IsTangent2D[circle,circle]
Returns True if two circles are tangent to each other; otherwise, returns False.

IsTangent2D[C1:Circle2D[{h1_,k1_},r1_],C2:Circle2D[{h2_,k2_},r2_]] :=
   Module[{d},
     d=(h1-h2)^2+(k1-k2)^2;
     IsZero2D[{d-(r1+r2)^2,d-(r1-r2)^2},Or] &&
     Not[IsCoincident2D[C1,C2]] ];

Line and Quadratic

Format: IsTangent2D[line,quad]
Returns True if a line is tangent to a quadratic; otherwise, returns False.

IsTangent2D[Line2D[p_,q_,r_],Quadratic2D[a_,b_,c_,d_,e_,f_]] :=
   IsZero2D[(4*c*f-e^2)*p^2 + 2*(d*e-2*b*f)*p*q +
            (4*a*f-d^2)*q^2 + 2*(b*e-2*c*d)*p*r +
            (4*a*c-b^2)*r^2 + 2*(b*d-2*a*e)*q*r];

Epilogue

End[ ]; (* end of "`Private" *)
EndPackage[ ]; (* end of "D2DGeometry2D`" *)


Copyright © 1999-2007 Donald L. Vossler, Descarta2D Publishing
www.Descarta2D.com