Java Drawing DrawTop

Language

JP  US  UK

 

Parametric curves

 H. Jyounishi, Tokyo Japan
 

Frame (Index), No frame                 version:0.3(latest)  

Summary:The parametric curve representation is useful for geometric calculation such as calculating intersection points of two curves etc. We extends the classes of the Rectangle2D, RoundRectangle2D, Ellipse2D and so on in java.awt.geom to be able to handle a parametric curve.
Relevant major classes of Java SE: java.awt.*, java.geom.*
Classes on this page: Segment2D, geomExtension, Curve2D, Rectangle2DE, RoundRectangle2DE, Ellipse2DE, Line2DE, Polyline2DE, CubicCurve2DE, GeneralCurve2DE, FergusonCurve2D


1. Overview of the parametric curve

1.1 The definition
A two dimensional parametric curve is defined by a parameter t and two functions (Cx(t), Cy(t)) which give the (x,y) coordinates for parameter t. We denote the parametric curve as follow.

(1)

The Cx(t) and Cy(t) are usually expressed by a piecewise function. Each piece is a polynominal function, circular functions and so on. For example, the bondary curve of the java.awt.geom. RoundRectangle2D consists of eight pieces - four straight lines and four arcs of the 90° central angle - and those pieces are arranged as line->arc->line->arc->⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ .
We defines the domain (interval) of the curve parameter t for each piece as 0≤t≤1 for the first piece, 1≤t≤2 for the second piece and so on.
Hereafter we call each piece as a curve segment or a segment and the junction point of two pieces as a segment junction point.
Let's denote the number of the curve segments of a parametric curve as nseg, then the curve segments numbered as 0,1,2⋅ ⋅ ⋅ ,nseg-1, and the segment junction points are numbered as 0,1,2⋅ ⋅ ⋅ ,nseg.

1.2 The expressions of parametric curve segment
(1) Elliptic arc (circular arc)
The elliptic arc corresponds to the java.awt.geom.Arc2D and its parametric curve ie expressed as follow

Cx(t)= a*cos((θextent*t+θstart)*π/180)+x0 (2)
Cy(t)= - b*sin((θextent*t+θstart)*π/180)+y0


The plus direction of the y-axis on the screen is downward, so a minus sign is needed for the expression of the Cy(t).
Here, (a) the angles are represented in degrees, (b) the plus rotation of the angle is anticlockwise.
And the notations in the (2) are as follow.
⋅ (x0,y0): The center of the arc.
⋅ a, b: the The transverse diameter and conjugate diameter.
⋅ θextent: The angular extent of the arc in degrees.
⋅ θstart: The starting angle of the arc in degrees.
⋅ π: The circle ratio.

(2) CubicCurve(Bezier curve segment)

P(t)=(1-t)3 Q0 + 3(1-t)2t Q1 + 3(1-t)t2 Q2 + t3Q3 (A bold character represents a vector)   (3)

The Bezier curve segment consists of four points. The Q0, Q3 are the endpoints of the segment, and Q1, Q2 are the control points which the segment doesn't generally pass through.

Table 1 Blending functions

X0(t) X1(t) X2(t) X3(t)
Xi(t) (1-t)3 3(1-t)2t 3(1-t)t2 t3
First derivatives: Xi'(t) -3(1-t)2 3(1-t)(1-3t) 3(2-3t)t 3t2
Second derivatives: Xi''(t) 6(1-t) -6(2-3t) 6(1-3t) 6t

Table 2 The function and the derivatives at t=0, 1

t=0 t=1
P(t) Q0 Q3
First derivatives: P'(t)

-3Q0+3Q1

-3Q2+3Q3
Second derivatives: P''(t) 6Q0-12Q1+6Q2
=6(Q2-Q1)- 6(Q1-Q0)
6Q1-12Q2+6Q3
=6(Q3-Q2)- 6(Q2-Q1)

(3) Ferguson curve segment
The Bezier curve can be rewritten as follows:

P(t)= X0(t)Q0 + X1(t)Q1 + X2(t)Q2 + X3(t)Q3
= (X0(t)+X1(t))Q0 + X1(t)(Q1 - Q0 ) - X2(t)(Q3 - Q2 ) + (X2(t)+X3(t))Q3
= (X0(t)+X1(t))P(0) + (X2(t)+X3(t)) P(1) + X1(t)/3 P'(0) - X2(t)/3 P'(1)
= f0(t) P0 + f1(t)P1 + g0(t) T0 - g1(t)T1 (4)


The last formula is the expression of the Ferguson curve segment.
Here, P0= P(0), P1= P(1), T0= P'(0), T1= P'(1) => Figure 1.1 (a)
and the functions of f0(t), f1(t), g0(t) and g1(t) are expressed as Table 3.

Table 3 Ferguson blending functions

f0(t)
= X0(t)+ X1(t))
f1(t)
= X2(t)+X3(t)
g0(t)
= X1(t)/3
g1(t)
= X2(t)/3
fi(t), gi(t) (1-t)2(1+2t) (3-2t)t2 (1-t)2t (1-t)t2
First derivatives: fi'(t), gi'(t) -6(1-t)t 6(1-t)t (1-t)(1-3t) (2-3t)t
Second derivatives: fi''(t), gi''(t) -6+12t 6-12t -4+6t 2-6t

The relation of the functions: f0(t)= f1(1-t), f0(1-t)= f1(t), g0(t)= g1(1-t), g0(1-t)= g1(t)
The expression of (4) may be convenient for handling the tangent vectors of the curve segment because the tangent vectors are expressed explicitly.

The definition of Tin, Tout
A spline curve can be represented by multiple Ferguson segments. In this case, two tangent vectors are defined at the i-th segment junction point - the first tangent vector is used for interpolate the (i-1)-the segment and the second is for the i-th segment. Those tangent vectors are denoted by P'(1) and P'(0) in the (4) and hereafter those vectors are denoted by Tin[i] and Tout[i] respectively.
In the case of a smooth spline, the directions of Tin[i] and Tout[i] are the same, however the lengths of Tin[i] and Tout[i] are not equal in general.


Figure 1.1 Curve segment and Tin, Tout
Annotation: The real (mathematical) direction of the Tin is the inverted direction that the Figure shows.



2. Class Segment2D return=>page top
public class Segment2D

The Segment2D class represents a parametric curve segment of Line2D, Arc2D and CubicCurve2D in the java.awt.geom package. The QuadCurve2D in the java.awt.geom is not used for the parametric curve segment, because it doesn't seem useful.
The major function of the Segment2D class is to calculate the position, tangent vector and second derivative vector of the parametric curve segment for a given parameter t (0≤t≤1) by the expression of the parametric curve segment.


Field Description
type int type
This field represents the type of the parametric curve segment.
One of the LINE, ARC or CUBIC is set to this filed.

shape

private Shape shape
One of the Line2D, Arc2D or CubicCurve2D object in the java.awt.geom is set to this field according to the type.
affineTransform private AffineTransform affineTransform
Stores the AffineTransform for the Arc2D object.
If the type equals Line or CUBIC, this field is not used to represent a transformed object, because the transformed object can be created from the original Line2D or CubicCurve2D object by transforming is endpoints and control points.
MOVETO public static final int MOVETO=0
The constants to be set to the type field.
Moves a point to the start point of the next subpath.

LINE

public static final int LINE=1
The constants to be set to the type field. The Line2D object is set to the shape field.
ARC public static final int ARC=2
The constants to be set to the type field. The Arc2D object is set to the shape field.
CUBIC public static final int CUBIC=3
The constants to be set to the type field. The CubicCurve2D object is set to the shape field.
QUAD public static final int QUAD=4
The constants to be set to the type field. The QuadCurve2D object is set to the shape field.
Not used currently.

Method Description
Constructor public Segment2D(int type, Shape shape) Sets the parameters to the corresponding field. Null is set to the affineTransform field.
Constructor public Segment2D(int type, Shape shape, AffineTransform affineTransform)
Sets the parameters to the corresponding field.
getType public int getType2()
Returns the type field.
isAffineTransform public boolean isAffineTransform()
Return true if the affineTransform isn't null.
getShape public Shape getShape()
Returns the shape field.
If thetype equals ARC and the affineTransform isn't null, then return the java.awt.geom.GeneralPath object which is created by using the shape and the affineTransform.
=> Returning the transformed Arc2D
getP public Point2D getP(double t)
Parameter:
t - The parameter of the curve segment.. 0≤t≤1.
Returns:
The position (x,y) of the curve segment at the parameter t.
getTangent public Vector2D getTangent(double t)
Parameter:
t - The parameter of the curve segment. 0≤t≤1.
Returns:
The derivative (tangent vector) of the curve segment at the parameter t.
getTangentDerivative public Vector2D getTangentDerivative(double t)
Parameter:
t - The parameter of the curve segment. 0≤t≤1.
Returns:
The second derivative (vector) of the curve segment t at the parameter t.
getEndPoints public Point2D[] getEndPoints()
Returns the endPoints of this object.
getCharacteristicPoints public CurvePT[] getCharacteristicPoints()
Returns the characteristic points of this object. Characteristic points are endpoints and middle points of the curve segments of this object, and north, south, east and west points of an ellipse or a circle.
getSegmentLength public double getSegmentLength(double t1, double t2)
Returns the curve length of the curve segment interval (t1≤t≤t2). 0≤t1, t2≤1.
getBoundingBox public Rectangle2D getBoundingBox()
Returns the bounding box enclosing the curve segment.
getBoundingBox public Rectangle2D getBoundingBox(double t1, double t2)
Returns the bounding box enclosing the curve segment interval (t1≤t≤t2).
0≤t1, t2≤1
resizeSegment public Segment2D resizeSegment(Rectangle2D oldBox, Rectangle2D newBox)
Parameters:
oldBox - The previous dragged rectangle.
newBox - The current dragged rectangle.
Returns:
The resized Segment2D object.
Processing:
⋅ If the affineTransform equals null, then performs the following.

Creates the resized Line2D, Arc2D or CubicCurve2D objects and creates a new Segment2D object using the type and the resized object.

⋅ If the type equals ARC and the affineTransform doesn't equals null, then performs the following.

Creates a transforming matrix by the getResizeMatrix method of the Matrix2D.
And calculates the multiplied matrix by the affineTransform and the transforming matrix, then returns a new Segment2D object which is created by using the type, the shape and the multiplied matrix.

trimSegment public Segment2D trimSegment(double t1, double t2)
Parameters:
t1 - The start parameter of the trimmed segment.
t2 - The end parameter of the trimmed segment.
0≤t1, t2≤1
Returns:
The trimmed Segment2D object.
Processing:
Creates the trimmed Shape object of Line2D, Arc2D or CubicCurve2D. Then creates a new Segment2D object using the type, the trimmed Shape and the affineTransform, and returns the new Segment2D.
getFergusonCurve public FergusonCurve2D getFergusonCurve()
Returns:
The FergusonCurve2D object converted from this Segment2D object.
Processing:
⋅ If the type equals LINE or CUBIC, then performs the following.

In this case, the Segment2D object can be converted to a single Ferguson segment within round-off error. So, returns the FergusonCurve2D of single segment.

⋅ If the type equals ARC, then performs the following.

The Segment2D can be approximated with multiple Ferguson segments by using the getOptimizedTangents method of the FergusonCurve2D. The number of the Ferguson segments is determined so that the approximation error is lower than 1e-8 for a unit circle.
As the result, the error range can be lower than 1e-4 for any shape on the canvas. In this case, returns the FergusonCurve2D of multiple segments.

transformSegment public Segment2D transformSegment(Matrix2D M)
Parameters:
M - The transforming matrix.
Returns:
The transformed Segment2D object.
Processing:
⋅ If the type equals Line2D or CubicCurve2D, then performs the following.

Creates a new Line2D or CubicCurve2D object by transforming the endpoints and control points of the shape and creates a new Segment2D object using the type and the new Line2D or CubicCurve2D object.

⋅ If the type equals ARC, then performs the following.

Calculates the multiplied matrix of the affineTransform and the transforming matrix M and created a new Segment2D object by using the type, the shape and the multiplied matrix.
Then returns the new Segment2D object.

reverseSegment public Segment2D reverseSegment()
Returns:
The Segment2D object which is reversed in curve direction.
Processing:
Creates a new Line2D, Arc2D or CubicCurve2D object whose direction is reversed and creates a new Segment2D object using the type and the reversed object, then returns the new Segment2D object.
moveSegmentEndPT public Segment2D moveSegmentEndPT(int index, Point2D newPT)
Parameters:
index - if the index equals 0, then move the start point of the curve segment, otherwise moves the end point of the curve segment.
newPT - The new endpoint.
Returns:
The Segment2D object whose specified endpoint was moved to the newPT.
Processing:
⋅ The case of the type equals LINE

Replaces the specified endpoint by the newPT.

⋅ The case of the type equals ARC

Creates the transforming matrix by the getRotationMatrix method of the Matrix2D and transforms this Segment2D object by the transformSegment method.

⋅ The case of the type equals CUBIC

Creates a new segment2D object by using the movePoint method of the FergusonCurve2D.

moveSegmentTangent public void moveSegmentTangent(int index, Vector2D newTangent)
Parameters:
index - if the index equals 0, then changes the tangent line at the start point, otherwise changes the tangent line at the end point of the curve segment.
newtangent - The new tangent vector.
Returns:
The Segment2D object whose direction of the tangent line at the specified endpoint was changed to the the direction of the newTangent.
Processing:
This method is used only for the Segment2D object whose type equals CUBIC.
Creates a new segment2D object by using the moveTangent method of the FergusonCurve2D.
clone public Object clone()
returns the clone of this object.
toString public String toString()
Returns the string representing this object.
getSerializableSegment2D public SerializableSegment2D getSerializableSegment2D()
Returns the SerializableSegment2D object which is used for writing this object to the file.

: Returning the transformed Arc2D
Shape shape=this.shape;
if(this.type==ARC&&this.affineTransform!=null){
GeneralPath generalpath=new GeneralPath();
generalpath.append(shape, false);
generalpath.transform(this.affineTransform);
shape=generalpath;
}
return shape;


3. The extension of java.awt.geom (geomExtension) return=>page top
We extends the classes of the Rectangle2D, RoundRectangle2D, Ellipse2D etc. in java.awt.geom package to be able to handle a parametric curve. The names of the extended classes are denoted by adding "E" at the end of the original class names - Rectangle2DE, RoundRectangle2DE, Ellipse2DE etc.
The each extended class has the array of parametric curve segments (Segment2D objects) and the java.awt.Shape object.
The array of the parametric curve segments is used for calculating the position (x,y), the tangent vector and the second derivative of the parametric curve. The Shape object is used for drawing the shape of the parametric curve by the methods of java.awt.Graphics and java.awt.Graphics2D. And the Shape object is also used for testing whether a specified point is inside the boundary of the Shape or not, by the contains method of the Shape.

Creating the java.awt.Shape object of a parametric curve

The java.awt.geom.GeneralPath is employed to create the Shape object of the parametric curve as follows.


Example:The constructor of the RoundRectangle2DE

A round rectangle consists of eight pieces of shapes - four straight lines and four arcs of the 90° central angle - and those pieces are arranged as line->arc->line->arc->⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ as mentioned in 1.1.


public RoundRectangle2DE(double x, double y, double width, double height, double arcw, double arch){
this.x=x; this.y=y; this.width=width; this.height=height;
this.arcw=arcw; this.arch=arch;
this.generalPath=new GeneralPath();
this.segments=new Segment2D[8];
Line2D line0=new Line2D.Double(x, y+0.5*arch, x, y+height-0.5*arch);
Line2D line1=new Line2D.Double(x+0.5*arcw, y+height, x+width-0.5*arcw, y+height);
Line2D line2=new Line2D.Double(x+width, y+height-0.5*arch, x+width, y+0.5*arch);
Line2D line3=new Line2D.Double(x+width-0.5*arcw, y, x+0.5*arcw, y);

Arc2D arc0=new Arc2D.Double(x, y+height-arch, arcw, arch, 180, 90, Arc2D.OPEN);
Arc2D arc1=new Arc2D.Double(x+width-arcw, y+height-arch, arcw, arch, 270, 90, Arc2D.OPEN);
Arc2D arc2=new Arc2D.Double(x+width-arcw, y, arcw, arch, 0, 90, Arc2D.OPEN);
Arc2D arc3=new Arc2D.Double(x, y, arcw, arch, 90, 90, Arc2D.OPEN);

segments[0]=new Segment2D(Segment2D.LINE, line0);
segments[1]=new Segment2D(Segment2D.ARC, arc0);
segments[2]=new Segment2D(Segment2D.LINE, line1);
segments[3]=new Segment2D(Segment2D.ARC, arc1);
segments[4]=new Segment2D(Segment2D.LINE, line2);
segments[5]=new Segment2D(Segment2D.ARC, arc2);
segments[6]=new Segment2D(Segment2D.LINE, line3);
segments[7]=new Segment2D(Segment2D.ARC, arc3);

for(int i=0;i<segments.length;i++){
Shape shape=segments[i].getShape();
generalPath.append(shape,true);
}
generalPath.closePath();
}


4. abstract class Curve2D return=>page top
public abstract class Curve2D
This class provides basic and common methods of the parametric curve. The other classes are the extended classes of this abstract class.

Field Description
segments Segment2D[] segments
The Segment2D objects which compose this parametric curve.
generalPath GeneralPath generalPath
The GeneralPath object which is referred as java.awt.Shape in getShape method..
This object is created by appending the shape - Line2D, Arc2D or CubicCurve2D - of Segment2D objects in the Curve2D constructor.
=> Creating and extracting java.awt.Shape
closed boolean closed
True if this parametric curve is closed.
Constants which represent Curve2D extensions public static final int RECTANGLE=1, ROUND_RECTANGLE=2, ELLIPSE=3, LINE=4, POLYLINE=5, CUBIC_CURVE=6, GENERAL_CURVE=7
The constants representing the type of the extended classes of this class.
eps public final static double eps=1e-5
The small number.
largeNumber public final static double largeNumber=1e+5
The large number.
ClosedTolerance public final static double ClosedTolerance=3d
The number used for testing whether the parametric curve is closed or not.

Method Description
Constructor public Curve2D(Segment2D[] segments)
Create a new Curve2D object with the Segment2D objects.
this.segments=segments;
this.generalPath=new GeneralPath();
Point2D startP=segments[0].getP(0);
Point2D endP=segments[segments.length-1].getP(1);
double dist=Vector2D.dist(new Vector2D(startP), new Vector2D(endP));
this.closed=false;
if(dist<Curve2D.eps) closed=true;
for(int i=0;i<segments.length;i++) {
Shape shape=segments[i].getShape();
this.generalPath.append(shape,true);
}
if(this.closed) this.generalPath.closePath();
setData public void setData(Segment2D[] segments)
Performs the same processing as the constructor.
getType2DE
(abstract)
public abstract int getType2DE()
Return the type of this parametric curve. The types are RECTANGLE, ROUND_RECTANGLE, ELLIPSE and so on.
getShape public Shape getShape()
Return the generalPath field.
=> Creating and extracting java.awt.Shape
isClosed public boolean isClosed()
Rturns the closed field.
getNumOfSegments public int getNumOfSegments()
Returns the number of the curve segments (segments field).
getSegment2Ds public Segment2D[] getSegment2Ds()
Return the segments.
getSegment2D public Segment2D getSegment2D(int Index)
Return the curve segment specified by the index.
getP public Point2D getP(double t)
Parameter:
t - The parameter of the curve segment.
0≤t≤nseg, nseg: the returned value of the getNumOfSegments.
Returns:
The position (x,y) of the parametric curve at the t.
getTangent public Vector2D getTangent(double t)
Parameter:
t - The parameter of the curve segment.
0≤t≤nseg, nseg: the returned value of the getNumOfSegments.
Returns:
The derivative (tangent vector) of the parametric curve at the t.
getTangentDerivative public Vector2D getTangentDerivative(double t)
Parameter:
t - The parameter of the curve segment.
0≤t≤nseg, nseg: the returned value of the getNumOfSegments.
Returns:
The second derivative vector of the parametric curve at the t.
getEndPoints public Point2D[] getEndPoints()
Returns the endpoints.
getCharacteristicPoints public CurvePT[] getCharacteristicPoints()
Returns the characteristic points. The characteristic points are endpoints of a line/curve segment, and north, south, east and west points of an ellipse/circle.
=> ConnectionLS Figure 1
getCurveLength public double getCurveLength(double t1, double t2)
Parameters:
t1 - The start parameter of the interval.
t2 - The end parameter of the interval.
0≤t1, t2≤nseg, nseg: the returned value of the getNumOfSegments.
Returns:
Returns the curve length of the interval (t1≤t≤t2).
getBoundingBox public Rectangle2D getBoundingBox()
Returns the bounding box enclosing the parametric curve.
getBoundingBox public Rectangle2D getBoundingBox(double t1, double t2)
Parameters:
t1 - The start parameter of the interval.
t2 - The end parameter of the interval.
0≤t1, t2≤nseg, nseg: the returned value of the getNumOfSegments.
Returns:
Returns the bounding box enclosing the curve interval (t1≤t≤t2) of the parametric curve.
getSerializableCurve2D public SerializableCurve2D getSerializableCurve2D()
Returns:
The SerializableCurve2D object which is used for writing this object to the file.
setSerializableCurve2D public void setSerializableCurve2D(SerializableCurve2D sdata)
Parameters:
sdata - The SerializableCurve2D object which is used for writing this object to the file.
Processing:
Sets the contents of the sdata to this object.
convertToGeneral
Curve2DE
public GeneralCurve2DE convertToGeneralCurve2DE()
Converts this object to the GeneralCurve2DE object.
This method is used for rotating Rectangle2DE, RoundRectangle2D etc.
reverse public void reverse()
Reverses the direction of parametric curve by using the Segment2D.reverseSegment.
transform public void transform(Matrix2D M)
Parameters:
M - The transforming matrix.
Processing:
Transforms the parametric curve by using the Segment2D.transformSegment method.
clone
(abstract)
public abstract Object clone()
Returns the clone of this object.
toString
(abstract)
public abstract String toString()
Returns the string representing this object.


5. Class Rectangle2DE return=>page top
public class Rectangle2DE extends Curve2D
Method Description
Constructor Rectangle2DE(Segment2D[] segments)
Calls the Curve2D constructor.
Constructor public Rectangle2DE(double x, double y, double width, double height)
Parameters:
The same as the java.awt.geom.Rectangle2D.Double.
Processing:
Creates a new Rectangle2DE object by connecting the four Segment2D objects of LINE.
getType2DE public int getType2DE()
Returns the constant of Curve2D.RECTANGLE.
getX public double getX()
Same as the getX method of the java.awt.geom.Rectangle2D.
Returns the x-coordinate of the upper-left corner point of the rectangle.
getY public double getY()
Same as the getY method of the java.awt.geom.Rectangle2D.
Returns the y-coordinate of the upper-left corner point of the rectangle.
getWidth public double getWidth()
Same as the getWidth method of the java.awt.geom.Rectangle2D.
Returns the width of the rectangle.
getHeight public double getHeight()
Same as the getHeight method of the java.awt.geom.Rectangle2D.
Returns the height of the rectangle.
clone public Object clone()
Returns the clone of this object.
toString public String toString()
Returns the string representing this object.


6. RoundRectangle2DE return=>page top
public class RoundRectangle2DE extends Curve2D
Method Description
Constructor RoundRectangle2DE(Segment2D[] segments)
Calls the Curve2D constructor.
Constructor public RoundRectangle2DE(double x, double y, double width, double height, double arcw, double arch)
Parameters:
The same as the java.awt.geom.RoundRectangle2D.Double.
Processing:
Creates a new RoundRectangle2DE object by connecting the eight Segment2D objects of LINE and ARC.
setData public void setData(double x, double y, double width, double height, double arcw, double arch)
Performs the same operation of the above constructor.
getType2DE public int getType2DE()
Returns the constant of Curve2D.ROUND_RECTANGLE.
getX public double getX()
Same as the getX method of the java.awt.geom.RoundRectangle2D.
Returns the x-coordinate of the upper-left corner point of the round rectangle.
getY public double getY()
Same as the getY method of the java.awt.geom.RoundRectangle2D.
Returns the y-coordinate of the upper-left corner point of the round rectangle.
getWidth public double getWidth()
Same as the getWidth method of the java.awt.geom.RoundRectangle2D.
Returns the width of the round rectangle.
getHeight public double getHeight()
Same as the getHeight method of the java.awt.geom.RoundRectangle2D.
Returns the height of the round rectangle.
getArcWidth public double getArcWidth()
Returns the width of the arc that rounds off the corners.
getArcHeight
public double getArcHeight()
Returns the height of the arc that rounds off the corners.
clone
public Object clone()
Returns the clone of this object.
toString public String toString()
Returns the string representing this object.


7. Ellipse2DE return=>page top
public class Ellipse2DE extends Curve2D
Method Description
Constructor Ellipse2DE(Segment2D[] segments)
Calls the Curve2D constructor.
Constructor public Ellipse2DE(double x, double y, double width, double height)
Parameters:
The same as the java.awt.geom.Ellipse2D.Double.
Processing:
Creates a new Ellipse2DE object by the Segment2D object of ARC.
getType2DE public int getType2DE()
Returns the constant of Curve2D.ELLIPSE.
getX public double getX()
Same as the getX method of the java.awt.geom.Ellipse2D.
Returns the x-coordinate of the upper-left corner point of the covering rectangle.
getY public double getY()
Same as the getY method of the java.awt.geom.Ellipse2D.
Returns the y-coordinate of the upper-left corner point of the covering rectangle.
getWidth public double getWidth()
Same as the getWidth method of the java.awt.geom.Ellipse2D.
Returns the width of the covering rectangle.
getHeight public double getHeight()
Same as the getHeight method of the java.awt.geom.Ellipse2D.
Returns the height of the covering rectangle.
clone public Object clone()
Returns the clone of this object.
toString public String toString()
Returns the string representing this object.


8. Line2DE return=>page top
public class Line2DE extends Curve2D
Method Description
Constructor Line2DE(Segment2D[] segments)
Calls the Curve2D constructor.
Constructor Line2DE(Point2D p1, Point2D p2)
Parameters:
The same as the java.awt.geom.Line2D.Double.
Processing:
Creates a new Line2DE object by the Segment2D object of LINE.
getType2DE public int getType2DE()
Returns the constant of Curve2D.LINE.
setData public void setData(Point2D p1, Point2D p2)
Performs the same operation of the above constructor.
getP1 public Point2D getP1()
Returns the start point.
getP2 public Point2D getP2()
Returns the end point.
getX1 public double getX1()
Returns the x coordinate of the start point.
getY1 public double getY1()
Returns the y coordinate of the start point.
getX2 public double getX2()
Returns the x coordinate of the end point.
getY2 public double getY2()
Returns the y coordinate of the end point.
getTrimmedCurve2DE public Line2DE getTrimmedCurve2DE(double t1, double t2)
Parameters:
t1 - The start parameter of the trimmed curve.
t2 - The end parameter of the trimmed curve.
0≤t1, t2≤1
Returns:
The trimmed Line2DE object.
getTrimmedLine public Line2DE getTrimmedLine(double cut1, double cut2)
Parameters:
cut1 - The cutting length (pixels) at the start point.
cut2 - The cutting length (pixels) at the end point.
Returns:
The trimmed Line2DE object.
Processing:
This method uses the getTrimmedCurve2DE.
clone public Object clone()
Returns the clone of this object.
toString public String toString()
Returns the string representing this object.


9. Polyline2DE return=>page top
public class Polyline2DE extends Curve2D
Method Description
Constructor Polyline2DE(Segment2D[] segments)
Calls the Curve2D constructor.
Constructor public Polyline2DE(Point2D[] points)
Creates a new Polyline2DE object by the junction points.
Whether this Polyline2DE is closed or not is judged by the Curve2D.ClosedTolerance.
Constructor public Polyline2DE(Point2D[] points, boolean closed)
Creates a new Polyline2DE object by the junction points.
Whether this Polyline2DE is closed or not is specified explicitly by the parameter.
setData public void setData(Point2D[] points)
Performs the same operation of the above constructor.
getType2DE public int getType2DE()
Returns the constant of Curve2D.POLYLINE.
getPoints public Point2D[] getPoints()
Returns the junction points.
getPoint public Point2D getPoint(int index)
Return the junction point specified by index.
getTrimmedCurve2DE public Polyline2DE getTrimmedCurve2DE(double t1, double t2)
Parameters:
t1 - The start parameter of the trimmed curve.
t2 - The end parameter of the trimmed curve.
0≤t1, t2≤nseg. nseg: the returned value of the getNumOfSegments.
Returns:
The trimmed Polyline2DE object.
getTrimmedPolyline public Polyline2DE getTrimmedPolyline(double cut1, double cut2)
Parameters:
cut1 - The cutting length (pixels) at the start point.
cut2 - The cutting length (pixels) at the end point.
Returns:
The trimmed Polyline2DE object.
Processing:
This method uses the getTrimmedCurve2DE.
clone public Object clone()
Returns the clone of this object.
toString public String toString()
Returns the string representing this object.


10. CubicCurve2DE return=>page top
public class CubicCurve2DE extends Curve2D
Method Description
Constructor CubicCurve2DE(Segment2D[] segments)
Calls the Curve2D constructor.
Constructor public CubicCurve2DE(Point2D[] Q)
Creates a new CubicCurve2DE object by the control points.
The number of the control points must be 3*n+1. Here "n" is the number of curve segments (Segment2D objects).
setData public void setData(Point2D[] points)
Performs the same operation of the above constructor.
getType2DE public int getType2DE()
Returns the constant of Curve2D.CUBIC_CURVE.
getPoints public Point2D[] getPoints()
Returns the segment junction points. The segment junction point means the junction point of the curve segments.
getCtrlPoints public Point2D[] getCtrlPoints()
Returns the control points.
getFergusonCurve2D public FergusonCurve2D getFergusonCurve2D()
Converts this multiple cubic curves to the Feguson curve and returns the Feguson curve (FergusonCurve2DE).
getTout public Vector2D getTout(int index)
Parameter:
index - The index of the segment junction point.
Returns:
The the tangent line (OUT) at the plus side of the specified node point.

getTin public Vector2D getTin(int index)
Paremeter:
index - The index of the segment junction point.
Returns:
The tangent line (IN) at the minus side of the specified node point.
getTrimmedCurve2DE public CubicCurve2DE getTrimmedCurve2DE(double t1, double t2)
t1 - The start parameter of the trimmed curve.
t2 - The end parameter of the trimmed curve.
0≤t1, t2≤nseg. nseg: the returned value of the getNumOfSegments.
Returns:
The trimmed CubicCurve2DE object.
clone public Object clone()
Returns the clone of this object.
toString public String toString()
Returns the string representing this object.


11. GeneralCurve2DE return=>page top
public class GeneralCurve2DE extends Curve2D<

This class represents a parametric curve which consists of arbitrary number of subpaths.


Figure 11.1 Global numbering of the segments and junction points
Segment number: Seg-0, Seg-1,..., Segment point (Junction point) number: P-0, P-1,....


Figure 11.2 Local numbering of the segments and junction points
The segments and the junction points are numbered from 0 for each sub path.
(a) Prints out the 0-7 segments

segment[0]=CUBIC, P1=640.04,371.28, P2=685.90,324.95, CtrlP1=654.01,353.07,CtrlP2=665.80,324.95
segment[1]=CUBIC, P1=685.90,324.95, P2=775.45,415.98, CtrlP1=722.90,324.95, CtrlP2=738.46,415.93
segment[2]=CUBIC, P1=775.45,415.98, P2=846.18,364.98, CtrlP1=801.94,416.01, CtrlP2=831.32,406.89
segment[3]=MoveTo
segment[4]=CUBIC, P1=928.82,371.58, P2=1,004.96,328.01, CtrlP1=926.56,337.66, CtrlP2=975.82,334.84
segment[5]=CUBIC, P1=1,004.96,328.01, P2=1,085.27,382.36, CtrlP1=1,041.93,319.35, CtrlP2=1,086.01,344.76
segment[6]=CUBIC, P1=1,085.27,382.36, P2=989.42,438.44, CtrlP1=1,084.42,425.39, CtrlP2=1,029.39,455.40
segment[7]=CUBIC, P1=989.42,438.44, P2=928.82,371.58, CtrlP1=960.27,426.07, CtrlP2=931.06,405.02


(2) Prints out 0-7 segments in subpath-form

- sub path=0, close=false, numseg=3, startSegment=0, endSegment=2 [ start t-param=0, end t-param=3 ]

segment[0]=CUBIC, P1=640.04,371.28, P2=685.90,324.95, CtrlP1=654.01,353.07, CtrlP2=665.80,324.95
segment[1]=CUBIC, P1=685.90,324.95, P2=775.45,415.98, CtrlP1=722.90,324.95, CtrlP2=738.46,415.93
segment[2]=CUBIC, P1=775.45,415.98, P2=846.18,364.98, CtrlP1=801.94,416.01, CtrlP2=831.32,406.89

- sub path=1, close=true, numseg=4, startSegment=4, endSegment=7 [ start t-param=4, end t-param=8 ]

segment[0]=CUBIC, P1=928.82,371.58, P2=1,004.96,328.01, CtrlP1=926.56,337.66, CtrlP2=975.82,334.84
segment[1]=CUBIC, P1=1,004.96,328.01, P2=1,085.27,382.36, CtrlP1=1,041.93,319.35, CtrlP2=1,086.01,344.76
segment[2]=CUBIC, P1=1,085.27,382.36, P2=989.42,438.44, CtrlP1=1,084.42,425.39, CtrlP2=1,029.39,455.40
segment[3]=CUBIC, P1=989.42,438.44, P2=928.82,371.58, CtrlP1=960.27,426.07, CtrlP2=931.06,405.02



Method Description
Constructor GeneralCurve2DE(Segment2D[] segments)
Calls the following setData method.
setData public void setData(Segment2D[] segments)
Sets the segments (Segment2D objects) to this object. For the Figure 11.1 example, sets the 8 segments inclideing one MOVETO segment.
getType2DE public int getType2DE()
Returns the constant of Curve2D.GENERAL_CURVE.
getNumOfSubPaths public int getNumOfSubPaths()
Returns the number of the subpaths of this object. Returns 2 for the Figure 11.1 example.
getNumOfLocalSegments public int[] getNumOfLocalSegments()
Returns each number of the segments which configures a subpaths.
For the Figure 11.1 example, returns int[0]=3, int[0]=4, which means the first path consists of 3 segments and the second path consists of 4 segments.
getSubPathIndex public int getSubPathIndex(int segmentPtIndex)
Return the subpath number for the argument which specifies a segment number or segment joint number.
For the Figure 11.1 example, returns 0 as the subPath index for segmentPtIndex=0 - 3, and returns 1 as the subPath index for segmentPtIndex=4 - 8.
getLocalSegmentIndex private int getLocalSegmentIndex(int segmentIndex)
Returns the local segment number of a sub path for the specified argument which is the global segment number.
The sub path number can be givven by getSubPathIndex method.
For the Figure 11.1 example, returns as follows.
⋅ segmentIndex=0 - 2 => localSegmentIndex=0 - 2,
⋅ segmentIndex=4 - 7 => localSegmentIndex=0 - 3,
⋅ segmentIndex=3 => localSegmentIndex=-1(MOVETO segment, ineffective)
getLocalSegmentPtIndex public int getLocalSegmentPtIndex(int segmentPtIndex)
Returns the local segment junction point number of a sub path for the specified argument which is the global segment junction point number. The sub path number can be givven by getSubPathIndex method.
For the Figure 11.1 example, returns as follows.
⋅ segmentPtIndex=0 - 3=>localSegmentPtIndex=0 - 3.
⋅ segmentPtIndex=4 - 8=>localSegmentPtIndex=0 - 4.
getGlobalSegmentIndex private int getGlobalSegmentIndex(int subPathIndex, int localSegmentIndex)
Return the global segment number for the specified arguments which are sub path number and the local segment number.
For the Figure 11.1 example, returns as follows.
⋅ subPathIndex=0, localSegmentIndex=0 - 2 => globalSegmentIndex=0 - 2.
⋅ subPathIndex=1, localSegmentIndex=0 - 3 => globalSegmentIndex=4 - 7.
⋅ return -1 (ineffective) except the aboves.
getGlobalSegmentPtIndex public int getGlobalSegmentPtIndex(int subPathIndex, int localSegmentPtIndex)
Return the global segment junction point number for the specified arguments which are sub path number and the local segment junction point number.
For the Figure 11.1 example, returns as follows.
⋅ subPathIndex=0, localSegmentPtIndex=0 - 3 => globalSegmentPtIndex=0 - 3.
⋅ subPathIndex=1, localSegmentPtIndex=0 - 4 => globalSegmentPtIndex=4 - 8.
⋅ return -1 (ineffective) except the aboves.
getSubPathSegments private Segment2D[] getSubPathSegments(int subPathIndex)
Returns the segments which belong to the sub path specified by argument.
For the Figure 11.1 example, returns as follows.
⋅ subPathInde=0 => returns 0 - 2 segments.
⋅ subPathInde=1 => returns 4 -7 segments.
getSubPath private GeneralCurve2DE getSubPath(int index)
Returns the sub path curve as a GeneralCurve2DE object for the specified argument which is sub path number.
For the Figure 11.1 example, returns as follows.
⋅ subPathInde=0 => GeneralCurve2DE object which consists of 0 - 2 segments.
⋅ subPathInde=1 => GeneralCurve2DE object which consists of 4 - 7 segments.
getSubPaths public GeneralCurve2DE[] getSubPaths()
Returns the array the sub paths which are represented as GeneralCurve2DE objects.
setSubPaths public void setSubPaths(Curve2D[] curves)
Specifies the plural sub paths as the arguments and sets them to this object.
⋅ Checks the connections between the specified sub paths by the PathConnect class, and connects them if possible.
isClosed public boolean isClosed()
Return true, if the sub path of this object is only one and it is closed. Returns false for the othe case.
To confirm closed or not closed for each subpath, use getPaths method and inquire by isClosed method of each sub path object.
getTrimmedCurve2DE public CubicCurve2DE getTrimmedCurve2DE(double t1, double t2)
t1 - The start parameter of the trimmed curve.
t2 - The end parameter of the trimmed curve.
0≤t1, t2≤nseg. nseg: the returned value of the getNumOfSegments.
Returns:
The trimmed GeneralCurve2DE object.
getSimpleCurve2Ds public Curve2D[] getSimpleCurve2Ds()
getSimpleCurve2D public Curve2D getSimpleCurve2D()
Returns:
The Curve2DE object of simpler form.
Processing:
If this GeneralCurve2DE can be converted to Line2DE,Polyline2DE or CubicCurve2DE, then converts the GeneralCurve2DE to simpler form and returns it.
clone public Object clone()
Returns the clone of this object.
toString public String toString()
Returns the string representing this object.


12. FergusonCurve2D return=>page top
public class FergusonCurve2D
This class is not a extended class of the Curve2D and it represents the Ferguson curve.
The Ferguson curve is convenient for handling the tangent vectors of the curve segment because the tangent vectors are expressed explicitly.



Figure 12.1 Ferguson curve

=> The definition of Tin, Tout


Field Description
P Point2D[] P
The array of the segment junction points.
Tin Vector2D[] Tin
The array of the tangent vectors at the segment junction points which interpolate the next curve segments.
=> Ferguson curve segment on this page
Tout Vector2D[] Tout
The array of the tangent vectors at the segment junction points which interpolate the previous curve segments.
=> Ferguson curve segment on this page
closed boolean closed
True if the curve is closed.
pai static double pai=Math.PI
The circle ratio.
eps static double eps=1e-12
The small number.
TIN, TOUT public static final int TIN=0, TOUT=1

Method Description
Constructor public FergusonCurve2D()
Creates a new object that has no curve data.
Constructor public FergusonCurve2D(Point2D[] P, Vector2D[] Tin, Vector2D[] Tout)
Parameters:
P - The array of the segment junction points.
Tin - The array of the tangent vectors at the segment junction points which interpolate the next curve segments
Tout - The array of the tangent vectors at the segment junction points which interpolate the previous curve segments.
Processing:
Sets the parameters to corresponding fields.
If P[0}=P[np-1], then sets true to the closed field.
np: the number of the segment junction points.
isClosed public boolean isClosed()
Return the closed field.
getNumOfSegments public int getNumOfCSegments()
Returns the number of the curve segments.
getCubicCurve2DE public CubicCurve2DE getCubicCurve2DE()
Returns the CubicCurve2DE object which is converted from this object.
getCubicCurve2D public CubicCurve2D getCubicCurve2D(int index)
Returns the java.awt.geom.CubicCurve2D object which is converted from the curve segment of this object specified by the index.
getCtrlPoints public Point2D[] getCtrlPoints()
Converts this FergusonCurve2D object to the CubicCurve2DE object and returns the control points of the CubicCurve2DE.
The number of the control points is (3×(np-1)+1).
np: the number of the segment junction points.
getP public Point2D getP(int index)
Returns the segment junction point specified by the index.
setP public void setP(Point2D P, int index)
Sets the point P to the P at the position specified by the index.
getTin public Vector2D getTin(int index)
Returns the Tin (tangent vector) specified by the index.
setTin public void setTin(Vector2D Tin, int index)
Sets the tangent vector Tin to the Tin at the position specified by the index..
getTout public Vector2D getTout(int index)
Returns the Tout (tangent vector) specified by the index.
setTout public void setTout(Vector2D Tout, int index)
Sets the tangent vector Tout to the Tout at the position specified by the index.
getP public Point2D getP(double t)
Returns the point on the Fergusn curve specified by t.
getTangent public Vector2D getTangent(double t)
Returns the tangent vector on the Fergusn curve specified by t.
movePoint public void movePoint(int index, Point2D newPoint)
Paremeters:
index - The index of the segment junction point to be moved.
newPoint - the new segment junction point.
Processing:
Replace the segment junction point (P[index]) by the newPoint. The directions of the Tout[index-1], Tin[index], Tout[index] and Tin[index+1] are not changed, however the lengths of those vectors are optimized by the getOptimizedTangents method.
moveTangent public void moveTangent(int index, Vector2D newTangent)
Paremeters:
index - The index of the segment junction point.
newTangent - The new tangent vector.
The direction of the newTangent will be referred (the length isn't referred).
Processing:
Replaces the direction of the Tin[index], Tout[index] by the newTangent. The lengths of the Tout[index-1], Tin[index], Tout[index] and Tin[index+1] are optimized by the getOptimizedTangents method.
addPoint public void addPoint(double t)
Parameters:
t - The curve parameter of the point to be added.
Processing:
Adds the segment junction point at the parameter of t.
Let's define as it= (int)t, then the new segment junction point is indicated by the index of (it+1).
The point and the Tin, Tout at t can be calculated by the getP and the getTangent, so by adding these data to P[it+1], Tin[it+1] and Tout[it+1], the new Ferguson curve will be created.
However the length of the Tout[it], Tin[it+1], Tout[it+1] and Tin[it+2] must be changed so that any point on the new curve lies on the original curve.
The formulas of the new lengths are the follows.
⋅ The lengths of Tout[it], Tin[it+1]:Provided by the formula of (t-it)*(the original length).
⋅ The lengths of Tout[it+1], Tin[it+2]:Provided by the formula of (i+1-t)*(the original length).
deletePoint public void deletePoint(int index)
Parameters:
index - The index of the segment junction point to be delete.
Processing:
Deletes the P[index], Tin[index] and Tout[index] and creates a new curve.
If the original curve is closed, then the new curve must be closed.



toString public String toString()
Return the string representing this object.
createNaturalSpline
(static)
public static FergusonCurve2D createNaturalSpline(Point2D[] nodePTs)
Paremeters:
nodePTs - The segment junction points of the spline
Returns:
The C2 class spline curve of Furguson curve format.
Processing:
Creates the C2 class spline curve which passes the given segment junction points (nodePTs).
⋅ If the start point and the end point of the given points doesn't occupy the same location, then performs the following.

Calls the getUnitTangentOfOpenCurve method to determine the tangent directions at the given points for a open (not closed) spline.

⋅ If the start point and the end point of the given points occupies the same location, then performs the following.

Calls the getUnitTangentOfOpenCurve method to determine the tangent directions at the given points for a closed spline.

The length of the tangent vectors are determined by the the Curve2DUtil.createCircularArcs method.
getUnitTangentOf
OpenCurve

(static)
public static Vector2D[] getUnitTangentOfOpenCurve(Point2D[] nodePTs)
Parameters:
nodePTs - The segment junction points of the spline.
Returns:
The unit tangent vectors at the nodePTs.
Processing:
Solves the linear equation by the Matrix.GaussianElimination method. The linear equation is created by the condition of the C2 class continuity of the spline at each segment junction point.
The tangent vectors at the start node and the end node are calculated by the the Curve2DUtil.createCircularArcs method .
getUnitTangentOf
ClosedCurve

(static)
public static Vector2D[] getUnitTangentOfClosedCurve(Point2D[] nodePTs)
Parameters:
nodePTs - The segment junction points of the spline.
Returns:
The unit tangent vectors at the nodePTs.
Processing:
Solves the linear equation by the Matrix.GaussianElimination method. The linear equation is created by the condition of the C2 class continuity of the spline at each segment junction point.
getOptimizedTangents
(static)
public static Vector2D[] getOptimizedTangents(Point2D P0, Point2D P1, Vector2D Tout, Vector2D Tin)
Parameters:
P0 - The first segment junction point.
P1 - The second segment junction point.
Tout - The first tangent vector.
Tin - The second tangent vector.
Returns:
The new Tout, Tin vectors.
This method changes the lengths of the Tout and Tin without changing their directions.
Processing:
The notations in the figure below are as follows.

⋅ The line of P0,Q0: The normal line of the Tout.
⋅ The line of P1,Q1: The normal line of the Tin.
⋅ P01: The middle point of P0, P1.
⋅ The line of P01, Q1: The normal line of the line of P0, P1.

The optimized vector length |Tout|, |Tin| are calculated as follows.

|Tout|=4.0*r0*(1-cos(teta0))/sin(teta0)
|Tin| =4.0*r1*(1-cos(teta1))/sin(teta1)

: If the Tout and Tin are parallel, then the lengths of Tout and Tin are the same as the line length of P0, P1.


Copyright (c) 2009-2013
All other trademarks are property of their respective owners.