Exploring Analyic Geometry with Mathematica® |
|||||
| Home | Contents | Commands | Packages | Explorations | Reference |
| Tour | Lines | Circles | Conics | Analysis | Tangents |
D2DTangentLines2D
The package D2DTangentLines2D provides functions for computing lines that are tangent to curves using a variety of defining conditions.
Initialization
BeginPackage["D2DTangentLines2D`", {"D2DCircle2D`", "D2DConic2D`", "D2DEllipse2D`", "D2DEquations2D`", "D2DExpressions2D`", "D2DGeometry2D`", "D2DHyperbola2D`", "D2DLine2D`", "D2DMaster2D`", "D2DParabola2D`", "D2DPoint2D`", "D2DQuadratic2D`", "D2DSegment2D`", "D2DSolve2D`", "D2DTangentPoints2D`", "D2DTransform2D`"}];
D2DTangentLines2D::usage=
"D2DTangentLines2D is a package for constructing tangent lines and line segments.";
TangentEquation2D::usage=
"TangentEquation2D[line, quad] constructs an equation involving the coefficients of a line and a quadratic constraining the line to be tangent to the quadratic.";
TangentLines2D::usage=
"TangentLines2D[point, curve] constructs a list of lines through a point and tangent to a second-degree curve; TangentLines2D[line, curve, Parallel2D] constructs a list of tangent lines parallel to a given line; TangentLines2D[line, curve, Perpendicular2D] constructs a list of tangent lines perpendicular to a given line; TangentLines2D[curve, curve] constructs a list of lines tangent to two curves.";
TangentSegments2D::usage=
"TangentSegments2D[curve,curve] constructs a list of line segments tangent to two curves.";
Begin["`Private`"];
Tangent Equation
Line Tangent to a Quadratic
Format: TangentEquation2D[line,quad]
Forms an equation between the coefficients of a line and a quadratic constraining the line to be tangent to the quadratic.
TangentEquation2D[Line2D[p_,q_,r_],
Quadratic2D[a_,b_,c_,d_,e_,f_]] :=
((4*c*f-e^2)*p^2+(4*a*f-d^2)*q^2+(4*a*c-b^2)*r^2+
2*(b*d-2*a*e)*q*r+2*(b*e-2*c*d)*p*r+2*(d*e-2*b*f)*p*q)==0;
Line Construction
Lines Through a Point Tangent to a Circle
Format: TangentLines2D[point,circle]
Constructs a list containing up to two lines through a point and tangent to a circle.
TangentLines2D[Point2D[{x1_,y1_}],Circle2D[{h2_,k2_},r2_]] :=
Union[TangentLine$2D[{x1,y1},0,{h2,k2},r2,1]];
Lines Through a Point Tangent to a Curve
Format: TangentLines2D[point,curve]
Constructs a list containing up to two lines through a point and tangent to a curve or quadratic.
TangentLines2D[P1:Point2D[{x1_,y1_}],crv2_] :=
Module[{pts},
pts=TangentPoints2D[P1,crv2];
Which[
pts=={}, {},
Length[pts]==1, {Line2D[P1,crv2]},
True, Map[Line2D[P1,#]&,pts]] ] /;
Is2D[crv2,{Ellipse2D,Hyperbola2D,Parabola2D,Quadratic2D}];
Parallel or Perpendicular Tangent Lines
Format: TangentLines2D[line,curve,Parallel2D | Perpendicular2D]
Constructs a list containing up to two lines which are parallel or perpendicular to a given line and tangent to a conic curve or quadratic. If the Parallel2D | Perpendicular2D keyword is omitted, the default is Parallel2D.
TangentLines2D[L:Line2D[p_,q_,r_],Q:Quadratic2D[a_,b_,c_,d_,e_,f_],
Parallel2D] :=
Module[{z,eq1,R,ans},
z=R*(-b^2+4*a*c)+q*(b*d-2*a*e)+p*(-2*c*d+b*e);
If[IsZero2D[z],{},
eq1=TangentEquation2D[Line2D[p,q,R],Q];
ans=Select[Solve2D[{eq1},{R}],
Not[IsComplex2D[R /. #]]&];
Map[Line2D[p,q,(R /. #)]&,ans]] ];
TangentLines2D[L:Line2D[a_,b_,c_],crv_,Parallel2D] :=
TangentLines2D[L,Quadratic2D[crv],Parallel2D] /;
Is2D[crv,{Circle2D,Ellipse2D,Hyperbola2D,Parabola2D}];
TangentLines2D[L:Line2D[a_,b_,c_],crv_] :=
TangentLines2D[L,crv,Parallel2D] /;
Is2D[crv,{Circle2D,Ellipse2D,Hyperbola2D,Parabola2D,Quadratic2D}];
TangentLines2D[Line2D[a_,b_,c_],crv_,Perpendicular2D] :=
TangentLines2D[Line2D[-b,a,c],crv,Parallel2D] /;
Is2D[crv,{Circle2D,Ellipse2D,Hyperbola2D,Parabola2D,Quadratic2D}];
Lines Tangent to Two Circles
Format: TangentLines2D[circle,circle]
Constructs a list containing up to four lines which are tangent to two circles. The first two lines in the list are the external tangents; the last two lines (if present) are the internal tangents. The private function TangentLine$2D implements the mathematics.
TangentLines2D[Circle2D[{h1_,k1_},r1_],Circle2D[{h2_,k2_},r2_]] :=
Flatten[{Map[Union[TangentLine$2D[{h1,k1},r1,{h2,k2},r2,#]]&,{-1,1}]}];
TangentLine$2D[{h1_,k1_},r1_,{h2_,k2_},r2_,s_] :=
Module[{H=h1-h2,K=k1-k2,R=r1+s*r2,L,A2,B2,C2,lns,sv1,sv2},
L=H^2+K^2;
A2=A1*H-B1*K; B2=B1*H+A1*K; C2 =L*r1-h1*A2-k1*B2;
sv1=Head[Line2D::imaginary];Off[Line2D::imaginary];
sv2=Head[Line2D::invalid];Off[Line2D::invalid];
lns=Map[(Line2D[A2, B2, C2] /. #)&,
{{A1->R, B1-> If[IsZero2D[L-R^2],0,Sqrt[L-R^2]]},
{A1->R, B1->-If[IsZero2D[L-R^2],0,Sqrt[L-R^2]]}}];
If[sv1===String,On[Line2D::imaginary]];
If[sv2===String,On[Line2D::invalid]];
Select[lns,IsValid2D]];
Lines Tangent to Two Quadratics
Format: TangentLines2D[quad,quad]
Constructs a list containing up to four lines tangent to two quadratics. The private function TanLn$2D computes the candidate tangent lines, and the private function DeleteCoincident$2D removes coincident solutions.
TanLn$2D[Q1:Quadratic2D[a1_,b1_,c1_,d1_,e1_,f1_],
Q2:Quadratic2D[a2_,b2_,c2_,d2_,e2_,f2_]] :=
Module[{L,p,q,r,ans,lns,svMsg1,svMsg2},
L=Line2D[p,q,r];
ans=Solve2D[{TangentEquation2D[L,Q1],
TangentEquation2D[L,Q2],
p^2+q^2==1},{p,q,r}];
svMsg1=Head[Line2D::imaginary];Off[Line2D::imaginary];
svMsg2=Head[Line2D::invalid];Off[Line2D::invalid];
lns=Map[(L /. #)&,ans];
If[svMsg1===String,On[Line2D::imaginary]];
If[svMsg2===String,On[Line2D::invalid]];
Select[lns,IsValid2D] ];
DeleteCoincident$2D[{s1___,
L1:Line2D[a1_,b1_,c1_],s2___,
L2:Line2D[a2_,b2_,c2_],s3___}]:=
DeleteCoincident$2D[{s1,L1,s2,s3}] /;
IsCoincident2D[L1,L2];
DeleteCoincident$2D[lns_List]:=lns;
TangentLines2D[Q1:Quadratic2D[a1_,b1_,c1_,d1_,e1_,f1_],
Q2:Quadratic2D[a2_,b2_,c2_,d2_,e2_,f2_]] :=
If[IsCoincident2D[Q1,Q2],{},
DeleteCoincident$2D[TanLn$2D[Q1,Q2]]];
Lines Tangent to Two Conics
Format: TangentLines2D[curve,curve]
Constructs a list containing up to four lines tangent to two conic curves (circles, ellipses, hyperbolas, parabolas or quadratics).
TangentLines2D[crv1_,crv2_] :=
Module[{Q1,Q2},
Q1=If[Is2D[crv1,{Quadratic2D}],crv1,Quadratic2D[crv1]];
Q2=If[Is2D[crv2,{Quadratic2D}],crv2,Quadratic2D[crv2]];
TangentLines2D[Q1,Q2]] /;
Is2D[crv1,{Circle2D,Ellipse2D,Hyperbola2D,Parabola2D,Quadratic2D}] &&
Is2D[crv2,{Circle2D,Ellipse2D,Hyperbola2D,Parabola2D,Quadratic2D}];
Line Segments Tangent to Two Curves
Format: TangentSegments2D[curve,curve]
Constructs a list containing up to four line segments tangent to two curves (circles, ellipses, hyperbolas, parabola or quadratics).
TangentSegments2D[crv1_,crv2_] :=
Module[{lns,svMsg1,svMsg2},
lns=TangentLines2D[crv1,crv2];
svMsg1=Head[Segment2D::imaginary];Off[Segment2D::imaginary];
svMsg2=Head[Segment2D::invalid];Off[Segment2D::invalid];
lns=Map[Segment2D[Point2D[#,crv1],Point2D[#,crv2]]&,lns];
If[svMsg1===String,On[Segment2D::imaginary]];
If[svMsg2===String,On[Segment2D::invalid]];
Select[lns,IsValid2D] ] /;
Is2D[crv1,{Circle2D,Ellipse2D,Hyperbola2D,Parabola2D,Quadratic2D}] &&
Is2D[crv2,{Circle2D,Ellipse2D,Hyperbola2D,Parabola2D,Quadratic2D}];
Epilogue
End[ ]; (* end of "`Private" *)
EndPackage[ ]; (* end of "D2DTangentLines2D`" *)