Java Geometry Algorithm generateSpline(final Point[] controls)

Here you can find the source of generateSpline(final Point[] controls)

Description

Generates a spline that moves no more then one pixel at a time TIP: For most movements, this spline is not good, use applyDynamism

License

Open Source License

Parameter

Parameter Description
controls An array of control points

Return

An array of Points that represents the spline

Declaration

public static Point[] generateSpline(final Point[] controls) 

Method Source Code


//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;
    }
}

Related

  1. forceMouseMove(Point pos)
  2. generateLine(Point2D.Double point, double length, double angle)
  3. generateLookAtTag(ArrayList geoCoords, ArrayList modsAM)
  4. generatePoint(Shape region)
  5. generateRobotPositions(Point start, Point end, int stepSize)
  6. gridAlign(final Point2D point, final double gridX, final double gridY)
  7. hitsLine(final Point2D p, final Point2D fromPoint, final Point2D toPoint, final double thickness)
  8. insidePoly(Polygon pg, Point p)
  9. interceptLineAndBox(Point2D startPosition, Point2D endPosition, RectangularShape boundingBox)