org.oscim.utils.geom.BezierPath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vtm Show documentation
Show all versions of vtm Show documentation
OpenGL vector map library written in Java - running on Android, iOS, Desktop and within the browser.
package org.oscim.utils.geom;
import org.oscim.core.Point;
import java.util.ArrayList;
import java.util.List;
public class BezierPath {
/**
* from http://paulbourke.net/geometry/bezier/index.html
* Three control point Bezier interpolation
* mu ranges from 0 to 1, start to end of the curve
*/
public static Point bezier3(Point p1, Point p2, Point p3, double mu) {
double mum1, mum12, mu2;
Point p = new Point();
mu2 = mu * mu;
mum1 = 1 - mu;
mum12 = mum1 * mum1;
p.x = p1.x * mum12 + 2 * p2.x * mum1 * mu + p3.x * mu2;
p.y = p1.y * mum12 + 2 * p2.y * mum1 * mu + p3.y * mu2;
//p.z = p1.z * mum12 + 2 * p2.z * mum1 * mu + p3.z * mu2;
return (p);
}
/**
* from http://paulbourke.net/geometry/bezier/index.html
* Four control point Bezier interpolation
* mu ranges from 0 to 1, start to end of curve
*/
public static Point cubicBezier(Point p1, Point p2, Point p3, Point p4, double mu) {
double mum1, mum13, mu3;
Point p = new Point();
mum1 = 1 - mu;
mum13 = mum1 * mum1 * mum1;
mu3 = mu * mu * mu;
p.x = mum13 * p1.x + 3 * mu * mum1 * mum1 * p2.x + 3 * mu * mu * mum1 * p3.x + mu3 * p4.x;
p.y = mum13 * p1.y + 3 * mu * mum1 * mum1 * p2.y + 3 * mu * mu * mum1 * p3.y + mu3 * p4.y;
//p.z = mum13*p1.z + 3*mu*mum1*mum1*p2.z + 3*mu*mu*mum1*p3.z + mu3*p4.z;
return (p);
}
/**
* from geodroid
* FIXME
*/
public static List cubicSplineControlPoints(Point[] coords, float alpha) {
if (alpha < 0.0 || alpha > 1.0) {
throw new IllegalArgumentException("alpha must be between 0 and 1 inclusive");
}
if (coords.length < 2) {
throw new IllegalArgumentException("number of Points must be >= 2");
}
int n = coords.length;
List ctrl = new ArrayList();
Point curr = new Point(2 * coords[0].x - coords[1].x, 2 * coords[0].y - coords[1].y);
Point next = coords[0];
Point mid = new Point();
mid.x = (curr.x + next.x) / 2.0;
mid.y = (curr.y + next.y) / 2.0;
Point midPrev = new Point();
Point last = new Point(2 * coords[n - 1].x - coords[n - 2].x,
2 * coords[n - 1].y - coords[n - 2].y);
Point anchor = new Point();
double dv = curr.distance(next);
for (int i = 0; i < n; i++) {
curr = next;
next = i < n - 1 ? coords[i + 1] : last;
midPrev.x = mid.x;
midPrev.y = mid.y;
mid.x = (curr.x + next.x) / 2.0;
mid.y = (curr.y + next.y) / 2.0;
double dvPrev = dv;
dv = curr.distance(next);
double p = dvPrev / (dvPrev + dv);
anchor.x = midPrev.x + p * (mid.x - midPrev.x);
anchor.y = midPrev.y + p * (mid.y - midPrev.y);
double dx = anchor.x - curr.x;
double dy = anchor.y - curr.y;
if (i > 0) {
ctrl.add(new Point(alpha * (curr.x - midPrev.x + dx) + midPrev.x - dx,
alpha * (curr.y - midPrev.y + dy) + midPrev.y - dy));
}
if (i < n - 1) {
ctrl.add(new Point(alpha * (curr.x - mid.x + dx) + mid.x - dx,
alpha * (curr.y - mid.y + dy) + mid.y - dy));
}
}
return ctrl;
}
}