Exploring Analyic Geometry with Mathematica® |
|||||
| Home | Contents | Commands | Packages | Explorations | Reference |
| Tour | Lines | Circles | Conics | Analysis | Tangents |
D2DArc2D
The package D2DArc2D implements the Arc2D object.
Initialization
BeginPackage["D2DArc2D`", {"D2DCircle2D`", "D2DExpressions2D`", "D2DGeometry2D`", "D2DLine2D`", "D2DMaster2D`", "D2DNumbers2D`", "D2DPoint2D`", "D2DSketch2D`", "D2DTransform2D`"}];
D2DArc2D::usage=
"D2DArc2D is a package that implements the Arc2D object.";
Arc2D::usage=
"Arc2D[{x0,y0},{x1,y1},B] is the standard form of an arc with start point (x0,y0), end point (x1,y1) and positive bulge factor 'B'.";
Bulge2D::usage=
"Bulge2D[arc] returns the bulge factor of an arc.";
Complement2D::usage=
"Complement2D is a keyword required in Arc2D[arc, Complement2D].";
Begin["`Private`"];
Description
Representation
Format: Arc2D[{
,
},{
,
},B]
Standard representation of an arc in Descarta2D. The first argument is a list of coordinates representing the start point of the arc. The second argument is a list of coordinates representing the end point of the arc. The third argument is a scalar representing the bulge factor of the arc, B>0. The arc is traversed counter-clockwise from
to
. The bulge factor is the ratio of the arc's height, h, to half the chord length, d/2; so B=2h/d.
Evaluation
Format: Arc2D[{
,
},{
,
},B][t]
Evaluates an arc at a parameter value, t, and returns a list of coordinates {x,y}. Parameters in the range 0≤t≤1 cover the complete span of the arc.
Arc2D[{x0_,y0_},{x1_,y1_},B_][t_?IsScalar2D] :=
Module[{arc,h,k,betaangle},
arc=Arc2D[{x0,y0},{x1,y1},B];
{h,k}=Coordinates2D[arc];
betaangle=Angle2D[arc];
{h+(x0-h)*Cos[betaangle*t]-(y0-k)*Sin[betaangle*t],
k+(x0-h)*Sin[betaangle*t]+(y0-k)*Cos[betaangle*t]}];
Graphics
Provides graphics primitives for an arc by extending the Mathematica Display command. Executed when the package is loaded.
SetDisplay2D[
Arc2D[{x0_,y0_},{x1_,y1_},B_][{t1_?IsScalar2D,t2_?IsScalar2D}],
Circle[Coordinates2D[Arc2D[{x0,y0},{x1,y1},B]],
Radius2D[Arc2D[{x0,y0},{x1,y1},B]],
PrimaryAngleRange2D[{
Angle2D[Arc2D[{x0,y0},{x1,y1},B],t1],
Angle2D[Arc2D[{x0,y0},{x1,y1},B],t2]}]] ];
SetDisplay2D[
Arc2D[{x0_,y0_},{x1_,y1_},B_],
Circle[Coordinates2D[Arc2D[{x0,y0},{x1,y1},B]],
Radius2D[Arc2D[{x0,y0},{x1,y1},B]],
PrimaryAngleRange2D[Arc2D[{x0,y0},{x1,y1},B]]] ]
Validation
Format: Arc2D[{
,
},{
,
},B]
Detects an arc with imaginary arguments and returns the $Failed symbol. If the imaginary parts are insignificant, they are removed.
Arc2D::imaginary=
"An invalid arc of the form 'Arc2D[`1`, `2`, `3`]' has been detected; the arguments cannot be imaginary.";
Arc2D[{x0_,y0_},{x1_,y1_},B_] :=
(Arc2D @@ ChopImaginary2D[Arc2D$Head[{x0,y0},{x1,y1},B]]) /;
(FreeQ[{x0,y0,x1,y1,B},_Pattern] &&
IsTinyImaginary2D[{x0,y0,x1,y1,B}]);
Arc2D[{x0_,y0_},{x1_,y1_},B_] :=
(Message[Arc2D::imaginary,{x0,y0},{x1,y1},B];$Failed) /;
(FreeQ[{x0,y0,x1,y1,B},_Pattern] &&
IsComplex2D[{x0,y0,x1,y1,B},0]);
Format: Arc2D[{
,
},{
,
},B]
Detects an arc with a negative bulge factor and returns an arc with the defining points interchanged and the positive bulge factor.
Arc2D[{x0_,y0_},{x1_,y1_},B_?IsNegative2D] :=
Arc2D[{x1,y1},{x0,y0},-B];
Format: Arc2D[{
,
},{
,
},B]
Detects an arc with a zero bulge factor and returns the $Failed symbol.
Arc2D::invalid=
"An invalid arc of the form 'Arc2D[`1`, `2`, `3`]' has been detected; the bulge factor must be positive and the defining points must be distinct.";
Arc2D[{x0_,y0_},{x1_,y1_},B_] :=
(Message[Arc2D::invalid,{x0,y0},{x1,y1},B];$Failed) /;
(FreeQ[{x0,y0,x1,y1,B},_Pattern] &&
IsZero2D[B,0]);
Format: Arc2D[{
,
},{
,
},B]
Detects an arc whose defining points arc coincident and returns the $Failed symbol.
Arc2D[{x0_,y0_},{x1_,y1_},B_] :=
(Message[Arc2D::invalid,{x0,y0},{x1,y1},B];$Failed) /;
(FreeQ[{x0,y0,x1,y1,B},_Pattern] &&
IsZero2D[Distance2D[{x0,y0},{x1,y1}]]);
Format: IsValid2D[arc]
Returns True for a syntactically valid arc.
IsValid2D[Arc2D[{x0_?IsScalar2D,y0_?IsScalar2D},
{x1_?IsScalar2D,y1_?IsScalar2D},
B_?IsScalar2D]] := True;
Scalars
Angular Span of an Arc
Format: Angle2D[arc]
Computes the angular span of an arc. The result is returned in radians.
Angle2D[Arc2D[{x0_,y0_},{x1_,y1_},B_]] := 4*ArcTan[B];
Angle at Parameter on an Arc
Format: Angle2D[arc,t]
Computes the angle between a line through the arc center parallel to the +x-axis and a line through a point at a parameter value, t, on the arc. For example, Angle2D[arc,0] gives the start angle,
, and Angle2D[arc,1] gives the end angle,
.
Angle2D[A:Arc2D[{x0_,y0_},{x1_,y1_},B_],t_?IsScalar2D] :=
Module[{h,k,xt,yt},
{h,k}=Coordinates2D[A];
{xt,yt}=A[t];
ArcTan[xt-h,yt-k] ];
Bulge Factor of an Arc
Format: Bulge2D[arc]
Returns the bulge factor of an arc.
Bulge2D[Arc2D[{x0_,y0_},{x1_,y1_},B_]] := B;
Primary Angle Range
Format: PrimaryAngleRange2D[arc]
Computes a list of two primary angles measured counter-clockwise from the +x-axis to the defining points of an arc. The arc is traversed counter-clockwise from the first angle to the second.
PrimaryAngleRange2D[A:Arc2D[{x0_,y0_},{x1_,y1_},B_]] :=
Module[{h,k},
{h,k}=Coordinates2D[A];
PrimaryAngleRange2D[{ArcTan[x0-h,y0-k],
ArcTan[x1-h,y1-k]}] ];
Radius of an Arc
Format: Radius2D[arc]
Computes the radius of an arc.
Radius2D[Arc2D[{x0_,y0_},{x1_,y1_},B_]] :=
Sqrt[(x0-x1)^2+(y0-y1)^2]*(B+1/B)/4;
Transformations
Reflect
Format: Reflect2D[arc,line]
Reflects an arc in a line.
Reflect2D[Arc2D[{x0_,y0_},{x1_,y1_},B_],L:Line2D[a_,b_,c_]] :=
Arc2D[Reflect2D[{x1,y1},L],Reflect2D[{x0,y0},L],B];
Rotate
Format: Rotate2D[arc,θ,coords]
Rotates an arc by an angle θ about a position given by a coordinate list. If the third argument is omitted, it defaults to the origin (see D2DTransform2D.html).
Rotate2D[Arc2D[{x0_,y0_},{x1_,y1_},B_],theta_?IsScalar2D,
{xc_?IsScalar2D,yc_?IsScalar2D}] :=
Arc2D[Rotate2D[{x0,y0},theta,{xc,yc}],
Rotate2D[{x1,y1},theta,{xc,yc}],B];
Scale
Format: Scale2D[arc,s,coords]
Scales an arc from a position given by coordinates. If the position is omitted, it defaults to the origin (see D2DTransform2D.html).
Scale2D[Arc2D[{x0_,y0_},{x1_,y1_},B_],s_?IsScalar2D,
{xc_?IsScalar2D,yc_?IsScalar2D}] :=
Arc2D[Scale2D[{x0,y0},s,{xc,yc}],
Scale2D[{x1,y1},s,{xc,yc}],B] /;
Not[IsZeroOrNegative2D[s]];
Translate
Format: Translate2D[arc,{u,v}]
Translates an arc delta distance.
Translate2D[Arc2D[{x0_,y0_},{x1_,y1_},B_],
{u_?IsScalar2D,v_?IsScalar2D}] :=
Arc2D[{x0+u,y0+v},{x1+u,y1+v},B];
Construction
Center Point of an Arc
Format: Point2D[arc]
Constructs the center point of the arc.
Point2D[Arc2D[{x0_,y0_},{x1_,y1_},B_]] :=
Module[{K},
K=(1/B-B)/4;
Point2D[{(x0+x1)/2+K*(y0-y1),(y0+y1)/2-K*(x0-x1)}] ];
Circle from Arc
Format: Circle2D[arc]
Constructs the circle associated with an arc.
Circle2D[A:Arc2D[{x0_,y0_},{x1_,y1_},B_]] :=
Circle2D[Coordinates2D[A],Radius2D[A]];
Complement Arc
Format: Arc2D[arc,Complement2D]
Constructs an arc that is the complement of a given arc.
Arc2D[Arc2D[{x0_,y0_},{x1_,y1_},B_],Complement2D] :=
Arc2D[{x1,y1},{x0,y0},1/B];
Arc from Center Point, Radius and Span
Format: Arc2D[point,r,{
,
}]
Constructs an arc from a center point, radius and angular span range. The arc is defined counter-clockwise from the start point associated with
to the end point associated with
.
Arc2D::invalidSpan=
"The angular span of the arc is invalid; the span cannot be an integer multiple of 2Pi radians.";
Arc2D::invalidRadius=
"The radius, `1`, of the arc is invalid; the radius must be positive.";
Arc2D[Point2D[c:{h_,k_}], r_?IsZeroOrNegative2D,
{t0_?IsScalar2D,t1_?IsScalar2D}] :=
(Message[Arc2D::invalidRadius,r];$Failed);
Arc2D[Point2D[c:{h_,k_}], r_?IsScalar2D,
{t0_?IsScalar2D,t1_?IsScalar2D}] :=
(Message[Arc2D::invalidSpan];$Failed) /;
IsZero2D[Distance2D[Circle2D[c,r][t0],Circle2D[c,r][t1]]];
Arc2D[Point2D[c:{h_,k_}], r_?IsScalar2D,
{t0_?IsScalar2D,t1_?IsScalar2D}] :=
Module[{T0,T1,p0,p1,d,pm,H,B},
{T0,T1}=PrimaryAngleRange2D[{t0,t1}];
p0=Circle2D[c,r][T0];
p1=Circle2D[c,r][T1];
d=Distance2D[p0,p1];
pm=Circle2D[c,r][(T0+T1)/2];
H=Distance2D[(p0+p1)/2,pm];
B=2*H/d;
Arc2D[p0,p1,B] ];
Arc from Defining Points and Entry Angle
Format: Arc2D[{point,θ},point]
Constructs an arc from the start and end points and the angle between the chord and the entry vector. The angle cannot be an integer multiple of π radians. The angle is positive for counter-clockwise arcs and negative for clockwise arcs.
Arc2D::invalidEntryAngle=
"The entry angle of the arc is invalid; the entry angle cannot be an integer multiple of Pi radians.";
Arc2D::invalidCoincident=
"The defining points are coincident; an arc cannot be constructed.";
Arc2D[{P0:Point2D[p0:{x0_,y0_}],A_?IsScalar2D},
P1:Point2D[p1:{x1_,y1_}]] :=
Which[
IsZero2D[PrimaryAngle2D[A,Pi]],
Message[Arc2D::invalidEntryAngle];$Failed,
IsCoincident2D[P0,P1],
Message[Arc2D::invalidCoincident];$Failed,
True,
Arc2D[p0,p1,Tan[A/2]] ];
Arc from Three Points
Format: Arc2D[point,point,point]
Constructs an arc through three points. The first and the third points are the start and end points of the arc, respectively, and the second point is a general point on the arc. The private function Minor$2D is the 2D vector cross-product.
Arc2D::invalidCollinear=
"The three defining points are collinear; an arc cannot be constructed.";
Minor$2D[{u1_,v1_},{u2_,v2_}] := u1*v2-u2*v1;
Arc2D[P0:Point2D[p0:{x0_,y0_}],
Pon:Point2D[coordson:{xon_,yon_}],
P1:Point2D[p1:{x1_,y1_}]] :=
Module[{s,c,B},
Which[
IsCollinear2D[P0,Pon,P1],
Message[Arc2D::invalidCollinear];$Failed,
True,
s=Minor$2D[coordson-p0,p1-coordson];
c=Dot[coordson-p0,p1-coordson];
B=s/(c+Sqrt[c^2+s^2]);
Arc2D[p0,p1,B]] ];
Arc from Center, Radius and Ray End Points
Format: Arc2D[point,r,{point,point}]
Constructs an arc given the center point, radius and ray end points. The ray end points do not have to be on the arc, but they cannot be coincident with the center point.
Arc2D[P:Point2D[{h_,k_}],r_?IsScalar2D,
{P0:Point2D[{x0_,y0_}],P1:Point2D[{x1_,y1_}]}] :=
Which[
IsZeroOrNegative2D[r],
Message[Arc2D::invalidRadius,r];$Failed,
IsCoincident2D[P,P0] || IsCoincident2D[P,P1],
Message[Arc2D::invalidCoincident];$Failed,
True,
Arc2D[Point2D[{h,k}],r,
{ArcTan[x0-h,y0-k],ArcTan[x1-h,y1-k]}] ]
Epilogue
End[ ]; (* end of "`Private" *)
EndPackage[ ]; (* end of "D2DArc2D`" *)