Commit 7d666092 authored by Nico Mack's avatar Nico Mack

Added methods to create quadratic B-Splines

parent 060595ad
......@@ -16,8 +16,10 @@
*/
package lu.list.itis.dkd.tui.utility;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.PathIterator;
import java.util.List;
/**
* @author mack
......@@ -30,6 +32,9 @@ public class ShapeUtils {
// * Constants *
// ***************************************************************************
private static final int QUADRATIC_WEIGHTS = 3;
// private static final int CUBIC_WEIGHTS = 4;
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s)
......@@ -40,6 +45,76 @@ public class ShapeUtils {
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* Computes the weights of the four control points using the basis function of Cubic B-Spline
* Curves.
*
* @param i
* @param t
* @return
* @see http://www2.cs.uregina.ca/~anima/408/Notes/Interpolation/UniformBSpline.htm
*/
// ---------------------------------------------------------------------------
public static double[] getQuadraticWeights(double x) {
double[] weights = new double[QUADRATIC_WEIGHTS];
double oneMinusX = (1 - x);
weights[0] = oneMinusX * oneMinusX;
weights[1] = 2 * oneMinusX * x;
weights[2] = x * x;
return weights;
}
// ---------------------------------------------------------------------------
/**
* Computes the weights of the four control points using the basis function of Cubic B-Spline
* Curves.
*
* @param i
* @param t
* @return
* @see http://www2.cs.uregina.ca/~anima/408/Notes/Interpolation/UniformBSpline.htm
*/
// ---------------------------------------------------------------------------
// public static double[] getCubicWeights(double x) {
// double[] weights = new double[CUBIC_WEIGHTS];
//
// double oneMinusX = (1 - x);
// double X2 = x * x;
// double X3 = X2 * x;
//
// weights[0] = (oneMinusX * oneMinusX * oneMinusX) / 6;
// weights[1] = (3 * X3 - 6 * X2 + 4) / 6;
// weights[2] = (-3 * X3 + 3 * X2 + 3 * x + 1) / 6;
// weights[3] = X3 / 6;
//
// return weights;
// }
// ---------------------------------------------------------------------------
private static Point getControlPoint(int index, double u, Point[] controlSegments) {
double ctrlX = 0;
double ctrlY = 0;
double[] weights = getQuadraticWeights(u);
for (int i = 0; i < QUADRATIC_WEIGHTS; i++) {
Point segment = controlSegments[index + i];
ctrlX += weights[i] * segment.x;
ctrlY += weights[i] * segment.y;
}
return new Point((float) ctrlX, (float) ctrlY, 0f, ScreenCoordinates.class);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body
......@@ -98,12 +173,55 @@ public class ShapeUtils {
}
pi.next();
}
signedArea *= 0.5;
centroidX /= (6d * signedArea);
centroidY /= (6d * signedArea);
// signedArea *= 0.5;
// centroidX /= (6d * signedArea);
// centroidY /= (6d * signedArea);
signedArea *= 3d;
if (signedArea != 0) {
centroidX /= signedArea;
centroidY /= signedArea;
}
return new Point((float) centroidX, (float) centroidY, 0f, ScreenCoordinates.class);
}
// ---------------------------------------------------------------------------
/**
* @param controlSegments
* @param numberOfSteps
* @return
*/
// ---------------------------------------------------------------------------
public static Polygon quadraticBSpline(List<Point> controlSegments, int numberOfSteps) {
Polygon poly = new Polygon();
int numberOfPoints = controlSegments.size();
Point[] segments = new Point[numberOfPoints];
Point ctrl;
for (int i = 0; i < numberOfPoints; i++) {
segments[i] = controlSegments.get(i).clone().toCoordinates(ScreenCoordinates.class);
}
numberOfPoints -= (QUADRATIC_WEIGHTS - 1);
for (int i = 0; i < numberOfPoints; i++) {
for (int j = 0; j <= numberOfSteps; j++) {
double u = ((double) j) / numberOfSteps;
ctrl = getControlPoint(i, u, segments);
poly.addPoint((int) ctrl.x, (int) ctrl.y);
}
}
return poly;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class
// ***************************************************************************
// ---------------------------------------------------------------------------
}
/**
* Copyright Luxembourg Institute of Science and Technology, 2019. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.utility;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public class ShapeUtilsTest {
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {}
@Test
public void testcubicBSpline() {
List<Point> controlSegments = new ArrayList<>();
controlSegments.add(new Point(0, 100, 0, ScreenCoordinates.class));
controlSegments.add(new Point(0, 0, 0, ScreenCoordinates.class));
controlSegments.add(new Point(100, 0, 0, ScreenCoordinates.class));
Polygon poly = ShapeUtils.quadraticBSpline(controlSegments, 4);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment