lots of new methods for PShape/SVG, adding support for querying data

This commit is contained in:
benfry
2010-06-05 19:10:44 +00:00
parent 4d7942d6c2
commit 1b37c70760
2 changed files with 126 additions and 18 deletions
+101 -12
View File
@@ -85,7 +85,7 @@ public class PShape implements PConstants {
protected int family;
/** ELLIPSE, LINE, QUAD; TRIANGLE_FAN, QUAD_STRIP; etc. */
protected int kind;
protected int primitive;
protected PMatrix matrix;
@@ -140,7 +140,7 @@ public class PShape implements PConstants {
static public final int BEZIER_VERTEX = 1;
static public final int CURVE_VERTEX = 2;
static public final int BREAK = 3;
/** Array of VERTEX, BEZIER_VERTEX, and CURVE_VERTEXT calls. */
/** Array of VERTEX, BEZIER_VERTEX, and CURVE_VERTEX calls. */
protected int vertexCodeCount;
protected int[] vertexCodes;
/** True if this is a closed path. */
@@ -427,10 +427,10 @@ public class PShape implements PConstants {
protected void drawPrimitive(PGraphics g) {
if (kind == POINT) {
if (primitive == POINT) {
g.point(params[0], params[1]);
} else if (kind == LINE) {
} else if (primitive == LINE) {
if (params.length == 4) { // 2D
g.line(params[0], params[1],
params[2], params[3]);
@@ -439,18 +439,18 @@ public class PShape implements PConstants {
params[3], params[4], params[5]);
}
} else if (kind == TRIANGLE) {
} else if (primitive == TRIANGLE) {
g.triangle(params[0], params[1],
params[2], params[3],
params[4], params[5]);
} else if (kind == QUAD) {
} else if (primitive == QUAD) {
g.quad(params[0], params[1],
params[2], params[3],
params[4], params[5],
params[6], params[7]);
} else if (kind == RECT) {
} else if (primitive == RECT) {
if (image != null) {
g.imageMode(CORNER);
g.image(image, params[0], params[1], params[2], params[3]);
@@ -459,29 +459,29 @@ public class PShape implements PConstants {
g.rect(params[0], params[1], params[2], params[3]);
}
} else if (kind == ELLIPSE) {
} else if (primitive == ELLIPSE) {
g.ellipseMode(CORNER);
g.ellipse(params[0], params[1], params[2], params[3]);
} else if (kind == ARC) {
} else if (primitive == ARC) {
g.ellipseMode(CORNER);
g.arc(params[0], params[1], params[2], params[3], params[4], params[5]);
} else if (kind == BOX) {
} else if (primitive == BOX) {
if (params.length == 1) {
g.box(params[0]);
} else {
g.box(params[0], params[1], params[2]);
}
} else if (kind == SPHERE) {
} else if (primitive == SPHERE) {
g.sphere(params[0]);
}
}
protected void drawGeometry(PGraphics g) {
g.beginShape(kind);
g.beginShape(primitive);
if (style) {
for (int i = 0; i < vertexCount; i++) {
g.vertex(vertices[i]);
@@ -722,6 +722,95 @@ public class PShape implements PConstants {
// }
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/** The shape type, one of GROUP, PRIMITIVE, PATH, or GEOMETRY. */
public int getFamily() {
return family;
}
public int getPrimitive() {
return primitive;
}
public int getVertexCount() {
return vertexCount;
}
public float[] getVertex(int index) {
if (index < 0 || index >= vertexCount) {
String msg = "No vertex " + index + " for this shape, " +
"only vertices 0 through " + (vertexCount-1) + ".";
throw new IllegalArgumentException(msg);
}
return vertices[index];
}
public float getVertexX(int index) {
return vertices[index][X];
}
public float getVertexY(int index) {
return vertices[index][Y];
}
public float getVertexZ(int index) {
return vertices[index][Z];
}
public int[] getVertexCodes() {
if (vertexCodes.length != vertexCodeCount) {
vertexCodes = PApplet.subset(vertexCodes, 0, vertexCodeCount);
}
return vertexCodes;
}
public int getVertexCodeCount() {
return vertexCodeCount;
}
/**
* One of VERTEX, BEZIER_VERTEX, CURVE_VERTEX, or BREAK.
*/
public int getVertexCode(int index) {
return vertexCodes[index];
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
public boolean contains(float x, float y) {
if (family == PATH) {
boolean c = false;
for (int i = 0, j = vertexCount-1; i < vertexCount; j = i++) {
if (((vertices[i][Y] > y) != (vertices[j][Y] > y)) &&
(x <
(vertices[j][X]-vertices[i][X]) *
(y-vertices[i][Y]) /
(vertices[j][1]-vertices[i][Y]) +
vertices[i][X])) {
c = !c;
}
}
return c;
} else {
throw new IllegalArgumentException("The contains() method is only implemented for paths.");
}
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+25 -6
View File
@@ -241,6 +241,15 @@ public class PShapeSVG extends PShape {
element = properties;
name = properties.getStringAttribute("id");
// @#$(* adobe illustrator mangles names of objects when re-saving
if (name != null) {
while (true) {
String[] m = PApplet.match(name, "_x(.*)_");
if (m == null) break;
char repair = (char) PApplet.unhex(m[1]);
name = name.replace(m[0], "" + repair);
}
}
String displayStr = properties.getStringAttribute("display", "inline");
visible = !displayStr.equals("none");
@@ -329,8 +338,9 @@ public class PShapeSVG extends PShape {
} else if (name.equals("linearGradient")) {
return new LinearGradient(this, elem);
} else if (name.equals("text")) {
PGraphics.showWarning("Text in SVG files is not currently supported, " +
} else if (name.equals("text") || name.equals("font")) {
PGraphics.showWarning("Text and fonts in SVG files " +
"are not currently supported, " +
"convert text to outlines instead.");
} else if (name.equals("filter")) {
@@ -339,6 +349,15 @@ public class PShapeSVG extends PShape {
} else if (name.equals("mask")) {
PGraphics.showWarning("Masks are not supported.");
} else if (name.equals("pattern")) {
PGraphics.showWarning("Patterns are not supported.");
} else if (name.equals("stop")) {
// stop tag is handled by gradient parser, so don't warn about it
} else if (name.equals("sodipodi:namedview")) {
// these are always in Inkscape files, the warnings get tedious
} else {
PGraphics.showWarning("Ignoring <" + name + "> tag.");
}
@@ -347,7 +366,7 @@ public class PShapeSVG extends PShape {
protected void parseLine() {
kind = LINE;
primitive = LINE;
family = PRIMITIVE;
params = new float[] {
element.getFloatAttribute("x1"),
@@ -367,7 +386,7 @@ public class PShapeSVG extends PShape {
* @param circle true if this is a circle and not an ellipse
*/
protected void parseEllipse(boolean circle) {
kind = ELLIPSE;
primitive = ELLIPSE;
family = PRIMITIVE;
params = new float[4];
@@ -390,7 +409,7 @@ public class PShapeSVG extends PShape {
protected void parseRect() {
kind = RECT;
primitive = RECT;
family = PRIMITIVE;
params = new float[] {
element.getFloatAttribute("x"),
@@ -425,7 +444,7 @@ public class PShapeSVG extends PShape {
protected void parsePath() {
family = PATH;
kind = 0;
primitive = 0;
String pathData = element.getStringAttribute("d");
if (pathData == null) return;