21package com.jogamp.math.geom.plane;
23import java.io.PrintStream;
24import java.util.NoSuchElementException;
26import com.jogamp.math.geom.AABBox;
32 static final String invalidWindingRuleValue =
"Invalid winding rule value";
33 static final String iteratorOutOfBounds =
"Iterator out of bounds";
48 return (
byte) this.ordinal();
54 case 0:
return MOVETO;
55 case 1:
return LINETO;
56 case 2:
return QUADTO;
57 case 3:
return CUBICTO;
60 throw new IllegalArgumentException(
"Unhandled Segment Type: "+type);
67 case 0:
return MOVETO.point_count;
68 case 1:
return LINETO.point_count;
69 case 2:
return QUADTO.point_count;
70 case 3:
return CUBICTO.point_count;
71 case 4:
return CLOSE.point_count;
73 throw new IllegalArgumentException(
"Unhandled Segment Type: "+type);
85 private static final int BUFFER_SIZE = 10;
90 private static final int BUFFER_CAPACITY = 10;
95 private byte[] m_types;
100 private float[] m_points;
105 private int m_typeSize;
110 private int m_pointSize;
135 private int typeIndex;
140 private int pointIndex;
161 private void reset() {
176 return area() >= 0 ? Winding.CCW : Winding.CW ;
180 public float[]
points() {
return p.m_points; }
183 public int index() {
return pointIndex; }
200 throw new NoSuchElementException(iteratorOutOfBounds);
204 System.arraycopy(p.m_points, pointIndex, coords, 0, count*2);
206 t.
transform(coords, 0, coords, 0, count);
213 return typeIndex < p.m_typeSize;
228 private float area() {
231 final float[] pCoord =
new float[2];
233 final int idx =
index();
237 pCoord[0] =
points[idx+0];
238 pCoord[1] =
points[idx+1];
241 area += pCoord[0] *
points[idx+1] -
points[idx+0] * pCoord[1];
242 pCoord[0] =
points[idx+0];
243 pCoord[1] =
points[idx+1];
246 area += pCoord[0] *
points[idx+1] -
points[idx+0] * pCoord[1];
248 pCoord[0] =
points[idx+2];
249 pCoord[1] =
points[idx+3];
252 area += pCoord[0] *
points[idx+1] -
points[idx+0] * pCoord[1];
255 pCoord[0] =
points[idx+4];
256 pCoord[1] =
points[idx+5];
272 this(rule, BUFFER_SIZE, BUFFER_SIZE);
276 this(rule, initialCapacity, initialCapacity);
279 public Path2F(
final WindingRule rule,
final int initialTypeCapacity,
final int initialPointCapacity) {
281 m_types =
new byte[initialTypeCapacity];
282 m_points =
new float[initialPointCapacity * 2];
306 private void checkBuf(
final int pointCount,
final boolean checkMove) {
307 if (checkMove && m_typeSize == 0) {
310 if (m_typeSize == m_types.length) {
311 final byte tmp[] =
new byte[m_typeSize + BUFFER_CAPACITY];
312 System.arraycopy(m_types, 0, tmp, 0, m_typeSize);
315 if (m_pointSize + pointCount > m_points.length) {
316 final float tmp[] =
new float[m_pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
317 System.arraycopy(m_points, 0, tmp, 0, m_pointSize);
327 public void moveTo(
final float x,
final float y) {
328 if ( m_typeSize > 0 && m_types[m_typeSize - 1] ==
SegmentType.
MOVETO.integer() ) {
329 m_points[m_pointSize - 2] = x;
330 m_points[m_pointSize - 1] = y;
334 m_points[m_pointSize++] = x;
335 m_points[m_pointSize++] = y;
344 public void lineTo(
final float x,
final float y) {
347 m_points[m_pointSize++] = x;
348 m_points[m_pointSize++] = y;
358 public void quadTo(
final float x1,
final float y1,
final float x2,
final float y2) {
361 m_points[m_pointSize++] = x1;
362 m_points[m_pointSize++] = y1;
363 m_points[m_pointSize++] = x2;
364 m_points[m_pointSize++] = y2;
376 public void cubicTo(
final float x1,
final float y1,
final float x2,
final float y2,
final float x3,
final float y3) {
379 m_points[m_pointSize++] = x1;
380 m_points[m_pointSize++] = y1;
381 m_points[m_pointSize++] = x2;
382 m_points[m_pointSize++] = y2;
383 m_points[m_pointSize++] = x3;
384 m_points[m_pointSize++] = y3;
405 return m_typeSize > 0 && m_types[m_typeSize - 1] ==
SegmentType.
CLOSE.integer() ;
437 final float[] points = path.
points();
439 final int idx = path.
index();
443 if ( !connect || 0 == m_typeSize ) {
444 moveTo(points[idx+0], points[idx+1]);
448 m_points[m_pointSize - 2] == points[idx+0] &&
449 m_points[m_pointSize - 1] == points[idx+1]
456 lineTo(points[idx+0], points[idx+1]);
459 quadTo(points[idx+0], points[idx+1], points[idx+2], points[idx+3]);
462 cubicTo(points[idx+0], points[idx+1], points[idx+2], points[idx+3], points[idx+4], points[idx+5]);
474 final float[] points = path.
points();
477 final int idx = path.
index();
481 out.printf(
"%2d: moveTo(%.4f/%.4f)%n", i, points[idx+0], points[idx+1]);
484 out.printf(
"%2d: lineTo(%.4f/%.4f)%n", i, points[idx+0], points[idx+1]);
487 out.printf(
"%2d: quadTo(%.4f/%.4f, %.4f/%.4f)%n", i, points[idx+0], points[idx+1], points[idx+2], points[idx+3]);
490 out.printf(
"%2d: cubicTo(%.4f/%.4f, %.4f/%.4f, %.4f/%.4f)%n", i, points[idx+0], points[idx+1], points[idx+2], points[idx+3], points[idx+4], points[idx+5]);
493 out.printf(
"%2d: closePath()%n", i);
506 t.
transform(m_points, 0, m_points, 0, m_pointSize / 2);
518 float rx1, ry1, rx2, ry2;
519 if (m_pointSize == 0) {
520 rx1 = ry1 = rx2 = ry2 = 0.0f;
522 int i = m_pointSize - 1;
523 ry1 = ry2 = m_points[i--];
524 rx1 = rx2 = m_points[i--];
526 final float y = m_points[i--];
527 final float x = m_points[i--];
542 return new AABBox(rx1, ry1, 0f, rx2, ry2, 0f);
550 boolean isInside(
final int cross) {
552 return Crossing2F.isInsideNonZero(cross);
554 return Crossing2F.isInsideEvenOdd(cross);
557 public boolean contains(
final float px,
final float py) {
558 return isInside(Crossing2F.crossShape(
this, px, py));
561 public boolean contains(
final float rx,
final float ry,
final float rw,
final float rh) {
562 final int cross = Crossing2F.intersectShape(
this, rx, ry, rw, rh);
563 return cross != Crossing2F.CROSSING && isInside(cross);
566 public boolean intersects(
final float rx,
final float ry,
final float rw,
final float rh) {
567 final int cross = Crossing2F.intersectShape(
this, rx, ry, rw, rh);
568 return cross == Crossing2F.CROSSING || isInside(cross);
Axis Aligned Bounding Box.
int index()
Return the points() index for the current segment.
float[] points()
Returns reference of the point array covering the whole iteration of Path2D, use index() to access th...
WindingRule getWindingRule()
Return the WindingRule set.
Iterator(final Path2F path, final AffineTransform at)
Constructs a new GeneralPath.Iterator for given general path and transformation.
Winding getWinding()
Compute the general winding of the vertices.
SegmentType getType()
Return current segment type.
boolean hasNext()
Returns true if the iteration has more elements.
SegmentType next()
Returns the current segment type in the iteration, then moving to the next path segment.
SegmentType currentSegment(final float[] coords)
Return the current segment type and copies the current segment's points to given storage.
Path2F represents and provides construction method for a 2D shape using float[2] points.
void moveTo(final float x, final float y)
Start a new position for the next line segment at given point x/y (P1).
void append(final Iterator path, boolean connect)
Append the given path geometry to this instance.
WindingRule getWindingRule()
Return the WindingRule set.
Path2F(final WindingRule rule)
void quadTo(final float x1, final float y1, final float x2, final float y2)
Add a quadratic curve segment, intersecting the last point and the second given point x2/y2 (P2).
Path2F(final Path2F path)
Path2F(final WindingRule rule, final int initialTypeCapacity, final int initialPointCapacity)
Path2F createTransformedShape(final AffineTransform t)
Path2F(final WindingRule rule, final int initialCapacity)
void printSegments(final PrintStream out)
boolean contains(final float px, final float py)
void closePath()
Closes the current sub-path segment by drawing a straight line back to the coordinates of the last mo...
final synchronized AABBox getBounds2D()
boolean intersects(final float rx, final float ry, final float rw, final float rh)
Winding getWinding()
Compute the general winding of the vertices.
void transform(final AffineTransform t)
void append(final Path2F path, final boolean connect)
Append the given path geometry to this instance.
void cubicTo(final float x1, final float y1, final float x2, final float y2, final float x3, final float y3)
Add a cubic Bézier curve segment, intersecting the last point and the second given point x3/y3 (P3).
void lineTo(final float x, final float y)
Add a line segment, intersecting the last point and the given point x/y (P1).
void setWindingRule(final WindingRule rule)
Set the WindingRule set.
Iterator iterator(final AffineTransform t)
boolean contains(final float rx, final float ry, final float rw, final float rh)
final boolean isClosed()
Returns true if the last sub-path is closed, otherwise false.
boolean intersects(final AABBox r)
boolean contains(final AABBox r)
static int getPointCount(final int type)
Return the number of points associated with the integer segment type.
final int point_count
Number of points associated with this segment type.
static SegmentType valueOf(final int type)
Return the SegmentType associated with the integer segment type.
byte integer()
Return the integer segment type value as a byte.
Winding rule, either EVEN_ODD or NON_ZERO (like for TrueType fonts).
NON_ZERO
The non-zero rule specifies that a point lies inside the path if a ray drawn in any direction from th...
Winding direction, either clockwise (CW) or counter-clockwise (CCW).