|
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectde.unihalle.informatik.Alida.operator.ALDData
de.unihalle.informatik.MiToBo.core.datatypes.MTBPolygon2D
@ALDParametrizedClass public class MTBPolygon2D
Polygon datatype with double precision.
This class re-implements the class Polygon
. The main reason
for this is the awt-polygons are based on integer points. However, in MiToBo
we require double precision in snake calculations.
Each polygon can be of complex or simple nature (i.e. does or does not intersect with itself), can be open or closed and is sorted either counter-clockwise or clockwise. Note that boundary points belongs to the polygon per definition.
The point of the polygon must have positive values for x- and y-coordinates. Negative coordinates can afford an undesirable behavior of some methods. This class uses native routines interfacing the Computational Geometry Algorithms Library (CGAL) in some sections.
Polygon
Nested Class Summary | |
---|---|
private class |
MTBPolygon2D.IntersectionPoint2D
Helper class for function simplify(). |
Field Summary | |
---|---|
protected boolean |
isClosed
Indicates if the polygon is closed or not. |
protected java.util.Vector<java.awt.geom.Point2D.Double> |
points
List of polygon points. |
private Polygon2D_Cgal |
polyHelper
Helper object interfacing CGAL by native methods. |
Constructor Summary | |
---|---|
MTBPolygon2D()
Default constructor. |
|
MTBPolygon2D(double[] xp,
double[] yp,
boolean closed)
Construct polygon from coordinate arrays. |
|
MTBPolygon2D(java.util.Vector<java.awt.geom.Point2D.Double> ps,
boolean closed)
Construct from point list. |
Method Summary | |
---|---|
void |
addPoint(double x,
double y)
Appends a new point to the end of the polygon. |
MTBPolygon2D |
clone()
|
boolean |
contains(double px,
double py,
int w,
int h)
Determines if a point lies inside a polygon or on its boundary. |
void |
drawPolygon(MTBImage img)
Draw a polygon into an image (in red color). |
void |
drawPolygon(MTBImage img,
int color)
Draw a polygon into an image. |
void |
drawPolygonPoints(MTBImage img)
Draw polygon points into an image (in red color and as crosses). |
void |
drawPolygonPoints(MTBImage img,
int color,
int mode)
Draw polygon points into an image. |
int[][] |
getBinaryMask(int w,
int h)
Generates binary mask for inside part of the polygon. |
double[] |
getBoundingBox()
Calculates the axes-parallel bounding box of the snake. |
double |
getLength()
|
int |
getPointNum()
Get the number of points from the polygon. |
java.util.Vector<java.awt.geom.Point2D.Double> |
getPoints()
Get polygon points. |
MTBPolygon2D |
getPolygon()
Get a Polygon2D copy of this object. |
double |
getSignedArea()
Calculates the signed area of simple (!) |
boolean |
isClosed()
Returns true if the polygon forms a closed polygon. |
boolean |
isSimple()
Deprecated. |
boolean |
isSortedCounterClockwise()
Deprecated. |
boolean |
jni_containsPoint(double x,
double y)
Determines if a point lies inside a polygon or on its boundary. |
boolean |
jni_isClockwiseOriented()
JNI method for checking clockwise ordering. |
boolean |
jni_isConvex()
JNI method for checking if polygon is convex. |
boolean |
jni_isCounterClockwiseOriented()
JNI method for checking counter-clockwise ordering. |
boolean |
jni_isSimple()
JNI method for checking if polygon is simple. |
void |
jni_makePolySimple()
JNI method for eliminating loops in polygons. |
int |
jni_orientation(java.awt.geom.Point2D.Double p)
JNI method for calculating orientation of point w.r.t. to polygon. |
void |
resample(double segmentLength)
Method to re-sample the line segments of the polygon in a range of a given segment length. |
void |
reversePolypoints()
Changes the ordering of the polygon points. |
void |
setClosed()
Set polygon closed. |
void |
setOpen()
Set polygon opened (not closed). |
void |
setPoints(java.util.Vector<java.awt.geom.Point2D.Double> ps)
Set all points of the polygon from the specified point vector object. |
void |
shift(double shiftValue,
int imageSizeX,
int imageSizeY)
Method to shift the whole polygon outward (positive value) ore inward (negative value) to its normal vector from every line segment. |
boolean |
simplify()
Deprecated. |
java.awt.geom.Point2D.Double |
standardization(java.awt.geom.Point2D.Double p)
|
private java.util.Vector<java.awt.geom.Point2D.Double> |
traversePolygonPointList(java.util.Vector<java.awt.geom.Point2D.Double> pointlist,
int startPointID)
Helper function for simplify(). |
Methods inherited from class de.unihalle.informatik.Alida.operator.ALDData |
---|
cloneProperties, getLocation, getProperty, getPropertyKeys, print, setLocation, setProperty |
Methods inherited from class java.lang.Object |
---|
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
@ALDClassParameter(label="Polygon is closed") protected boolean isClosed
@ALDClassParameter(label="List of points") protected java.util.Vector<java.awt.geom.Point2D.Double> points
private Polygon2D_Cgal polyHelper
Constructor Detail |
---|
public MTBPolygon2D()
public MTBPolygon2D(double[] xp, double[] yp, boolean closed)
xp
- x coordinates of points.yp
- y coordinates of points.closed
- Should be true if polygon is closed.public MTBPolygon2D(java.util.Vector<java.awt.geom.Point2D.Double> ps, boolean closed)
ps
- List with points.closed
- Should be true if polygon is closed.Method Detail |
---|
public void addPoint(double x, double y)
x
- Point x coordinate.y
- Point y coordinate.public MTBPolygon2D clone()
clone
in class java.lang.Object
public boolean contains(double px, double py, int w, int h)
Use this method only for single point testing. If a couple of points should be tested, use the getBinaryMask method to get the region inside the polygon and test the points whether they are inside (value = 1) or outside (value = 0) the polygon.
px
- x coordinate of point to checkpy
- y coordinate of point to checkw
- width of the image where the polygon is includedh
- height of the image where the polygon is included
public void drawPolygon(MTBImage img)
img
- Image where to draw the polygon into.public void drawPolygon(MTBImage img, int color)
img
- Image where to draw the polygon into.public void drawPolygonPoints(MTBImage img)
img
- Image where to draw the polygon points into.public void drawPolygonPoints(MTBImage img, int color, int mode)
img
- Image where to draw the polygon points into.color
- Color to be used.mode
- Shape to be drawn.public int[][] getBinaryMask(int w, int h)
w
- image widthh
- image height
public double[] getBoundingBox()
The function extracts the coordinates of the upper left and lower right corner of the bounding box of the snake. Note that the there is at least one point of the snake lying on each side of the bounding box, i.e. the snake not just touches the box, but lies on it.
The result array contains the corner coordinates in the following order: [xmin, ymin, xmax, ymax]
public double getLength()
public int getPointNum()
public java.util.Vector<java.awt.geom.Point2D.Double> getPoints()
public MTBPolygon2D getPolygon()
public double getSignedArea()
The area is calculated according to the formulas found at
http://www.faqs.org/faqs/graphics/algorithms-faq/,
item 2.01. If the polygon points are ordered counter-clockwise the area will be larger than zero, otherwise smaller.
Note: if the polygon is complex, the result is undetermined! TODO Replace with JNI CGAL function.
public boolean isClosed()
@Deprecated public boolean isSimple()
The algorithm works brute-force by simply checking each pair of polygon segments for intersections.
@Deprecated public boolean isSortedCounterClockwise()
Implemented according to item 2.07 at
http://www.faqs.org/faqs/graphics/algorithms-faq/.
Note that if the polygon is complex the result maybe wrong.
public boolean jni_containsPoint(double x, double y) throws MTBPolygon2DException
The method indirectly relies on CGAL functions.
Method is not very fast. The Polygon must be a simple polygon.
For fast method to check whether a couple of points lies inside or outside the polygon, use the binary mask (see getBinaryMask) an check pixel values for 0 or 1.
x
- x coordinate of point to check.y
- y coordinate of point to check.
MTBPolygon2DException
public boolean jni_isClockwiseOriented() throws MTBPolygon2DException
MTBPolygon2DException
public boolean jni_isConvex()
public boolean jni_isCounterClockwiseOriented() throws MTBPolygon2DException
MTBPolygon2DException
public boolean jni_isSimple()
public void jni_makePolySimple()
ATTENTION!!! The returned polygon is CLOCKWISE ORIENTED!!!
public int jni_orientation(java.awt.geom.Point2D.Double p)
p
- Point to calculate orientation for.
public void resample(double segmentLength)
Method to re-sample the line segments of the polygon in a range of a given segment length. The range is calculated from the given length of a segment by calculation: - minimum = segment length * 0.5 - maximum = segment length * 1.5 If a line segment (p,q) is too small, the point q is removed from the list. Then the new line segment (p,r) is observed, where r is the successor of q. If a line segment (p,q) is too large, new points will be added. The number of new points is calculated by the possible number of points (depending on the given segment length) that fit into the line segment between p and q.
public void reversePolypoints()
If the polygon points are ordered clockwise afterwards they are ordered counter-clockwise and vice versa.
public void setClosed()
public void setOpen()
public void setPoints(java.util.Vector<java.awt.geom.Point2D.Double> ps)
ps
- vector with new points of the polygonpublic void shift(double shiftValue, int imageSizeX, int imageSizeY)
ATTENTION!!! After shifting a polygon, it can happen that the polygon is not simple !!!
shiftValue
- positive ore negative value to shift the polygonimageSizeX
- width of the image to test whether the coordinates of the shifted
polygon are validimageSizeY
- height of the image to test whether the coordinates of the shifted
polygon are valid@Deprecated public boolean simplify()
Given a polygon with points sorted counter-clockwise any self-intersection
is eliminated. Basically, at first all intersections are calculated and
then inserted into the point list, which results in a new pointlist
including all polygon points and the intersections in between.
In a second step the complete pointlist is traversed counter-clockwise.
Non-intersection points are directly added to the simplified polygon. If an
intersection point is found, its second counter-part in the list is
searched. Then the neighbor of that point with lies left of the current
segment is added to the simple polygon and traversal continues in the
direction of the recently added point.
The whole procedure stops when the starting point is reached again.
Complexity of the algorithm:
Searching for all intersection points requires to check each segment
against each other, yielding a complexity of O(N*N). During pointlist
traversal each point of the list is considered maximal once, however, the
list is traversed two times in two different directions to make sure that
we run in the correct direction on the polygon. Thus, traversal needs
O(2*|pointlist|).
Altogether this results in O(N*N + N), i.e. quadratic complexity.
IMPORTANT! It is strongly required that the polygon is sorted counter-clockwise!
public java.awt.geom.Point2D.Double standardization(java.awt.geom.Point2D.Double p)
private java.util.Vector<java.awt.geom.Point2D.Double> traversePolygonPointList(java.util.Vector<java.awt.geom.Point2D.Double> pointlist, int startPointID)
This function traverses a given point list in counter-clockwise ordering and eliminates all intersection points.
pointlist
- List of points to traverse.startPointID
- ID of point where to start.
|
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |