Exploring Analyic Geometry with Mathematica® |
|||||
| Home | Contents | Commands | Packages | Explorations | Reference |
| Tour | Lines | Circles | Conics | Analysis | Tangents |
D2DConicArc2D
The package D2DConicArc2D implements the ConicArc2D object.
Initialization
BeginPackage["D2DConicArc2D`",{"D2DCircle2D`", "D2DEllipse2D`", "D2DEquations2D`", "D2DExpressions2D`", "D2DGeometry2D`", "D2DHyperbola2D`", "D2DIntersect2D`", "D2DLine2D`", "D2DLoci2D`", "D2DMaster2D`", "D2DNumbers2D`", "D2DParabola2D`", "D2DPoint2D`", "D2DQuadratic2D`", "D2DSketch2D`", "D2DTransform2D`"}];
D2DConicArc2D::usage=
"D2DConicArc2D is a package providing the conic arc object.";
Apex2D::usage=
"Apex2D is a keyword used in Point2D[cnarc,Apex2D] to construct the apex control point of a conic arc.";
ConicArc2D::usage=
"ConicArc2D[{x0,y0},{xA,yA},{x1,y1},p] is the standard form of conic arc with start point (x0,y0), end point (x1,y1), apex point (xA,yA) and projective discriminant 'p'.";
Rho2D::usage=
"Rho2D[cnarc] returns the rho value of a conic arc; 0<rho<1/2 is an ellipse; rho=1/2 is a parabola; 1/2<rho<1 is a hyperbola.";
Begin["`Private`"];
Description
Representation
Format: ConicArc2D[{
,
},{
,
},{
,
},ρ]
Standard representation of a conic arc in Descarta2D. The first and third arguments are the coordinates of the start and end points of the conic arc, respectively. The second argument is the coordinates of the apex point of the conic arc (the apex point is the intersection of the start/end point tangents). The fourth argument is a scalar representing the rho value of the conic arc (0<ρ<1/2, ellipse; ρ=1/2, parabola; 1/2<ρ<1, hyperbola).
Equation
Format: Quadratic2D[cnarc]
Constructs a quadratic representing the equation of the curve associated with a conic arc.
Quadratic2D[ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_]] :=
Module[{eqn,a,b,k,x,y},
eqn=a*b==k*(1-a-b)^2 /.
{k->(1-p)^2/(4*p^2),
a->(( y-yA)*(x1-xA)-( x-xA)*(y1-yA))/
((y0-yA)*(x1-xA)-(x0-xA)*(y1-yA)),
b->(( y-yA)*(x0-xA)-( x-xA)*(y0-yA))/
((y1-yA)*(x0-xA)-(x1-xA)*(y0-yA))};
Quadratic2D[eqn,{x,y}] ];
Evaluation
Format: ConicArc2D[{
,
},{
,
},{
,
},ρ][t]
Evaluates a conic arc at a parameter, t, and returns a list of coordinates {x,y}. Parameter values in the range 0≤t≤1 cover the complete span of the conic arc.
ConicArc2D[p0:{x0_,y0_},pA:{xA_,yA_},p1:{x1_,y1_},p_][t_?IsScalar2D] :=
Module[{b0,b1,b2},
b0=(1-t)^2; b1=2*t*(1-t); b2=t^2;
(b0*(1-p)*p0+b1*p*pA+b2*(1-p)*p1)/(b0*(1-p)+b1*p+b2*(1-p))];
Graphics
Provides graphics primitives for a conic arc by extending the Mathematica Display command. Executed when the package is loaded.
SetDisplay2D[
ConicArc2D[{x0_,y0_},{xA_,yA_},
{x1_,y1_},p_][{t1_?IsScalar2D,t2_?IsScalar2D}],
MakePrimitives2D[
ConicArc2D[{x0,y0},{xA,yA},{x1,y1},p],{t1,t2}] ];
SetDisplay2D[
ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_],
MakePrimitives2D[
ConicArc2D[{x0,y0},{xA,yA},{x1,y1},p],{0,1}] ];
Validation
Format: ConicArc2D[{
,
},{
,
},{
,
},ρ]
Detects a conic arc with imaginary arguments and returns the $Failed symbol. If the imaginary parts are insignificant, they are removed.
ConicArc2D::imaginary=
"An invalid conic arc of the form 'ConicArc2D[`1`, `2`, `3`, `4`]' has been detected; the arguments cannot be imaginary.";
ConicArc2D[p0:{x0_,y0_},pA:{xA_,yA_},p1:{x1_,y1_},p_] :=
(ConicArc2D @@ ChopImaginary2D[ConicArc$2D[p0,pA,p1,p]]) /;
(FreeQ[{p0,pA,p1,p},_Pattern] && IsTinyImaginary2D[{p0,pA,p1,p}]);
ConicArc2D[p0:{x0_,y0_},pA:{xA_,yA_},p1:{x1_,y1_},p_] :=
(Message[ConicArc2D::imaginary,p0,pA,p1,p];$Failed) /;
(FreeQ[{p0,pA,p1,p},_Pattern] && IsComplex2D[{p0,pA,p1,p},0]);
Format: ConicArc2D[{
,
},{
,
},{
,
},ρ]
Detects a conic arc with collinear control points and returns the $Failed symbol.
ConicArc2D::points=
"An invalid conic arc of the form 'ConicArc2D[`1`, `2`, `3`, `4`]' has been detected; the control points cannot be collinear.";
ConicArc2D[p0:{x0_,y0_},pA:{xA_,yA_},p1:{x1_,y1_},p_] :=
(Message[ConicArc2D::points,p0,pA,p1,p];$Failed) /;
(FreeQ[{p0,pA,p1,p},_Pattern] &&
IsCollinear2D[Point2D[p0],Point2D[pA],Point2D[p1]]);
Format: ConicArc2D[{
,
},{
,
},{
,
},ρ]
Detects a conic arc with an invalid ρ value and returns the $Failed symbol.
ConicArc2D::rho=
"An invalid conic arc of the form 'ConicArc2D[`1`, `2`, `3`, `4`]' has been detected; the value of rho must be in the range 0<rho<1.";
ConicArc2D[p0:{x0_,y0_},pA:{xA_,yA_},p1:{x1_,y1_},p_] :=
(Message[ConicArc2D::rho,p0,pA,p1,p];$Failed) /;
(FreeQ[{p0,pA,p1,p},_Pattern] &&
(IsZeroOrNegative2D[p,0] || IsZeroOrNegative2D[1-p,0]));
Format: IsValid2D[cnarc]
Verifies that a conic arc is syntactically valid.
IsValid2D[
ConicArc2D[{x0_?IsScalar2D,y0_?IsScalar2D},
{xA_?IsScalar2D,yA_?IsScalar2D},
{x1_?IsScalar2D,y1_?IsScalar2D},p_?IsScalar2D]] := True;
Scalars
Rho
Format: Rho2D[cnarc]
Returns the ρ value of a conic arc.
Rho2D[ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_]] := p;
Transformations
Reflect
Format: Reflect2D[cnarc,line]
Reflects a conic arc in a line.
Reflect2D[ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_],
L:Line2D[A2_,B2_,C2_]] :=
ConicArc2D[Reflect2D[{x0,y0},L],
Reflect2D[{xA,yA},L],
Reflect2D[{x1,y1},L],p];
Rotate
Format: Rotate2D[cnarc,θ,coords]
Rotates a conic arc by an angle θ about a position specified by a coordinate list. If the third argument is omitted, it defaults to the origin (see D2DTransform2D.html).
Rotate2D[ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_],
theta_?IsScalar2D,
{h_?IsScalar2D,k_?IsScalar2D}] :=
ConicArc2D[Rotate2D[{x0,y0},theta,{h,k}],
Rotate2D[{xA,yA},theta,{h,k}],
Rotate2D[{x1,y1},theta,{h,k}],p];
Scale
Format: Scale2D[cnarc,s,coords]
Scales a conic arc by ascale factor, s, from a position given by coordinates. If the position is omitted, it defaults to the origin (see D2DTransform2D.html).
Scale2D[ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_],
s_?IsScalar2D,
{h_?IsScalar2D,k_?IsScalar2D}] :=
ConicArc2D[Scale2D[{x0,y0},s,{h,k}],
Scale2D[{xA,yA},s,{h,k}],
Scale2D[{x1,y1},s,{h,k}],p] /;
Not[IsZeroOrNegative2D[s]];
Translate
Format: Translate2D[cnarc,{u,v}]
Translates a conic arc delta distance.
Translate2D[ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_],
{u_?IsScalar2D,v_?IsScalar2D}] :=
ConicArc2D[{x0+u,y0+v},{xA+u,yA+v},{x1+u,y1+v},p];
Construction
Apex Point
Format: Point2D[cnarc,Apex2D]
Constructs the apex control point of a conic arc.
Point2D[ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_],
Apex2D] := Point2D[{xA,yA}];
Center Point
Format: Point2D[cnarc]
Constructs the center point of the central conic underlying a conic arc.
Point2D::notCentral1=
"The conic underlying `1` is not a central conic; it has no center point.";
Point2D[C1:ConicArc2D[p0:{x0_,y0_},pA:{xA_,yA_},p1:{x1_,y1_},p_]] :=
If[IsZero2D[p-1/2],
Message[Point2D::notCentral1,C1];$Failed,
Point2D[(-p^2*pA+(p-1)^2*(p0+p1)/2)/(1-2*p)] ];
Conic from Conic Arc
Format: Loci2D[cnarc]
Constructs a list containing the conic curve associated with a conic arc.
Loci2D[C1:ConicArc2D[{x0_,y0_},{xA_,yA_},{x1_,y1_},p_]] :=
Loci2D[Quadratic2D[C1]];
Conic Arc from Conic
Format: ConicArc2D[line,conic]
Constructs a conic arc from a portion of a conic curve defined by a chordal line.
ConicArc2D::noChord=
"No chord exists between `1` and `2`; a conic arc cannot be constructed.";
ConicArc2D::center=
"The chord defined by `1` passes through the center of `2`; a conic arc cannot be constructed.";
The private function FindRho$2D[curve,point,{point,point}] computes ρ for a conic arc from the apex point and start/end points.
FindRho$2D[Parabola2D[{h_,k_},f_,theta_],
Point2D[{xA_,yA_}],
{Point2D[{x0_,y0_}],Point2D[{x1_,y1_}]}] := 1/2;
FindRho$2D[Circle2D[{h_,k_},r_] |
Ellipse2D[{h_,k_},a_,b_,theta_] |
Hyperbola2D[{h_,k_},a_,b_,theta_],
Point2D[{xA_,yA_}],
{Point2D[{x0_,y0_}],Point2D[{x1_,y1_}]}] :=
Module[{xM,yM},
{xM,yM}={x0+x1,y0+y1}/2;
If[IsZero2D[h-xM],
1/(1+Sqrt[k-yA]/Sqrt[k-yM]),
1/(1+Sqrt[h-xA]/Sqrt[h-xM])] //Simplify ];
For central conics (circles, ellipses and hyperbolas) there is a restriction that the center point cannot be on the line defining the chord of the conic arc.
ConicArc2D[L1:Line2D[a1_,b1_,c1_],
C2_ /; Is2D[C2,{Circle2D,Ellipse2D,Hyperbola2D}]] :=
If[IsOn2D[Point2D[C2],L1],
Message[ConicArc2D::center,L1,C2];$Failed,
CnArc$2D[L1,C2,Points2D[L1,C2]]];
Non-central conics (parabolas) have no restrictions on the position of the line defining the chord of the conic arc.
ConicArc2D[L1:Line2D[a1_,b1_,c1_],C2:Parabola2D[{h_,k_},f_,theta_]] :=
CnArc$2D[L1,C2,Points2D[L1,C2]];
Both end points of the chord of the conic arc must be on the same branch of a hyperbola.
CnArc$2D[L1:Line2D[a1_,b1_,c1_],
H2:Hyperbola2D[{h_,k_},a_,b_,theta_],
{Point2D[{x0_,y0_}],Point2D[{x1_,y1_}]}] :=
(Message[ConicArc2D::noChord,L1,H2];$Failed) /;
IsNegative2D[Polynomial2D[Quadratic2D[H2],{x0+x1,y0+y1}/2]];
The private function CnArc$2D[line,curve,{point,point}] completes the computation of the conic arc.
CnArc$2D[L1:Line2D[a1_,b1_,c1_],C2_,
P:{Point2D[{x0_,y0_}],Point2D[{x1_,y1_}]}] :=
Module[{pt},
pt=Point2D[L1,C2];
ConicArc2D[{x0,y0},Coordinates2D[pt],{x1,y1},FindRho$2D[C2,pt,P]] ];
No conic arc exists if the intersection of the line and the curve does not result in two points.
CnArc$2D[L1:Line2D[a1_,b1_,c1_],C2_,pts_] :=
(Message[ConicArc2D::noChord,L1,C2];$Failed)
Epilogue
End[ ]; (* end of "`Private" *)
EndPackage[ ]; (* end of "D2DConicArc2D`" *)