CS101 Package Problem Set Javadocs

cs101.awt.geom
Class ShapeUtils

java.lang.Object
  extended bycs101.awt.geom.ShapeUtils

public final class ShapeUtils
extends java.lang.Object

This utility class holds routines for doing conversions on classes that implement the Shape interface. Generally the first step is in each routine is to convert the shape to a GeneralPath, and return values of type Shape will in fact be instances of the GeneralPath class unless specified otherwise.

Java's GeneralPath class is a series of concatenated line segments, second order (quadratic) Bezier curves and third order (cubic) Bezier curves. Bezier Curves consist of two types of points: knot points which are points that lie on the curve, and control points which do not lie on the curve but denote vectors that influence the shape of the curve between knot points.

None of the routines in this class attempt to convert between lines, quadratics, and cubics. A shape consisting entirely of lines, will remain entirely line based, and a purely cubic shape will also remain cubic. Mixed shapes will remain mixed, but the ratios of the number of segements of any two types is almost certain to change.

Version:
$Id: ShapeUtils.java,v 1.18 2003/09/23 15:23:40 gus Exp $
Author:
Patrick G. Heck, Gus.heck@olin.edu

Method Summary
static double angleToVert(java.awt.geom.Line2D.Float aLine)
          Find the angle between a given line segment and the vertical axis in direction that roataes the positive x axis towards positive y axis
static java.awt.geom.Line2D.Float bounce(java.awt.geom.Line2D.Float surface, java.awt.geom.Line2D.Float velVect)
          Compute a velocity vector after a bounce off a given surface.
static void createIntermediateCurve(java.awt.geom.Point2D.Float start, float[] pts)
          Mutate the supplied array of float to contain an additional knot and modify the associated control points.
static void createIntermediateLine(java.awt.geom.Point2D.Float start, float[] pts)
          Mutate the suppled array of float to contain an additional knot.
static void createIntermediateQuad(java.awt.geom.Point2D.Float start, float[] pts)
          Mutate the suppled array of float to contain an additional knot and modify the associated control points.
static java.awt.geom.Line2D.Float doReflect(java.awt.Shape s1, java.awt.Shape s2, double v1X, double v1Y)
          Find the resultant velocity from the collision of a mobile and imobile shape.
static java.awt.geom.Line2D.Float doReflect(java.awt.Shape s1, java.awt.Shape s2, java.awt.geom.Line2D.Float velVect1)
          Find the resultant velocity from the collision of a mobile and imobile shape.
static double doXReflect(java.awt.Shape s1, java.awt.Shape s2, double v1X, double v1Y)
          Find the new x velocity after reflecting a moving shape from a imobile shape.
static double doYReflect(java.awt.Shape s1, java.awt.Shape s2, double v1X, double v1Y)
          Find the new x velocity after reflecting a moving shape from a imobile shape.
static java.util.ArrayList getContainedPoints(java.awt.Shape container, java.awt.Shape containee)
          Get a list of the points belonging to one shape and contained within another.
static java.awt.geom.GeneralPath getImprovedPath(java.awt.geom.GeneralPath aPath, float precision)
          Used iteratively by getPrecisePath to acheive as specified precision.
static java.awt.geom.Line2D.Float getLineFromNeighbors(java.awt.Shape s, java.awt.geom.Point2D.Float pt)
          Find the line between points on either side of a knot point on a given shape.
static java.awt.geom.Point2D.Float getNearestPoint(java.awt.Shape s, java.awt.geom.Point2D.Float pt)
          Find the knot point in the given shape that is closest to the specified point.
static java.awt.geom.GeneralPath getPrecisePath(java.awt.geom.GeneralPath aPath, float precision)
          Increase the precision of a given GeneralPath object.
static java.awt.Shape getPreciseShape(java.awt.Shape aShape, float precision)
          Convert any AWT shape into a shape with a specified precision.
static boolean isOverlapping(java.awt.Shape shapeA, java.awt.Shape shapeB)
          Test to see if two Shape objects overlap.
static java.awt.geom.Point2D.Float meanContainedPoint(java.awt.Shape container, java.awt.Shape containee)
          Calcualte the average of all points contained within one shape and belonging to another.
static java.awt.geom.Point2D.Float meanPoint(java.util.List pointList)
          Find the mean location of a list of Point2D.Float.
static java.awt.geom.Point2D.Float midPoint(float x1, float y1, float x2, float y2)
          Find the midpoint of a specifed line segment.
static java.awt.geom.Line2D.Float nearestSegment(java.awt.Shape aShape, java.awt.geom.Point2D.Float aPoint)
          Find the line segment between two consecutive knot points of the given Shape that is closest to a specified point.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

bounce

public static java.awt.geom.Line2D.Float bounce(java.awt.geom.Line2D.Float surface,
                                                java.awt.geom.Line2D.Float velVect)
Compute a velocity vector after a bounce off a given surface. The bounce is computed by rotating the system until the line is vertical, inverting the x component to calculate the bounce, and then performing the inverse transform to get the desired.

Parameters:
surface - The line representing the angle of the surface to bounce off of.
velVect - A line with starting point 0,0 representing the velocity vector to be bounced.
Returns:
A line starting at 0,0 representing the new velocity vector.

doReflect

public static java.awt.geom.Line2D.Float doReflect(java.awt.Shape s1,
                                                   java.awt.Shape s2,
                                                   double v1X,
                                                   double v1Y)
Find the resultant velocity from the collision of a mobile and imobile shape. The two shapes must have already collided and be in a state of overlap, and must be shapes consisting of more than one point.

Parameters:
s1 - The moving shape (tiny mass)
s2 - The imobile shape (infinite mass)
v1X - The x component of the velocity of s1
v1Y - The y component of the velocity of s1
Returns:
a line starting at the origin and representing the new velocity vector

doReflect

public static java.awt.geom.Line2D.Float doReflect(java.awt.Shape s1,
                                                   java.awt.Shape s2,
                                                   java.awt.geom.Line2D.Float velVect1)
Find the resultant velocity from the collision of a mobile and imobile shape. The two shapes must have already collided and be in a state of overlap, and must be shapes consisting of more than one point.

Parameters:
s1 - The moving shape (tiny mass)
s2 - The imobile shape (infinite mass)
velVect1 - The velocity vector of s1, (x1,y1 point at 0.0 x2,y2 representing the x and y components of the velocity)
Returns:
a line starting at the origin and representing the new velocity vector

doXReflect

public static double doXReflect(java.awt.Shape s1,
                                java.awt.Shape s2,
                                double v1X,
                                double v1Y)
Find the new x velocity after reflecting a moving shape from a imobile shape.

Parameters:
s1 - The moving shape (tiny mass)
s2 - The imobile shape (infinite mass)
v1X - The x component of the velocity of s1
v1Y - The y component of the velocity of s1

doYReflect

public static double doYReflect(java.awt.Shape s1,
                                java.awt.Shape s2,
                                double v1X,
                                double v1Y)
Find the new x velocity after reflecting a moving shape from a imobile shape.

Parameters:
s1 - The moving shape (tiny mass)
s2 - The imobile shape (infinite mass)
v1X - The x component of the velocity of s1
v1Y - The y component of the velocity of s1

angleToVert

public static double angleToVert(java.awt.geom.Line2D.Float aLine)
Find the angle between a given line segment and the vertical axis in direction that roataes the positive x axis towards positive y axis

Parameters:
aLine - A line to find the angle of
Returns:
The angle in radians.

getLineFromNeighbors

public static java.awt.geom.Line2D.Float getLineFromNeighbors(java.awt.Shape s,
                                                              java.awt.geom.Point2D.Float pt)
Find the line between points on either side of a knot point on a given shape. If the shape is unclosed, and the point queried is the start or end of the shape then the line between the querried point and the nearest point will be returned. The shape must have more than one point.

Parameters:
s - The shape to find points from, comprised of than one point.
pt - The point that is a knot of s for which we want a neighbors line.

getNearestPoint

public static java.awt.geom.Point2D.Float getNearestPoint(java.awt.Shape s,
                                                          java.awt.geom.Point2D.Float pt)
Find the knot point in the given shape that is closest to the specified point. In the case of equidistant points, the qualifying point closest to the start of the shape will be returned. The shape passed to this method must have at least one point.

Parameters:
s - The shape to find a point from
pt - The point to which the points of the shape are compared.
Returns:
A point on the shape that is as close or closer than any other point on the shape to pt

nearestSegment

public static java.awt.geom.Line2D.Float nearestSegment(java.awt.Shape aShape,
                                                        java.awt.geom.Point2D.Float aPoint)
                                                 throws NoUniqueLineException,
                                                        NotEnoughPointsException
Find the line segment between two consecutive knot points of the given Shape that is closest to a specified point. Note that this method will return a line even if the segment it represents in the shape is a cubic or quadratic bezier curve.

Parameters:
aShape - The shape from which to find the line segment
aPoint - The point to which the distance is compared.
Returns:
A unique line segment that is closer to the point than any other.
Throws:
NoUniqueLineException - If there are two or more lines equidistant from the point.
NotEnoughPointsException - If the aShape contains less than 2 points

meanPoint

public static java.awt.geom.Point2D.Float meanPoint(java.util.List pointList)
Find the mean location of a list of Point2D.Float.

Parameters:
pointList - A list containing only Point2D.Float
Returns:
The average point.
Throws:
java.lang.ClassCastException - If the objects in the supplied list are not of type Point2D.Float

meanContainedPoint

public static java.awt.geom.Point2D.Float meanContainedPoint(java.awt.Shape container,
                                                             java.awt.Shape containee)
                                                      throws NotEnoughPointsException
Calcualte the average of all points contained within one shape and belonging to another.

Parameters:
container - The shape which may contain points
containee - The shape whose points may be contained
Returns:
The average of the points contained.
Throws:
NotEnoughPointsException

getContainedPoints

public static java.util.ArrayList getContainedPoints(java.awt.Shape container,
                                                     java.awt.Shape containee)
Get a list of the points belonging to one shape and contained within another.

Parameters:
container - The shape which may contain points
containee - The shape whose points may be contained
Returns:
The points belonging to containee and within conainer

isOverlapping

public static boolean isOverlapping(java.awt.Shape shapeA,
                                    java.awt.Shape shapeB)
Test to see if two Shape objects overlap. The algorithim in this test will only detect the type of overlap where a knot point from one shape is contained by the other shape (as determined by each shape's implementation of the contains(double, double) method.

Parameters:
shapeA - the first shape
shapeB - the second shape
Returns:
true if the shapes overlap false otherwise

getPreciseShape

public static java.awt.Shape getPreciseShape(java.awt.Shape aShape,
                                             float precision)
Convert any AWT shape into a shape with a specified precision. The specified precision indicates the maximum tolerable distance between knot points. If the shape is already precise enough then it is returned unmodified.

Parameters:
aShape - the shape to be converted if necessary.
precision - the maximum tolerable distance between knot points.
Returns:
A more precise version of the shape, or the same shape if the precision is already satisfied.

getPrecisePath

public static java.awt.geom.GeneralPath getPrecisePath(java.awt.geom.GeneralPath aPath,
                                                       float precision)
Increase the precision of a given GeneralPath object. The specified precision indicates the maximum tolerable distance between knot points. If the path is already precise enough then it is returned unmodified.

Parameters:
aPath - The path to convert if necessary.
precision - the maximum tolerable distance between knot points.
Returns:
A more precise version of the path or the same path if the precision was alredy satisfied.

getImprovedPath

public static java.awt.geom.GeneralPath getImprovedPath(java.awt.geom.GeneralPath aPath,
                                                        float precision)
Used iteratively by getPrecisePath to acheive as specified precision. The path is traversed and for every case in which the distance between consecutive knot points is greater than the precision value, a new knot point and associated control points are inserted. The surroundng knot points have their control points modified appropriately to maintain an Identical curve. The new knot point is only guaranteed to lie on the curve and in extreme cases may even be further from either of the orriginal knot points than the distance between the original knot points, but this indicates a situation in which a radical curve has been drawn and further itterations will eventually reduce the distance.

Note that because GeneralPath does not overide equals we return a reference to the SAME object passed in if there are no improvements to be made. aPath.equals(newPath) is equivalent to aPath == newPath.

Parameters:
aPath - The path that may need to be improved.
precision - The minimum acceptable distance between knot points.

createIntermediateLine

public static void createIntermediateLine(java.awt.geom.Point2D.Float start,
                                          float[] pts)
Mutate the suppled array of float to contain an additional knot.

Parameters:
start - the start point of the Line.
pts - An array of at least size 4 containing the end point x,y coordinates at position 0 and 1 respectively. This array format matches that returned by PathIterator

createIntermediateQuad

public static void createIntermediateQuad(java.awt.geom.Point2D.Float start,
                                          float[] pts)
Mutate the suppled array of float to contain an additional knot and modify the associated control points.

Parameters:
start - the start point of the quadratic Bezier spline.
pts - An array of at least size 8 containing the end point x,y coordinates at position 2 and 3 respectively. The control point should be specified at positions 0 and 1. This array format matches the format returned by PathIterator.

createIntermediateCurve

public static void createIntermediateCurve(java.awt.geom.Point2D.Float start,
                                           float[] pts)
Mutate the supplied array of float to contain an additional knot and modify the associated control points.

Parameters:
start - the start point of the quadratic Bezier spline.
pts - An array of at least size 8 containing the end point x,y coordinates at position 4 and 5 respectively. The control point for the start point should be specified at positions 0 and 1; The control point for the end point should be specified at positions 2 and 3 This array format matches the format returned by PathIterator.

midPoint

public static java.awt.geom.Point2D.Float midPoint(float x1,
                                                   float y1,
                                                   float x2,
                                                   float y2)
Find the midpoint of a specifed line segment.

Parameters:
x1 - start x coordinate
y1 - start y coordinate
x2 - end x coordinate
y2 - end y coordinate
Returns:
The calculated midpoint

CS101 Package Problem Set Javadocs