41f62de088
In anticipation of the saying of nay, I offer this: these are value classes, and in a civilized language, I wouldn't have setters either. "foo.x = x" would call a setter method over which I had control. However, rather than throwing my hands up and saying "Gee, I have to have verbose setters, so I guess I better have verbose getters," I say, "I'll take what I can get." Methods that verb can be verbs, and we can all agree to understand that methods that are nouns are getters. foo.width() does not width my foo, it's my foo's width. foo.invert() inverts up my foo, it is not some attribute of my foo's nonsensically named invert. I don't want to add my foo's getWidth and getHeight, I want to add my foo's width and height. So why should I have to type get over and over again just because I want to protect myself from future representation change? (Or in this case, to offer immutable views of my value classes.)
102 lines
3.8 KiB
Java
102 lines
3.8 KiB
Java
//
|
|
// Pythagoras - a collection of geometry classes
|
|
// http://github.com/samskivert/pythagoras
|
|
|
|
package pythagoras.f;
|
|
|
|
/**
|
|
* Cubic curve-related utility methods.
|
|
*/
|
|
public class CubicCurves
|
|
{
|
|
public static float flatnessSq (float x1, float y1, float ctrlx1, float ctrly1,
|
|
float ctrlx2, float ctrly2, float x2, float y2) {
|
|
return Math.max(Lines.pointSegDistSq(ctrlx1, ctrly1, x1, y1, x2, y2),
|
|
Lines.pointSegDistSq(ctrlx2, ctrly2, x1, y1, x2, y2));
|
|
}
|
|
|
|
public static float flatnessSq (float[] coords, int offset) {
|
|
return flatnessSq(coords[offset + 0], coords[offset + 1], coords[offset + 2],
|
|
coords[offset + 3], coords[offset + 4], coords[offset + 5],
|
|
coords[offset + 6], coords[offset + 7]);
|
|
}
|
|
|
|
public static float flatness (float x1, float y1, float ctrlx1, float ctrly1,
|
|
float ctrlx2, float ctrly2, float x2, float y2) {
|
|
return FloatMath.sqrt(flatnessSq(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
|
|
}
|
|
|
|
public static float flatness (float[] coords, int offset) {
|
|
return flatness(coords[offset + 0], coords[offset + 1], coords[offset + 2],
|
|
coords[offset + 3], coords[offset + 4], coords[offset + 5],
|
|
coords[offset + 6], coords[offset + 7]);
|
|
}
|
|
|
|
public static void subdivide (ICubicCurve src, CubicCurve left, CubicCurve right) {
|
|
float x1 = src.x1(), y1 = src.y1();
|
|
float cx1 = src.ctrlX1(), cy1 = src.ctrlY1();
|
|
float cx2 = src.ctrlX2(), cy2 = src.ctrlY2();
|
|
float x2 = src.x2(), y2 = src.y2();
|
|
float cx = (cx1 + cx2) / 2f, cy = (cy1 + cy2) / 2f;
|
|
cx1 = (x1 + cx1) / 2f;
|
|
cy1 = (y1 + cy1) / 2f;
|
|
cx2 = (x2 + cx2) / 2f;
|
|
cy2 = (y2 + cy2) / 2f;
|
|
float ax = (cx1 + cx) / 2f, ay = (cy1 + cy) / 2f;
|
|
float bx = (cx2 + cx) / 2f, by = (cy2 + cy) / 2f;
|
|
cx = (ax + bx) / 2f;
|
|
cy = (ay + by) / 2f;
|
|
if (left != null) {
|
|
left.setCurve(x1, y1, cx1, cy1, ax, ay, cx, cy);
|
|
}
|
|
if (right != null) {
|
|
right.setCurve(cx, cy, bx, by, cx2, cy2, x2, y2);
|
|
}
|
|
}
|
|
|
|
public static void subdivide (float[] src, int srcOff, float left[], int leftOff,
|
|
float[] right, int rightOff) {
|
|
float x1 = src[srcOff + 0], y1 = src[srcOff + 1];
|
|
float cx1 = src[srcOff + 2], cy1 = src[srcOff + 3];
|
|
float cx2 = src[srcOff + 4], cy2 = src[srcOff + 5];
|
|
float x2 = src[srcOff + 6], y2 = src[srcOff + 7];
|
|
float cx = (cx1 + cx2) / 2f, cy = (cy1 + cy2) / 2f;
|
|
cx1 = (x1 + cx1) / 2f;
|
|
cy1 = (y1 + cy1) / 2f;
|
|
cx2 = (x2 + cx2) / 2f;
|
|
cy2 = (y2 + cy2) / 2f;
|
|
float ax = (cx1 + cx) / 2f, ay = (cy1 + cy) / 2f;
|
|
float bx = (cx2 + cx) / 2f, by = (cy2 + cy) / 2f;
|
|
cx = (ax + bx) / 2f;
|
|
cy = (ay + by) / 2f;
|
|
if (left != null) {
|
|
left[leftOff + 0] = x1;
|
|
left[leftOff + 1] = y1;
|
|
left[leftOff + 2] = cx1;
|
|
left[leftOff + 3] = cy1;
|
|
left[leftOff + 4] = ax;
|
|
left[leftOff + 5] = ay;
|
|
left[leftOff + 6] = cx;
|
|
left[leftOff + 7] = cy;
|
|
}
|
|
if (right != null) {
|
|
right[rightOff + 0] = cx;
|
|
right[rightOff + 1] = cy;
|
|
right[rightOff + 2] = bx;
|
|
right[rightOff + 3] = by;
|
|
right[rightOff + 4] = cx2;
|
|
right[rightOff + 5] = cy2;
|
|
right[rightOff + 6] = x2;
|
|
right[rightOff + 7] = y2;
|
|
}
|
|
}
|
|
|
|
public static int solveCubic (float[] eqn) {
|
|
return solveCubic(eqn, eqn);
|
|
}
|
|
|
|
public static int solveCubic (float[] eqn, float[] res) {
|
|
return Crossing.solveCubic(eqn, res);
|
|
}
|
|
}
|