Here you can find the source of generateSpline(final Point[] controls)
applyDynamism
Parameter | Description |
---|---|
controls | An array of control points |
public static Point[] generateSpline(final Point[] controls)
//package com.java2s; //License from project: Open Source License import java.awt.*; public class Main { /**/*from w ww .j a v a 2 s . c o m*/ * Generates a spline that moves no more then one pixel at a time TIP: For * most movements, this spline is not good, use <code>applyDynamism</code> * * @param controls An array of control points * * @return An array of Points that represents the spline */ public static Point[] generateSpline(final Point[] controls) { final double degree = controls.length - 1; final java.util.Vector<Point> spline = new java.util.Vector<Point>(); boolean lastFlag = false; for (double theta = 0; theta <= 1; theta += 0.01) { double x = 0; double y = 0; for (double index = 0; index <= degree; index++) { final double probPoly = nCk((int) degree, (int) index) * Math.pow(theta, index) * Math.pow(1D - theta, degree - index); x += probPoly * controls[(int) index].x; y += probPoly * controls[(int) index].y; } final Point temp = new Point((int) x, (int) y); try { if (!temp.equals(spline.lastElement())) { spline.add(temp); } } catch (final Exception e) { spline.add(temp); } lastFlag = theta != 1.0; } if (lastFlag) { spline.add(new Point(controls[(int) degree].x, controls[(int) degree].y)); } adaptiveMidpoints(spline); return spline.toArray(new Point[spline.size()]); } /** * Binomial Coefficient. * * @param n The superset element count. * @param k The subset size. * * @return <code>n</code> choose <code>k</code>. */ private static double nCk(final int n, final int k) { return fact(n) / (fact(k) * fact(n - k)); } /** * Applies a midpoint algorithm to the Vector of points to ensure pixel to * pixel movement * * @param points The vector of points to be manipulated */ private static void adaptiveMidpoints(final java.util.Vector<Point> points) { int i = 0; while (i < points.size() - 1) { final Point a = points.get(i++); final Point b = points.get(i); if ((Math.abs(a.x - b.x) > 1) || (Math.abs(a.y - b.y) > 1)) { if (Math.abs(a.x - b.x) != 0) { final double slope = (double) (a.y - b.y) / (double) (a.x - b.x); final double incpt = a.y - slope * a.x; for (int c = a.x < b.x ? a.x + 1 : b.x - 1; a.x < b.x ? c < b.x : c > a.x; c += a.x < b.x ? 1 : -1) { points.add(i++, new Point(c, (int) Math.round(incpt + slope * c))); } } else { for (int c = a.y < b.y ? a.y + 1 : b.y - 1; a.y < b.y ? c < b.y : c > a.y; c += a.y < b.y ? 1 : -1) { points.add(i++, new Point(a.x, c)); } } } } } /** * Factorial ("n!"). * * @param n The integer. * * @return The factorial. */ private static double fact(final int n) { double result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } }