Specify whether Curve uses scaled or unscaled coordinates.

Unscaled coordinates will be used in a future commit (hopefully).

Added a normalize() method to Vec2f.

Throw RuntimeExceptions for any Curve initialization errors; the game would crash anyway, and this way the objects can be substituted for DummyObjects for a graceful failure.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-09-02 01:47:15 -05:00
parent 6c956e927f
commit d360b73bf5
7 changed files with 74 additions and 43 deletions

View File

@ -18,13 +18,10 @@
package itdelatrisu.opsu.objects.curves;
import itdelatrisu.opsu.ErrorHandler;
import itdelatrisu.opsu.beatmap.HitObject;
import java.util.LinkedList;
import org.newdawn.slick.SlickException;
/**
* Representation of Catmull Curve with equidistant points.
*
@ -36,7 +33,16 @@ public class CatmullCurve extends EqualDistanceMultiCurve {
* @param hitObject the associated HitObject
*/
public CatmullCurve(HitObject hitObject) {
super(hitObject);
this(hitObject, true);
}
/**
* Constructor.
* @param hitObject the associated HitObject
* @param scaled whether to use scaled coordinates
*/
public CatmullCurve(HitObject hitObject, boolean scaled) {
super(hitObject, scaled);
LinkedList<CurveType> catmulls = new LinkedList<CurveType>();
int ncontrolPoints = hitObject.getSliderX().length + 1;
LinkedList<Vec2f> points = new LinkedList<Vec2f>(); // temporary list of points to separate different curves
@ -51,24 +57,15 @@ public class CatmullCurve extends EqualDistanceMultiCurve {
for (int i = 0; i < ncontrolPoints; i++) {
points.addLast(new Vec2f(getX(i), getY(i)));
if (points.size() >= 4) {
try {
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
} catch (SlickException e) {
ErrorHandler.error(null, e, true);
}
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
points.removeFirst();
}
}
if (getX(ncontrolPoints - 1) != getX(ncontrolPoints - 2) ||
getY(ncontrolPoints - 1) != getY(ncontrolPoints - 2))
points.addLast(new Vec2f(getX(ncontrolPoints - 1), getY(ncontrolPoints - 1)));
if (points.size() >= 4) {
try {
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
} catch (SlickException e) {
ErrorHandler.error(null, e, true);
}
}
if (points.size() >= 4)
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
init(catmulls);
}

View File

@ -18,8 +18,6 @@
package itdelatrisu.opsu.objects.curves;
import org.newdawn.slick.SlickException;
/**
* Representation of a Centripetal CatmullRom spline.
* (Currently not technically Centripetal CatmullRom.)
@ -37,11 +35,10 @@ public class CentripetalCatmullRom extends CurveType {
/**
* Constructor.
* @param points the control points of the curve
* @throws SlickException
*/
protected CentripetalCatmullRom(Vec2f[] points) throws SlickException {
protected CentripetalCatmullRom(Vec2f[] points) {
if (points.length != 4)
throw new SlickException(String.format("Need exactly 4 points to initialize CentripetalCatmullRom, %d provided.", points.length));
throw new RuntimeException(String.format("Need exactly 4 points to initialize CentripetalCatmullRom, %d provided.", points.length));
this.points = points;
time = new float[4];

View File

@ -18,7 +18,6 @@
package itdelatrisu.opsu.objects.curves;
import itdelatrisu.opsu.ErrorHandler;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.beatmap.HitObject;
@ -54,7 +53,16 @@ public class CircumscribedCircle extends Curve {
* @param hitObject the associated HitObject
*/
public CircumscribedCircle(HitObject hitObject) {
super(hitObject);
this(hitObject, true);
}
/**
* Constructor.
* @param hitObject the associated HitObject
* @param scaled whether to use scaled coordinates
*/
public CircumscribedCircle(HitObject hitObject, boolean scaled) {
super(hitObject, scaled);
// construct the three points
this.start = new Vec2f(getX(0), getY(0));
@ -68,8 +76,6 @@ public class CircumscribedCircle extends Curve {
Vec2f norb = mid.cpy().sub(end).nor();
this.circleCenter = intersect(mida, nora, midb, norb);
if (circleCenter == null)
return;
// find the angles relative to the circle center
Vec2f startAngPoint = start.cpy().sub(circleCenter);
@ -90,13 +96,8 @@ public class CircumscribedCircle extends Curve {
startAng -= TWO_PI;
else if (Math.abs(startAng - (endAng - TWO_PI)) < TWO_PI && isIn(startAng, midAng, endAng - (TWO_PI)))
endAng -= TWO_PI;
else {
ErrorHandler.error(
String.format("Cannot find angles between midAng (%.3f %.3f %.3f).",
startAng, midAng, endAng), null, true
);
return;
}
else
throw new RuntimeException(String.format("Cannot find angles between midAng (%.3f %.3f %.3f).", startAng, midAng, endAng));
}
// find an angle with an arc length of pixelLength along this circle
@ -149,10 +150,8 @@ public class CircumscribedCircle extends Curve {
//u = ((b.y-a.y)ta.x +(a.x-b.x)ta.y) / (tb.x*ta.y - tb.y*ta.x);
float des = tb.x * ta.y - tb.y * ta.x;
if (Math.abs(des) < 0.00001f) {
ErrorHandler.error("Vectors are parallel.", null, true);
return null;
}
if (Math.abs(des) < 0.00001f)
throw new RuntimeException("Vectors are parallel.");
float u = ((b.y - a.y) * ta.x + (a.x - b.x) * ta.y) / des;
return b.cpy().add(tb.x * u, tb.y * u);
}

View File

@ -64,13 +64,21 @@ public abstract class Curve {
/**
* Constructor.
* @param hitObject the associated HitObject
* @param scaled whether to use scaled coordinates
*/
protected Curve(HitObject hitObject) {
protected Curve(HitObject hitObject, boolean scaled) {
this.hitObject = hitObject;
this.x = hitObject.getScaledX();
this.y = hitObject.getScaledY();
this.sliderX = hitObject.getScaledSliderX();
this.sliderY = hitObject.getScaledSliderY();
if (scaled) {
this.x = hitObject.getScaledX();
this.y = hitObject.getScaledY();
this.sliderX = hitObject.getScaledSliderX();
this.sliderY = hitObject.getScaledSliderY();
} else {
this.x = hitObject.getX();
this.y = hitObject.getY();
this.sliderX = hitObject.getSliderX();
this.sliderY = hitObject.getSliderY();
}
this.renderState = null;
}

View File

@ -42,7 +42,16 @@ public abstract class EqualDistanceMultiCurve extends Curve {
* @param hitObject the associated HitObject
*/
public EqualDistanceMultiCurve(HitObject hitObject) {
super(hitObject);
this(hitObject, true);
}
/**
* Constructor.
* @param hitObject the associated HitObject
* @param scaled whether to use scaled coordinates
*/
public EqualDistanceMultiCurve(HitObject hitObject, boolean scaled) {
super(hitObject, scaled);
}
/**

View File

@ -35,7 +35,17 @@ public class LinearBezier extends EqualDistanceMultiCurve {
* @param line whether a new curve should be generated for each sequential pair
*/
public LinearBezier(HitObject hitObject, boolean line) {
super(hitObject);
this(hitObject, line, true);
}
/**
* Constructor.
* @param hitObject the associated HitObject
* @param line whether a new curve should be generated for each sequential pair
* @param scaled whether to use scaled coordinates
*/
public LinearBezier(HitObject hitObject, boolean line, boolean scaled) {
super(hitObject, scaled);
LinkedList<CurveType> beziers = new LinkedList<CurveType>();

View File

@ -93,6 +93,17 @@ public class Vec2f {
return this;
}
/**
* Turns this vector into a unit vector.
* @return itself (for chaining)
*/
public Vec2f normalize() {
float len = len();
x /= len;
y /= len;
return this;
}
/**
* Returns a copy of this vector.
*/