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[{"D2DArc2D_1.gif","D2DArc2D_2.gif"},{"D2DArc2D_3.gif","D2DArc2D_4.gif"},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 "D2DArc2D_5.gif" to "D2DArc2D_6.gif".  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[{"D2DArc2D_7.gif","D2DArc2D_8.gif"},{"D2DArc2D_9.gif","D2DArc2D_10.gif"},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[{"D2DArc2D_11.gif","D2DArc2D_12.gif"},{"D2DArc2D_13.gif","D2DArc2D_14.gif"},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[{"D2DArc2D_15.gif","D2DArc2D_16.gif"},{"D2DArc2D_17.gif","D2DArc2D_18.gif"},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[{"D2DArc2D_19.gif","D2DArc2D_20.gif"},{"D2DArc2D_21.gif","D2DArc2D_22.gif"},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[{"D2DArc2D_23.gif","D2DArc2D_24.gif"},{"D2DArc2D_25.gif","D2DArc2D_26.gif"},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, "D2DArc2D_27.gif", and Angle2D[arc,1] gives the end angle, "D2DArc2D_28.gif".

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,{"D2DArc2D_29.gif","D2DArc2D_30.gif"}]
Constructs an arc from a center point, radius and angular span range. The arc is defined counter-clockwise from the start point associated with "D2DArc2D_31.gif" to the end point associated with "D2DArc2D_32.gif".

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`" *)


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