com.kitfox.svg.animation.Bezier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of svg-salamander Show documentation
Show all versions of svg-salamander Show documentation
A tool for displaying and playing SVG content using the Java2D
The newest version!
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at [email protected]. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 14, 2005, 4:08 AM
*/
package com.kitfox.svg.animation;
import java.awt.geom.*;
/**
* http://mathworld.wolfram.com/BezierCurve.html
* @author kitfox
*/
public class Bezier
{
double length;
double[] coord;
public Bezier(double sx, double sy, double[] coords, int numCoords)
{
setCoords(sx, sy, coords, numCoords);
}
public void setCoords(double sx, double sy, double[] coords, int numCoords)
{
coord = new double[numCoords * 2 + 2];
coord[0] = sx;
coord[1] = sy;
for (int i = 0; i < numCoords; i++)
{
coord[i * 2 + 2] = coords[i * 2];
coord[i * 2 + 3] = coords[i * 2 + 1];
}
calcLength();
}
/**
* Retuns aproximation of the length of the bezier
*/
public double getLength()
{
return length;
}
private void calcLength()
{
length = 0;
for (int i = 2; i < coord.length; i += 2)
{
length += lineLength(coord[i - 2], coord[i - 1], coord[i], coord[i + 1]);
}
}
private double lineLength(double x1, double y1, double x2, double y2)
{
double dx = x2 - x1, dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
public Point2D.Double getFinalPoint(Point2D.Double point)
{
point.x = coord[coord.length - 2];
point.y = coord[coord.length - 1];
return point;
}
public Point2D.Double eval(double param, Point2D.Double point)
{
point.x = 0;
point.y = 0;
int numKnots = coord.length / 2;
for (int i = 0; i < numKnots; i++)
{
double scale = bernstein(numKnots - 1, i, param);
point.x += coord[i * 2] * scale;
point.y += coord[i * 2 + 1] * scale;
}
return point;
}
/**
* Calculates the bernstein polynomial for evaluating parametric bezier
* @param numKnots - one less than number of knots in this curve hull
* @param knotNo - knot we are evaluating Bernstein for
* @param param - Parametric value we are evaluating at
*/
private double bernstein(int numKnots, int knotNo, double param)
{
double iParam = 1 - param;
//Faster evaluation for easy cases:
switch (numKnots)
{
case 0:
return 1;
case 1:
{
switch (knotNo)
{
case 0:
return iParam;
case 1:
return param;
}
break;
}
case 2:
{
switch (knotNo)
{
case 0:
return iParam * iParam;
case 1:
return 2 * iParam * param;
case 2:
return param * param;
}
break;
}
case 3:
{
switch (knotNo)
{
case 0:
return iParam * iParam * iParam;
case 1:
return 3 * iParam * iParam * param;
case 2:
return 3 * iParam * param * param;
case 3:
return param * param * param;
}
break;
}
}
//If this bezier has more than four points, calculate bernstein the hard way
double retVal = 1;
for (int i = 0; i < knotNo; i++)
{
retVal *= param;
}
for (int i = 0; i < numKnots - knotNo; i++)
{
retVal *= iParam;
}
retVal *= choose(numKnots, knotNo);
return retVal;
}
private int choose(int num, int denom)
{
int denom2 = num - denom;
if (denom < denom2)
{
int tmp = denom;
denom = denom2;
denom2 = tmp;
}
int prod = 1;
for (int i = num; i > denom; i--)
{
prod *= num;
}
for (int i = 2; i <= denom2; i++)
{
prod /= i;
}
return prod;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy