Exploring Analyic Geometry with Mathematica® |
|||||
| Home | Contents | Commands | Packages | Explorations | Reference |
| Tour | Lines | Circles | Conics | Analysis | Tangents |
D2DIntersect2D
The package D2DIntersect2D constructs points that are the intersection points of two curves. It also computes the parameter values where a chordal line intersects a conic curve.
Initialization
BeginPackage["D2DIntersect2D`",{"D2DCircle2D`", "D2DEllipse2D`", "D2DEquations2D`", "D2DExpressions2D`", "D2DGeometry2D`", "D2DHyperbola2D`", "D2DLine2D`", "D2DMaster2D`", "D2DNumbers2D`", "D2DParabola2D`", "D2DPoint2D`", "D2DQuadratic2D`", "D2DSolve2D`", "D2DTransform2D`"}];
D2DIntersect2D::usage=
"D2DIntersect2D is a package for constructing the intersection points between curves.";
Parameters2D::usage=
"Parameters2D[line, conic] constructs a list containing the two parameters where a line intersects a conic (circle, ellipse, parabola or hyperbola).";
Points2D::usage=
"Points2D[curve ,curve] constructs a list of intersection points of two curves.";
Begin["`Private`"];
Intersection Points
Intersection Point of Two Lines
Format: Points2D[line,line]
Constructs a list containing up to one point that is the intersection point of two lines.
Points2D[L1:Line2D[a1_,b1_,c1_],L2:Line2D[a2_,b2_,c2_]] :=
If[IsParallel2D[L1,L2], {}, {Point2D[L1,L2]}];
Intersection Points of a Line and a Circle
Format: Points2D[line,circle]
Constructs a list containing at most two points that are the intersection points of a line and a circle.
Points2D[Line2D[a1_,b1_,c1_],Circle2D[{h2_,k2_},r2_]] :=
Module[{a,b,d,z,mapList},
{a,b,d}={a1,b1,a1*h2+b1*k2+c1}/Sqrt[a1^2+b1^2];
z=r2^2-d^2;
mapList=Which[IsZero2D[z], {0},
IsNegative2D[z], {},
True, {-1,1}];
Map[Point2D[{h2-a*d+#*b*Sqrt[z],k2-b*d-#*a*Sqrt[z]}]&,mapList] ];
Intersection Points of Two Circles
Format: Points2D[circle,circle]
Constructs a list containing at most two points that are the intersection points of two circles.
Points2D[Circle2D[{h1_,k1_},r1_],Circle2D[{h2_,k2_},r2_]] :=
Module[{s,d,R,x0,y0,cos,sin,z,mapList},
If[IsCoincident2D[{h1,k1},{h2,k2}],{},
s=(h1-h2)^2+(k1-k2)^2; d=Sqrt[s]; R=s+r1^2-r2^2;
{x0,y0}={R,Sqrt[z=(4*s*r1^2-R^2)]}/(2d);
{cos,sin}={h2-h1,k2-k1}/d;
mapList=Which[IsZero2D[z], {0},
IsNegative2D[z], {},
True, {-1,1}];
Map[Point2D[{h1+cos*x0+#*sin*y0,k1+sin*x0-#*cos*y0}]&,mapList]] ];
Intersection Points of Two Curves
Format: Points2D[curve,curve]
Constructs a list containing at most four points that are the intersection points of two curves. Valid curve
forms are lines, circles, parabolas, ellipses, hyperbolas and quadratics. Coincident point solutions appear only once in the list returned. The private function Eqn$2D returns a line or quadratic representing a curve.
Eqn$2D[crv_] :=
If[Is2D[crv,{Line2D,Quadratic2D}],crv,Quadratic2D[crv]];
Points2D[crv1_,crv2_] :=
Module[{x,y,eqns,roots},
eqns=Map[Equation2D[#,{x,y}]&,Map[Eqn$2D,{crv1,crv2}]];
roots=Select[Solve2D[eqns,{x,y}],Not[IsComplex2D[{x,y} /. #]]&];
Union[Map[(Point2D[{x,y}] /. #)&,roots]] ] /;
(Is2D[crv1,
{Circle2D,Ellipse2D,Hyperbola2D,Line2D,Parabola2D,Quadratic2D}] &&
Is2D[crv2,
{Circle2D,Ellipse2D,Hyperbola2D,Line2D,Parabola2D,Quadratic2D}]);
Chordal Parameter Range
Sort Numerically
The private function SortNumeric$2D sorts a list of two numbers into ascending order, retaining the exact form of the numbers, and returns the sorted list. If the ascending order cannot be determined (for example, when the arguments are symbolic) then the original ordering is returned.
SortNumeric$2D[{n1_,n2_}] := If[IsNegative2D[n2-n1],{n2,n1},{n1,n2}];
Circle
Format: Parameters2D[line,circle]
Constructs a list containing the two parameters on a circle where a line intersects the circle. The parameters will be primary angles and sorted in increasing order (
).
Parameters2D::noChord=
"No chord exists between `1` and `2`.";
Parameters2D[L1:Line2D[a1_,b1_,c1_],C2:Circle2D[{h2_,k2_},r2_]] :=
Module[{pts,x1,x2,y1,y2},
pts=Points2D[L1,C2];
If[Length[pts]==2,
{{x1,y1},{x2,y2}}=Map[Coordinates2D,pts];
SortNumeric$2D[{PrimaryAngle2D[ArcTan[x1-h2,y1-k2]],
PrimaryAngle2D[ArcTan[x2-h2,y2-k2]]}],
Message[Parameters2D::noChord,L1,C2];$Failed] ];
Ellipse
Format: Parameters2D[line,ellipse]
Returns a list of the two parameters on an ellipse where a line intersects the ellipse. The parameters will be primary angles and sorted in increasing order (
).
Parameters2D[L1:Line2D[a1_,b1_,c1_],E2:Ellipse2D[{h_,k_},a_,b_,theta_]] :=
Module[{ln,pts,x1,y1,x2,y2},
ln=Rotate2D[Translate2D[L1,{-h,-k}],-theta];
pts=Points2D[ln,Ellipse2D[{0,0},a,b,0]];
If[Length[pts]==2,
{{x1,y1},{x2,y2}}=Map[Coordinates2D,pts];
SortNumeric$2D[{PrimaryAngle2D[ArcTan[x1/a,y1/b]],
PrimaryAngle2D[ArcTan[x2/a,y2/b]]}],
Message[Parameters2D::noChord,L1,E2];$Failed] ];
Hyperbola
Format: Parameters2D[line,hyperbola]
Returns a list of the two parameters on a hyperbola where a line intersects the hyperbola. The parameters are sorted in the order (
). The line must intersect the hyperbola's primary branch in two points for a parameter range to be returned.
Parameters2D[L1:Line2D[a1_,b1_,c1_],
H2:Hyperbola2D[{h_,k_},a_,b_,theta_]] :=
Module[{ln,pts,t1,t2,x1,x2,y1,y2},
ln=Rotate2D[Translate2D[L1,{-h,-k}],-theta];
pts=Points2D[ln,Hyperbola2D[{0,0},a,b,0]];
If[Length[pts]==2,
{{x1,y1},{x2,y2}}=Map[Coordinates2D,pts];
t1=ArcSinh[y1/b]/ArcCosh[Sqrt[a^2+b^2]/a];
t2=ArcSinh[y2/b]/ArcCosh[Sqrt[a^2+b^2]/a];
If[IsZero2D[t1-t2],
Message[Parameters2D::noChord,L1,H2];$Failed,
If[IsNumeric2D[{t1,t2}] &&
Not[IsCoincident2D[L1,Line2D[H2[t1],H2[t2]]]],
Message[Parameters2D::noChord,L1,h2];$Failed,
SortNumeric$2D[{t1,t2}]] ],
Message[Parameters2D::noChord,L1,H2];$Failed] ];
Parabola
Format: Parameters2D[line,parabola]
Returns a list of the two parameters on a parabola where a line intersects the parabola. The parameters are sorted in increasing order (
).
Parameters2D[L1:Line2D[a1_,b1_,c1_],P2:Parabola2D[{h_,k_},f_,theta_]] :=
Module[{t,x,y,ans},
{x,y}=P2[t];
ans=Select[Solve[a1*x+b1*y+c1==0,t],Not[IsComplex2D[t /. #]]&];
If[Length[ans]==2,
SortNumeric$2D[Map[(t /. #)&,ans]],
Message[Parameters2D::noChord,L1,P2];$Failed] ];
Epilogue
End[ ]; (* end of "`Private" *)
EndPackage[ ]; (* end of "D2DIntersect2D`" *)