mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 23:36:27 -04:00
added the path commands q, Q, t, T, s, S to the PolygonParser
This commit is contained in:
parent
a119caeba3
commit
c245cf9c7f
@ -76,7 +76,7 @@ public class Polygon implements Iterable<VectorInterface> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new bezier line to the polygon.
|
||||
* Adds a new cubic bezier curve to the polygon.
|
||||
*
|
||||
* @param c1 the first control point to add
|
||||
* @param c2 the second control point to add
|
||||
@ -84,6 +84,8 @@ public class Polygon implements Iterable<VectorInterface> {
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Polygon add(VectorInterface c1, VectorInterface c2, VectorInterface p) {
|
||||
if (points.size() == 0)
|
||||
throw new RuntimeException("cubic bezier curve is not allowed to be the first path element");
|
||||
isBezierStart.add(points.size());
|
||||
points.add(c1);
|
||||
points.add(c2);
|
||||
|
@ -18,6 +18,8 @@ public class PolygonParser {
|
||||
private float value;
|
||||
private float x;
|
||||
private float y;
|
||||
private VectorInterface lastQuadraticControlPoint;
|
||||
private VectorInterface lastCubicControlPoint;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@ -126,47 +128,76 @@ public class PolygonParser {
|
||||
switch (command) {
|
||||
case 'M':
|
||||
p.add(nextVector());
|
||||
clearControl();
|
||||
break;
|
||||
case 'm':
|
||||
p.add(nextVectorInc());
|
||||
clearControl();
|
||||
break;
|
||||
case 'V':
|
||||
y = nextValue();
|
||||
p.add(new VectorFloat(x, y));
|
||||
p.add(getCurrent());
|
||||
clearControl();
|
||||
break;
|
||||
case 'v':
|
||||
y += nextValue();
|
||||
p.add(new VectorFloat(x, y));
|
||||
p.add(getCurrent());
|
||||
clearControl();
|
||||
break;
|
||||
case 'H':
|
||||
x = nextValue();
|
||||
p.add(new VectorFloat(x, y));
|
||||
p.add(getCurrent());
|
||||
clearControl();
|
||||
break;
|
||||
case 'h':
|
||||
x += nextValue();
|
||||
p.add(new VectorFloat(x, y));
|
||||
p.add(getCurrent());
|
||||
clearControl();
|
||||
break;
|
||||
case 'l':
|
||||
p.add(nextVectorInc());
|
||||
clearControl();
|
||||
break;
|
||||
case 'L':
|
||||
p.add(nextVector());
|
||||
clearControl();
|
||||
break;
|
||||
case 'c':
|
||||
p.add(nextVectorRel(), nextVectorRel(), nextVectorInc());
|
||||
p.add(nextVectorRel(), setLastC3(nextVectorRel()), nextVectorInc());
|
||||
break;
|
||||
case 'C':
|
||||
p.add(nextVector(), nextVector(), nextVector());
|
||||
p.add(nextVector(), setLastC3(nextVector()), nextVector());
|
||||
break;
|
||||
case 'q':
|
||||
addQuadratic(p, getCurrent(), setLastC2(nextVectorRel()), nextVectorInc());
|
||||
break;
|
||||
case 'Q':
|
||||
addQuadratic(p, getCurrent(), setLastC2(nextVector()), nextVector());
|
||||
break;
|
||||
case 's':
|
||||
addCubicWithReflect(p, getCurrent(), setLastC3(nextVectorRel()), nextVectorInc());
|
||||
break;
|
||||
case 'S':
|
||||
addCubicWithReflect(p, getCurrent(), setLastC3(nextVector()), nextVector());
|
||||
break;
|
||||
case 't':
|
||||
addQuadraticWithReflect(p, getCurrent(), nextVectorInc());
|
||||
break;
|
||||
case 'T':
|
||||
addQuadraticWithReflect(p, getCurrent(), nextVector());
|
||||
break;
|
||||
case 'a':
|
||||
addArc(p, nextVectorInc(), nextValue(), nextValue() != 0, nextValue() != 0, nextVectorInc());
|
||||
clearControl();
|
||||
break;
|
||||
case 'A':
|
||||
addArc(p, nextVector(), nextValue(), nextValue() != 0, nextValue() != 0, nextVector());
|
||||
clearControl();
|
||||
break;
|
||||
case 'Z':
|
||||
case 'z':
|
||||
p.setClosed(true);
|
||||
clearControl();
|
||||
break;
|
||||
default:
|
||||
throw new ParserException("unsupported path command " + command);
|
||||
@ -175,10 +206,58 @@ public class PolygonParser {
|
||||
return p;
|
||||
}
|
||||
|
||||
private VectorInterface getCurrent() {
|
||||
return new VectorFloat(x, y);
|
||||
}
|
||||
|
||||
private VectorInterface setLastC2(VectorInterface p) {
|
||||
lastQuadraticControlPoint = p;
|
||||
lastCubicControlPoint = null;
|
||||
return p;
|
||||
}
|
||||
|
||||
private VectorInterface setLastC3(VectorInterface p) {
|
||||
lastCubicControlPoint = p;
|
||||
lastQuadraticControlPoint = null;
|
||||
return p;
|
||||
}
|
||||
|
||||
private void clearControl() {
|
||||
lastQuadraticControlPoint = null;
|
||||
lastCubicControlPoint = null;
|
||||
}
|
||||
|
||||
private VectorInterface getLastC2() {
|
||||
if (lastQuadraticControlPoint == null)
|
||||
return getCurrent();
|
||||
return lastQuadraticControlPoint;
|
||||
}
|
||||
|
||||
private VectorInterface getLastC3() {
|
||||
if (lastCubicControlPoint == null)
|
||||
return getCurrent();
|
||||
return lastCubicControlPoint;
|
||||
}
|
||||
|
||||
private void addArc(Polygon p, VectorFloat rad, float rot, boolean large, boolean sweep, VectorFloat pos) {
|
||||
p.add(pos);
|
||||
}
|
||||
|
||||
private void addQuadratic(Polygon poly, VectorInterface start, VectorInterface c, VectorInterface p) {
|
||||
c = c.mul(2.0f / 3);
|
||||
poly.add(start.mul(1f / 3).add(c), p.mul(1f / 3).add(c), p);
|
||||
}
|
||||
|
||||
private void addQuadraticWithReflect(Polygon poly, VectorInterface start, VectorInterface p) {
|
||||
VectorInterface c = start.add(start.sub(getLastC2()));
|
||||
addQuadratic(poly, start, setLastC2(c), p);
|
||||
}
|
||||
|
||||
private void addCubicWithReflect(Polygon poly, VectorInterface start, VectorInterface c2, VectorInterface p) {
|
||||
VectorInterface c1 = start.add(start.sub(getLastC3()));
|
||||
poly.add(c1, c2, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* The parser exception
|
||||
*/
|
||||
|
@ -54,6 +54,14 @@ public interface VectorInterface {
|
||||
*/
|
||||
VectorInterface div(int d);
|
||||
|
||||
/**
|
||||
* Creates a new vector which has the value this*m
|
||||
*
|
||||
* @param m m
|
||||
* @return this*m
|
||||
*/
|
||||
VectorFloat mul(float m);
|
||||
|
||||
/**
|
||||
* Creates a new vector which has the value this-a
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user