/*
* Copyright (c) 2014 Oculus Info Inc.
* http://www.oculusinfo.com/
*
* Released under the MIT License.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.oculusinfo.geometry.cartesian;
import com.oculusinfo.math.linearalgebra.Vector;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class VisualSplineTest extends JFrame {
private static final long serialVersionUID = 1L;
public static void main (String[] args) {
VisualSplineTest app = new VisualSplineTest();
app.setVisible(true);
}
private VisualSplineTest () {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setupPanels();
setLocation(100, 100);
setSize(800, 800);
}
private void setupPanels () {
SplinePanel sp = new SplinePanel();
sp.addSpline(CubicBSpline.fit(new double[] {0, 1, 2, 3, 4, 5, 6},
new Vector(0.25, 0.25),
new Vector(0.50, 0.15),
new Vector(0.75, 0.25),
new Vector(0.85, 0.50),
new Vector(0.75, 0.75),
new Vector(0.50, 0.85),
new Vector(0.25, 0.75)),
Color.CYAN);
sp.addSpline(CubicBSpline.fit(new double[] {0, 1, 2, 3},
new Vector(0.25, 0.25),
new Vector(0.75, 0.25),
new Vector(0.75, 0.75),
new Vector(0.25, 0.75)),
Color.BLUE);
sp.addSpline(CubicBSpline.fit(new double[] {0, 1, 2, 3},
new Vector(0.25, 0.25),
new Vector(0.70, 0.30),
new Vector(0.80, 0.70),
new Vector(0.20, 0.80)),
Color.RED);
sp.addSpline(CubicBSpline.fit(new double[] {0, 1, 2, 3},
new Vector(0.20, 0.30),
new Vector(0.70, 0.20),
new Vector(0.70, 0.80),
new Vector(0.30, 0.70)),
Color.GREEN);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(sp, BorderLayout.CENTER);
}
static class SplinePanel extends JPanel {
private static final long serialVersionUID = 1L;
private List<CubicBSpline> _splines;
private List<Color> _colors;
SplinePanel () {
_splines = new ArrayList<CubicBSpline>();
_colors = new ArrayList<Color>();
}
public void addSpline (CubicBSpline s, Color c) {
_splines.add(s);
_colors.add(c);
}
@Override
public void paint (Graphics g) {
Dimension size = getSize();
int w = size.width;
int h = size.height;
g.setColor(Color.WHITE);
g.fillRect(0, 0, w, h);
Point p00 = getPoint(w, h, new Vector(0, 0));
Point p10 = getPoint(w, h, new Vector(1, 0));
Point p01 = getPoint(w, h, new Vector(0, 1));
Point p11 = getPoint(w, h, new Vector(1, 1));
g.setColor(Color.BLACK);
g.drawLine(p00.x, p00.y, p10.x, p10.y);
g.drawLine(p10.x, p10.y, p11.x, p11.y);
g.drawLine(p11.x, p11.y, p01.x, p01.y);
g.drawLine(p01.x, p01.y, p00.x, p00.y);
for (int i=0; i<_splines.size(); ++i) {
CubicBSpline s = _splines.get(i);
g.setColor(_colors.get(i));
// Draw the control points, emphasizing every third.
int n = s.getNumSegments();
for (int j=0; j<n; ++j) {
drawPoint(g, getPoint(w, h, s.getControlPoint(j, 0)), j, 0, true);
drawPoint(g, getPoint(w, h, s.getControlPoint(j, 1)), j, 1, false);
drawPoint(g, getPoint(w, h, s.getControlPoint(j, 2)), j, 2, false);
if (n-1 == j) {
drawPoint(g, getPoint(w, h, s.getControlPoint(j, 3)), j, 3, true);
}
}
// Now draw the spline
Point lastPt = null;
for (double t=0.0; t<1.0; t+=0.01) {
Vector v = s.getPoint(t);
// System.out.println(String.format("%.4f: %s", t, v.toString()));
Point pt = getPoint(w, h, v);
if (null != lastPt) {
g.drawLine(lastPt.x, lastPt.y, pt.x, pt.y);
}
lastPt = pt;
}
Point pt = getPoint(w, h, s.getPoint(1.0));
g.drawLine(lastPt.x, lastPt.y, pt.x, pt.y);
}
}
private void drawPoint (Graphics g, Point pt, int sNum, int pNum, boolean emphasized) {
g.drawArc(pt.x-3, pt.y-3, 7, 7, 0, 360);
int w=3;
if (emphasized) {
g.drawArc(pt.x-6, pt.y-6, 13, 13, 0, 360);
w=6;
}
g.drawLine(pt.x, pt.y-w, pt.x, pt.y+w);
g.drawLine(pt.x-w, pt.y, pt.x+w, pt.y);
g.drawString(String.format("P%d_%d", sNum, pNum), pt.x+9, pt.y+9);
}
private Point getPoint (int w, int h, Vector v) {
double x = v.coord(0);
double y= v.coord(1);
x = (x+0.25)/1.5;
y = (y+0.25)/1.5;
return new Point((int) Math.round(w*x), (int) Math.round(h*y));
}
}
}