summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/graph/geom
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-05-06 14:39:17 +0200
committerSven Gothel <[email protected]>2011-05-06 14:39:17 +0200
commitd75835796900cac602f7e5789601ffba0a27efe2 (patch)
tree4331f4fa053f2f2ea02eee4c1974d7ea71689be0 /src/jogl/classes/com/jogamp/graph/geom
parent59aa8737528743b83cf56b804c9d713bc325c97c (diff)
Graph: More std. functionality (equals, clone) / Better in-place transformation (cubic -> quadratic)
Impl. more of John Pritchard <[email protected]> proposal https://github.com/syntelos/jogl/commit/05a7ec92d30e1e688b1eb7cc317cad83a0e8fd60 +++ More std. functionality (equals, deep clone) of AABBox, Vertex, Outline and OutlineShape. Simplify Vertex: - Remove 2 component constructor - Add on-curve in Vertex.Factory / Constructor - Adding equals(Object) - Remove Comparable/compareTo, since we only can make an equals statement Outline/OutlineShape: Handle dirty flag for boundary (new set/remove operation) OutlineShape: Better in-place transformation (cubic -> quadratic)
Diffstat (limited to 'src/jogl/classes/com/jogamp/graph/geom')
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/AABBox.java66
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/Outline.java189
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/Vertex.java29
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java116
4 files changed, 246 insertions, 154 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/geom/AABBox.java b/src/jogl/classes/com/jogamp/graph/geom/AABBox.java
index 7051e9110..87f084919 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/AABBox.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/AABBox.java
@@ -35,7 +35,7 @@ import com.jogamp.graph.math.VectorUtil;
* right corner of the box.
*
*/
-public class AABBox {
+public class AABBox implements Cloneable {
private float[] low = new float[3];
private float[] high = new float[3];
private float[] center = new float[3];
@@ -79,7 +79,7 @@ public class AABBox {
}
/** resets this box to the inverse low/high, allowing the next {@link #resize(float, float, float)} command to hit. */
- public void reset() {
+ public final void reset() {
setLow(Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE);
setHigh(-1*Float.MAX_VALUE,-1*Float.MAX_VALUE,-1*Float.MAX_VALUE);
center[0] = 0f;
@@ -90,11 +90,11 @@ public class AABBox {
/** Get the max xyz-coordinates
* @return a float array containing the max xyz coordinates
*/
- public float[] getHigh() {
+ public final float[] getHigh() {
return high;
}
- private void setHigh(float hx, float hy, float hz) {
+ private final void setHigh(float hx, float hy, float hz) {
this.high[0] = hx;
this.high[1] = hy;
this.high[2] = hz;
@@ -103,11 +103,11 @@ public class AABBox {
/** Get the min xyz-coordinates
* @return a float array containing the min xyz coordinates
*/
- public float[] getLow() {
+ public final float[] getLow() {
return low;
}
- private void setLow(float lx, float ly, float lz) {
+ private final void setLow(float lx, float ly, float lz) {
this.low[0] = lx;
this.low[1] = ly;
this.low[2] = lz;
@@ -116,7 +116,7 @@ public class AABBox {
/** Resize the AABBox to encapsulate another AABox
* @param newBox AABBox to be encapsulated in
*/
- public void resize(AABBox newBox) {
+ public final void resize(AABBox newBox) {
float[] newLow = newBox.getLow();
float[] newHigh = newBox.getHigh();
@@ -139,7 +139,7 @@ public class AABBox {
computeCenter();
}
- private void computeCenter() {
+ private final void computeCenter() {
center[0] = (high[0] + low[0])/2;
center[1] = (high[1] + low[1])/2;
center[2] = (high[2] + low[2])/2;
@@ -151,7 +151,7 @@ public class AABBox {
* @param y y-axis coordinate value
* @param z z-axis coordinate value
*/
- public void resize(float x, float y, float z) {
+ public final void resize(float x, float y, float z) {
/** test low */
if (x < low[0])
low[0] = x;
@@ -171,6 +171,15 @@ public class AABBox {
computeCenter();
}
+ /** Resize the AABBox to encapsulate the passed
+ * xyz-coordinates.
+ * @param xyz xyz-axis coordinate values
+ * @param offset of the array
+ */
+ public final void resize(float[] xyz, int offset) {
+ resize(xyz[0+offset], xyz[1+offset], xyz[2+offset]);
+ }
+
/** Check if the x & y coordinates are bounded/contained
* by this AABBox
* @param x x-axis coordinate value
@@ -178,7 +187,7 @@ public class AABBox {
* @return true if x belong to (low.x, high.x) and
* y belong to (low.y, high.y)
*/
- public boolean contains(float x, float y) {
+ public final boolean contains(float x, float y) {
if(x<low[0] || x>high[0]){
return false;
}
@@ -196,7 +205,7 @@ public class AABBox {
* @return true if x belong to (low.x, high.x) and
* y belong to (low.y, high.y) and z belong to (low.z, high.z)
*/
- public boolean contains(float x, float y, float z) {
+ public final boolean contains(float x, float y, float z) {
if(x<low[0] || x>high[0]){
return false;
}
@@ -217,7 +226,7 @@ public class AABBox {
* @param h hight
* @return true if this AABBox might have a common region with this 2D region
*/
- public boolean intersects(float x, float y, float w, float h) {
+ public final boolean intersects(float x, float y, float w, float h) {
if (w <= 0 || h <= 0) {
return false;
}
@@ -241,21 +250,21 @@ public class AABBox {
* length of the vector between low and high.
* @return a float representing the size of the AABBox
*/
- public float getSize() {
+ public final float getSize() {
return VectorUtil.computeLength(low, high);
}
/**Get the Center of the AABBox
* @return the xyz-coordinates of the center of the AABBox
*/
- public float[] getCenter() {
+ public final float[] getCenter() {
return center;
}
/** Scale the AABBox by a constant
* @param size a constant float value
*/
- public void scale(float size) {
+ public final void scale(float size) {
float[] diffH = new float[3];
diffH[0] = high[0] - center[0];
diffH[1] = high[1] - center[1];
@@ -274,30 +283,43 @@ public class AABBox {
low = VectorUtil.vectorAdd(center, diffL);
}
- public float getMinX() {
+ public final float getMinX() {
return low[0];
}
- public float getMinY() {
+ public final float getMinY() {
return low[1];
}
- public float getWidth(){
+ public final float getWidth(){
return high[0] - low[0];
}
- public float getHeight() {
+ public final float getHeight() {
return high[1] - low[1];
}
- public float getDepth() {
+ public final float getDepth() {
return high[2] - low[2];
}
- public AABBox clone() {
+
+ public final AABBox clone() {
return new AABBox(this.low, this.high);
}
- public String toString() {
+ public final boolean equals(Object obj) {
+ if( obj == this ) {
+ return true;
+ }
+ if( null == obj || !(obj instanceof AABBox) ) {
+ return false;
+ }
+ final AABBox other = (AABBox) obj;
+ return VectorUtil.checkEquality(low, other.low) &&
+ VectorUtil.checkEquality(high, other.high) ;
+ }
+
+ public final String toString() {
return "[ "+low[0]+"/"+low[1]+"/"+low[1]+" .. "+high[0]+"/"+high[0]+"/"+high[0]+", ctr "+
center[0]+"/"+center[1]+"/"+center[1]+" ]";
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
index 315be002f..e0c29cb84 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
@@ -43,110 +43,116 @@ import com.jogamp.graph.math.VectorUtil;
*
* @see OutlineShape, Region
*/
-public class Outline implements Comparable<Outline> {
+public class Outline implements Cloneable, Comparable<Outline> {
private ArrayList<Vertex> vertices = new ArrayList<Vertex>(3);
private boolean closed = false;
- private AABBox box = new AABBox();
+ private AABBox bbox = new AABBox();
+ private boolean dirtyBBox = false;
/**Create an outline defined by control vertices.
* An outline can contain off Curve vertices which define curved
* regions in the outline.
*/
- public Outline(){
+ public Outline() {
+ }
+ public final int getVertexNumber() {
+ return vertices.size();
}
- /** Add a vertex to the outline. The {@link Vertex} is added at the
- * end of the outline loop/strip.
+ /** Appends a vertex to the outline loop/strip.
* @param vertex Vertex to be added
+ * @throws NullPointerException if the {@link Vertex} element is null
*/
- public final void addVertex(Vertex vertex) {
- vertices.add(vertex);
- box.resize(vertex.getX(), vertex.getY(), vertex.getZ());
+ public final void addVertex(Vertex vertex) throws NullPointerException {
+ addVertex(vertices.size(), vertex);
}
- /** Add a {@link Vertex} by specifying its 2D attributes to the outline.
- * The {@link Vertex} is added at the
- * end of the outline loop/strip.
- * @param factory a {@link Factory} to get the required Vertex impl
- * @param x the x coordinate
- * @param y the y coordinate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
+ /** Insert the {@link Vertex} element at the given {@code position} to the outline loop/strip.
+ * @param position of the added Vertex
+ * @param vertex Vertex object to be added
+ * @throws NullPointerException if the {@link Vertex} element is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getVertexNumber())
*/
- public final void addVertex(Vertex.Factory<? extends Vertex> factory, float x, float y, boolean onCurve) {
- addVertex(factory, x, y, 0f, onCurve);
+ public final void addVertex(int position, Vertex vertex) throws NullPointerException, IndexOutOfBoundsException {
+ if (null == vertex) {
+ throw new NullPointerException("vertex is null");
+ }
+ vertices.add(position, vertex);
+ if(!dirtyBBox) {
+ bbox.resize(vertex.getX(), vertex.getY(), vertex.getZ());
+ }
}
-
- /** Add a {@link Vertex} by specifying its 3D attributes to the outline.
- * The {@link Vertex} is added at the
- * end of the outline loop/strip.
- * @param factory a {@link Factory} to get the required Vertex impl
- * @param x the x coordinate
- * @param y the y coordinate
- * @param z the z coordinate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
+
+ /** Replaces the {@link Vertex} element at the given {@code position}.
+ * <p>Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.</p>
+ *
+ * @param position of the replaced Vertex
+ * @param vertex replacement Vertex object
+ * @throws NullPointerException if the {@link Outline} element is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getVertexNumber())
*/
- public final void addVertex(Vertex.Factory<? extends Vertex> factory, float x, float y, float z, boolean onCurve) {
- Vertex v = factory.create(x, y, z);
- v.setOnCurve(onCurve);
- addVertex(v);
+ public final void setVertex(int position, Vertex vertex) throws NullPointerException, IndexOutOfBoundsException {
+ if (null == vertex) {
+ throw new NullPointerException("vertex is null");
+ }
+ vertices.set(position, vertex);
+ dirtyBBox = true;
}
- /** Add a vertex to the outline by passing a float array and specifying the
- * offset and length in which. The attributes of the vertex are located.
- * The attributes should be continuous (stride = 0).
- * Attributes which value are not set (when length less than 3)
- * are set implicitly to zero.
- * @param factory a {@link Factory} to get the required Vertex impl
- * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
- * @param offset the offset in the buffer to the x coordinate
- * @param length the number of attributes to pick from the buffer (maximum 3)
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(Vertex.Factory<? extends Vertex> factory, float[] coordsBuffer, int offset, int length, boolean onCurve) {
- Vertex v = factory.create(coordsBuffer, offset, length);
- v.setOnCurve(onCurve);
- addVertex(v);
+ public final Vertex getVertex(int index){
+ return vertices.get(index);
}
- public Vertex getVertex(int index){
- return vertices.get(index);
+ /** Removes the {@link Vertex} element at the given {@code position}.
+ * <p>Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.</p>
+ *
+ * @param position of the to be removed Vertex
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getVertexNumber())
+ */
+ public final Vertex removeVertex(int position) throws IndexOutOfBoundsException {
+ dirtyBBox = true;
+ return vertices.remove(position);
}
- public boolean isEmpty(){
+ public final boolean isEmpty(){
return (vertices.size() == 0);
}
- public Vertex getLastVertex(){
+
+ public final Vertex getLastVertex(){
if(isEmpty()){
return null;
}
return vertices.get(vertices.size()-1);
}
- public ArrayList<Vertex> getVertices() {
+ public final ArrayList<Vertex> getVertices() {
return vertices;
}
- public void setVertices(ArrayList<Vertex> vertices) {
+
+ /**
+ * Use the given outline loop/strip.
+ * <p>Validates the bounding box.</p>
+ *
+ * @param vertices the new outline loop/strip
+ */
+ public final void setVertices(ArrayList<Vertex> vertices) {
this.vertices = vertices;
+ validateBoundingBox();
}
- public AABBox getBox() {
- return box;
- }
- public boolean isClosed() {
+
+ public final boolean isClosed() {
return closed;
}
-
+
/** define if this outline is closed or not.
* if set to closed, checks if the last vertex is
* equal to the first vertex. If not Equal adds a
* vertex at the end to the list.
* @param closed
*/
- public void setClosed(boolean closed) {
+ public final void setClosed(boolean closed) {
this.closed = closed;
if(closed){
Vertex first = vertices.get(0);
@@ -162,9 +168,9 @@ public class Outline implements Comparable<Outline> {
* as criteria.
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
- public int compareTo(Outline outline) {
- float size = box.getSize();
- float newSize = outline.getBox().getSize();
+ public final int compareTo(Outline outline) {
+ float size = getBounds().getSize();
+ float newSize = outline.getBounds().getSize();
if(size < newSize){
return -1;
}
@@ -173,4 +179,61 @@ public class Outline implements Comparable<Outline> {
}
return 0;
}
+
+ private final void validateBoundingBox() {
+ dirtyBBox = false;
+ bbox.reset();
+ for (int i=0; i<vertices.size(); i++) {
+ bbox.resize(vertices.get(i).getCoord(), 0);
+ }
+ }
+
+ public final AABBox getBounds() {
+ if (dirtyBBox) {
+ validateBoundingBox();
+ }
+ return bbox;
+ }
+
+ /**
+ * @param obj the Object to compare this Outline with
+ * @return true if {@code obj} is an Outline, not null, equals bounds and equal vertices in the same order
+ */
+ public boolean equals(Object obj) {
+ if( obj == this) {
+ return true;
+ }
+ if( null == obj || !(obj instanceof Outline) ) {
+ return false;
+ }
+ final Outline o = (Outline) obj;
+ if(getVertexNumber() != o.getVertexNumber()) {
+ return false;
+ }
+ if( !getBounds().equals( o.getBounds() ) ) {
+ return false;
+ }
+ for (int i=getVertexNumber()-1; i>=0; i--) {
+ if( ! getVertex(i).equals( o.getVertex(i) ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return deep clone of this Outline
+ */
+ public Outline clone() {
+ Outline o;
+ try {
+ o = (Outline) super.clone();
+ } catch (CloneNotSupportedException e) { return null; /* never, ever */ }
+ o.bbox = bbox.clone();
+ o.vertices = new ArrayList<Vertex>(vertices.size());
+ for(int i=0; i<vertices.size(); i++) {
+ o.vertices.add(vertices.get(i).clone());
+ }
+ return o;
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java
index 859add943..3080f32cc 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java
@@ -30,22 +30,21 @@ package com.jogamp.graph.geom;
/**
* A Vertex with custom memory layout using custom factory.
*/
-public interface Vertex extends Comparable<Vertex>, Cloneable {
+public interface Vertex extends Cloneable {
public static interface Factory <T extends Vertex> {
T create();
- T create(float x, float y);
+ T create(float x, float y, float z, boolean onCurve);
- T create(float x, float y, float z);
-
- T create(float[] coordsBuffer, int offset, int length);
+ T create(float[] coordsBuffer, int offset, int length, boolean onCurve);
}
- void setCoord(float x, float y);
-
void setCoord(float x, float y, float z);
+ /**
+ * @see System#arraycopy(Object, int, Object, int, int) for thrown IndexOutOfBoundsException
+ */
void setCoord(float[] coordsBuffer, int offset, int length);
float[] getCoord();
@@ -70,11 +69,23 @@ public interface Vertex extends Comparable<Vertex>, Cloneable {
void setId(int id);
- int compareTo(Vertex p);
-
float[] getTexCoord();
void setTexCoord(float s, float t);
+ /**
+ * @see System#arraycopy(Object, int, Object, int, int) for thrown IndexOutOfBoundsException
+ */
+ void setTexCoord(float[] texCoordsBuffer, int offset, int length);
+
+ /**
+ * @param obj the Object to compare this Vertex with
+ * @return true if {@code obj} is a Vertex and not null, on-curve flag is equal and has same vertex- and tex-coords.
+ */
+ boolean equals(Object obj);
+
+ /**
+ * @return deep clone of this Vertex
+ */
Vertex clone();
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java b/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java
index 6241d60df..9dade17e9 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java
@@ -27,7 +27,6 @@
*/
package com.jogamp.graph.geom.opengl;
-
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.math.VectorUtil;
@@ -38,7 +37,7 @@ import com.jogamp.graph.math.VectorUtil;
public class SVertex implements Vertex {
private int id = Integer.MAX_VALUE;
protected float[] coord = new float[3];
- protected boolean onCurve = true;
+ protected boolean onCurve;
private float[] texCoord = new float[2];
static final Factory factory = new Factory();
@@ -46,133 +45,130 @@ public class SVertex implements Vertex {
public static Factory factory() { return factory; }
public static class Factory implements Vertex.Factory<SVertex> {
- @Override
public SVertex create() {
return new SVertex();
}
- @Override
- public SVertex create(float x, float y) {
- return new SVertex(x, y);
- }
-
- @Override
- public SVertex create(float x, float y, float z) {
- return new SVertex(x, y, z);
+ public SVertex create(float x, float y, float z, boolean onCurve) {
+ return new SVertex(x, y, z, onCurve);
}
- @Override
- public SVertex create(float[] coordsBuffer, int offset, int length) {
- return new SVertex(coordsBuffer, offset, length);
+ public SVertex create(float[] coordsBuffer, int offset, int length, boolean onCurve) {
+ return new SVertex(coordsBuffer, offset, length, onCurve);
}
}
public SVertex() {
}
- public SVertex(float x, float y) {
- setCoord(x, y);
- }
- public SVertex(float x, float y, float z) {
+ public SVertex(float x, float y, float z, boolean onCurve) {
setCoord(x, y, z);
- }
- public SVertex(float[] coordsBuffer, int offset, int length) {
+ setOnCurve(onCurve);
+ }
+
+ public SVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) {
setCoord(coordsBuffer, offset, length);
+ setOnCurve(onCurve);
}
- public void setCoord(float x, float y) {
- this.coord[0] = x;
- this.coord[1] = y;
- this.coord[2] = 0f;
+ public SVertex(float[] coordsBuffer, int offset, int length,
+ float[] texCoordsBuffer, int offsetTC, int lengthTC, boolean onCurve) {
+ setCoord(coordsBuffer, offset, length);
+ setTexCoord(texCoordsBuffer, offsetTC, lengthTC);
+ setOnCurve(onCurve);
}
-
- public void setCoord(float x, float y, float z) {
+
+ public final void setCoord(float x, float y, float z) {
this.coord[0] = x;
this.coord[1] = y;
this.coord[2] = z;
}
- public void setCoord(float[] coordsBuffer, int offset, int length) {
- if(length > coordsBuffer.length - offset) {
- throw new IndexOutOfBoundsException("coordsBuffer too small: "+coordsBuffer.length+" - "+offset+" < "+length);
- }
- if(length > 3) {
- throw new IndexOutOfBoundsException("length too big: "+length+" > "+3);
- }
- int i=0;
- while(i<length) {
- this.coord[i++] = coordsBuffer[offset++];
- }
+ public final void setCoord(float[] coordsBuffer, int offset, int length) {
+ System.arraycopy(coordsBuffer, offset, coord, 0, length);
}
- public float[] getCoord() {
+ public final float[] getCoord() {
return coord;
}
- public void setX(float x) {
+ public final void setX(float x) {
this.coord[0] = x;
}
- public void setY(float y) {
+ public final void setY(float y) {
this.coord[1] = y;
}
- public void setZ(float z) {
+ public final void setZ(float z) {
this.coord[2] = z;
}
- public float getX() {
+ public final float getX() {
return this.coord[0];
}
- public float getY() {
+ public final float getY() {
return this.coord[1];
}
- public float getZ() {
+ public final float getZ() {
return this.coord[2];
}
- public boolean isOnCurve() {
+ public final boolean isOnCurve() {
return onCurve;
}
- public void setOnCurve(boolean onCurve) {
+ public final void setOnCurve(boolean onCurve) {
this.onCurve = onCurve;
}
- public int getId(){
+ public final int getId(){
return id;
}
- public void setId(int id){
+ public final void setId(int id){
this.id = id;
}
- public int compareTo(Vertex p) {
- if(VectorUtil.checkEquality(coord, p.getCoord())) {
- return 0;
+ public boolean equals(Object obj) {
+ if( obj == this) {
+ return true;
+ }
+ if( null == obj || !(obj instanceof Vertex) ) {
+ return false;
}
- return -1;
+ final Vertex v = (Vertex) obj;
+ return this == v ||
+ isOnCurve() == v.isOnCurve() &&
+ VectorUtil.checkEqualityVec2(getTexCoord(), v.getTexCoord()) &&
+ VectorUtil.checkEquality(getCoord(), v.getCoord()) ;
}
- public float[] getTexCoord() {
+ public final float[] getTexCoord() {
return texCoord;
}
- public void setTexCoord(float s, float t) {
+ public final void setTexCoord(float s, float t) {
this.texCoord[0] = s;
this.texCoord[1] = t;
}
-
+
+ public final void setTexCoord(float[] texCoordsBuffer, int offset, int length) {
+ System.arraycopy(texCoordsBuffer, offset, texCoord, 0, length);
+ }
+
+ /**
+ * @return deep clone of this Vertex, but keeping the id blank
+ */
public SVertex clone(){
- SVertex v = new SVertex(this.coord, 0, 3);
- v.setOnCurve(this.onCurve);
- return v;
+ return new SVertex(this.coord, 0, 3, this.texCoord, 0, 2, this.onCurve);
}
public String toString() {
- return "[ID: " + id + " X: " + coord[0]
- + " Y: " + coord[1] + " Z: " + coord[2] + "]";
+ return "[ID: " + id + ", onCurve: " + onCurve +
+ ": p " + coord[0] + ", " + coord[1] + ", " + coord[2] +
+ ", t " + texCoord[0] + ", " + texCoord[1] + "]";
}
}