mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
Former-commit-id: 1647fa32ef6894bd7db44f741f07c2f4dcdf9054 Former-commit-id: 0e5810dcfbe1fd59b13e7cabe9f1e93c5542da2d
242 lines
6.2 KiB
Java
242 lines
6.2 KiB
Java
package org.newdawn.slick.geom;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* A shape built from lines and curves. Hole support is present but
|
|
* restricted.
|
|
*
|
|
* @author kevin
|
|
*/
|
|
public class Path extends Shape {
|
|
/** The local list of points */
|
|
private ArrayList localPoints = new ArrayList();
|
|
/** The current x coordinate */
|
|
private float cx;
|
|
/** The current y coordiante */
|
|
private float cy;
|
|
/** True if the path has been closed */
|
|
private boolean closed;
|
|
/** The list of holes placed */
|
|
private ArrayList holes = new ArrayList();
|
|
/** The current hole being built */
|
|
private ArrayList hole;
|
|
|
|
/**
|
|
* Create a new path
|
|
*
|
|
* @param sx The start x coordinate of the path
|
|
* @param sy The start y coordiante of the path
|
|
*/
|
|
public Path(float sx, float sy) {
|
|
localPoints.add(new float[] {sx,sy});
|
|
cx = sx;
|
|
cy = sy;
|
|
pointsDirty = true;
|
|
}
|
|
|
|
/**
|
|
* Start building a hole in the previously defined contour
|
|
*
|
|
* @param sx The start point of the hole
|
|
* @param sy The start point of the hole
|
|
*/
|
|
public void startHole(float sx, float sy) {
|
|
hole = new ArrayList();
|
|
holes.add(hole);
|
|
}
|
|
|
|
/**
|
|
* Add a line to the contour or hole which ends at the specified
|
|
* location.
|
|
*
|
|
* @param x The x coordinate to draw the line to
|
|
* @param y The y coordiante to draw the line to
|
|
*/
|
|
public void lineTo(float x, float y) {
|
|
if (hole != null) {
|
|
hole.add(new float[] {x,y});
|
|
} else {
|
|
localPoints.add(new float[] {x,y});
|
|
}
|
|
cx = x;
|
|
cy = y;
|
|
pointsDirty = true;
|
|
}
|
|
|
|
/**
|
|
* Close the path to form a polygon
|
|
*/
|
|
public void close() {
|
|
closed = true;
|
|
}
|
|
|
|
/**
|
|
* Add a curve to the specified location (using the default segments 10)
|
|
*
|
|
* @param x The destination x coordinate
|
|
* @param y The destination y coordiante
|
|
* @param cx1 The x coordiante of the first control point
|
|
* @param cy1 The y coordiante of the first control point
|
|
* @param cx2 The x coordinate of the second control point
|
|
* @param cy2 The y coordinate of the second control point
|
|
*/
|
|
public void curveTo(float x, float y, float cx1, float cy1, float cx2, float cy2) {
|
|
curveTo(x,y,cx1,cy1,cx2,cy2,10);
|
|
}
|
|
|
|
/**
|
|
* Add a curve to the specified location (specifing the number of segments)
|
|
*
|
|
* @param x The destination x coordinate
|
|
* @param y The destination y coordiante
|
|
* @param cx1 The x coordiante of the first control point
|
|
* @param cy1 The y coordiante of the first control point
|
|
* @param cx2 The x coordinate of the second control point
|
|
* @param cy2 The y coordinate of the second control point
|
|
* @param segments The number of segments to use for the new curve
|
|
*/
|
|
public void curveTo(float x, float y, float cx1, float cy1, float cx2, float cy2, int segments) {
|
|
// special case for zero movement
|
|
if ((cx == x) && (cy == y)) {
|
|
return;
|
|
}
|
|
|
|
Curve curve = new Curve(new Vector2f(cx,cy),new Vector2f(cx1,cy1),new Vector2f(cx2,cy2),new Vector2f(x,y));
|
|
float step = 1.0f / segments;
|
|
|
|
for (int i=1;i<segments+1;i++) {
|
|
float t = i * step;
|
|
Vector2f p = curve.pointAt(t);
|
|
if (hole != null) {
|
|
hole.add(new float[] {p.x,p.y});
|
|
} else {
|
|
localPoints.add(new float[] {p.x,p.y});
|
|
}
|
|
cx = p.x;
|
|
cy = p.y;
|
|
}
|
|
pointsDirty = true;
|
|
}
|
|
|
|
/**
|
|
* @see org.newdawn.slick.geom.Shape#createPoints()
|
|
*/
|
|
protected void createPoints() {
|
|
points = new float[localPoints.size() * 2];
|
|
for (int i=0;i<localPoints.size();i++) {
|
|
float[] p = (float[]) localPoints.get(i);
|
|
points[(i*2)] = p[0];
|
|
points[(i*2)+1] = p[1];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.newdawn.slick.geom.Shape#transform(org.newdawn.slick.geom.Transform)
|
|
*/
|
|
public Shape transform(Transform transform) {
|
|
Path p = new Path(cx,cy);
|
|
p.localPoints = transform(localPoints, transform);
|
|
for (int i=0;i<holes.size();i++) {
|
|
p.holes.add(transform((ArrayList) holes.get(i), transform));
|
|
}
|
|
p.closed = this.closed;
|
|
|
|
return p;
|
|
}
|
|
|
|
/**
|
|
* Transform a list of points
|
|
*
|
|
* @param pts The pts to transform
|
|
* @param t The transform to apply
|
|
* @return The transformed points
|
|
*/
|
|
private ArrayList transform(ArrayList pts, Transform t) {
|
|
float[] in = new float[pts.size()*2];
|
|
float[] out = new float[pts.size()*2];
|
|
|
|
for (int i=0;i<pts.size();i++) {
|
|
in[i*2] = ((float[]) pts.get(i))[0];
|
|
in[(i*2)+1] = ((float[]) pts.get(i))[1];
|
|
}
|
|
t.transform(in, 0, out, 0, pts.size());
|
|
|
|
ArrayList outList = new ArrayList();
|
|
for (int i=0;i<pts.size();i++) {
|
|
outList.add(new float[] {out[(i*2)],out[(i*2)+1]});
|
|
}
|
|
|
|
return outList;
|
|
}
|
|
|
|
// /**
|
|
// * Calculate the triangles that can fill this shape
|
|
// */
|
|
// protected void calculateTriangles() {
|
|
// if (!trianglesDirty) {
|
|
// return;
|
|
// }
|
|
// if (points.length >= 6) {
|
|
// boolean clockwise = true;
|
|
// float area = 0;
|
|
// for (int i=0;i<(points.length/2)-1;i++) {
|
|
// float x1 = points[(i*2)];
|
|
// float y1 = points[(i*2)+1];
|
|
// float x2 = points[(i*2)+2];
|
|
// float y2 = points[(i*2)+3];
|
|
//
|
|
// area += (x1 * y2) - (y1 * x2);
|
|
// }
|
|
// area /= 2;
|
|
// clockwise = area > 0;
|
|
//
|
|
// if (clockwise) {
|
|
// tris = new MannTriangulator();
|
|
// for (int i=0;i<points.length;i+=2) {
|
|
// tris.addPolyPoint(points[i], points[i+1]);
|
|
// }
|
|
//
|
|
// for (int h=0;h<holes.size();h++) {
|
|
// ArrayList hole = (ArrayList) holes.get(h);
|
|
// tris.startHole();
|
|
// for (int i=0;i<hole.size();i++) {
|
|
// float[] pt = (float[]) hole.get(i);
|
|
// tris.addPolyPoint(pt[0],pt[1]);
|
|
// }
|
|
// }
|
|
// tris.triangulate();
|
|
// } else {
|
|
// tris = new MannTriangulator();
|
|
// for (int i=points.length-2;i>=0;i-=2) {
|
|
// tris.addPolyPoint(points[i], points[i+1]);
|
|
// }
|
|
//
|
|
// for (int h=0;h<holes.size();h++) {
|
|
// ArrayList hole = (ArrayList) holes.get(h);
|
|
// tris.startHole();
|
|
// for (int i=hole.size()-1;i>=0;i--) {
|
|
// float[] pt = (float[]) hole.get(i);
|
|
// tris.addPolyPoint(pt[0],pt[1]);
|
|
// }
|
|
// }
|
|
// tris.triangulate();
|
|
// }
|
|
//
|
|
// } else {
|
|
// tris.triangulate();
|
|
// }
|
|
//
|
|
// trianglesDirty = false;
|
|
// }
|
|
|
|
/**
|
|
* True if this is a closed shape
|
|
*
|
|
* @return True if this is a closed shape
|
|
*/
|
|
public boolean closed() {
|
|
return closed;
|
|
}
|
|
}
|