package edu.gatech.cs2340.trydent.sample; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.util.LinkedList; import java.util.List; import javax.swing.JComponent; import javax.swing.JFrame; import edu.gatech.cs2340.trydent.math.BaseVector; import edu.gatech.cs2340.trydent.math.Position; import edu.gatech.cs2340.trydent.math.curve.Curve; import edu.gatech.cs2340.trydent.math.curve.IndexWrapMode; import edu.gatech.cs2340.trydent.math.curve.Interpolation; import edu.gatech.cs2340.trydent.math.curve.SplineCurve; /** * Class to visually test the shapes of various interpolation curves. */ public class InterpolationExample extends JComponent { private static final long serialVersionUID = 7283474201296522376L; public static void main(String[] args) { int width = 800; int height = 750; final InterpolationExample example = new InterpolationExample(width, height); example.clear(); Position[] pointsA = { new Position(60, 60), new Position(150, 60), new Position(250, 150), new Position(350, 100), new Position(450, 350), new Position(550, 200) }; example.render(Color.BLACK, new SplineCurve<BaseVector<?>>(Interpolation.STRAIGHT, IndexWrapMode.CLAMP, pointsA), pointsA); example.render(Color.RED, new SplineCurve<BaseVector<?>>(Interpolation.SMOOTH, IndexWrapMode.REFLECT, pointsA), pointsA); example.render(Color.GREEN, new SplineCurve<BaseVector<?>>(Interpolation.SMOOTH, IndexWrapMode.WRAP, pointsA), pointsA); example.render(Color.BLUE, new SplineCurve<BaseVector<?>>(Interpolation.SMOOTH, IndexWrapMode.CLAMP, pointsA), pointsA); Position[] pointsB = { new Position(100, 400), new Position(100, 500), new Position(200, 600), new Position(300, 500), new Position(200, 400), }; example.render(Color.BLACK, true, new SplineCurve<BaseVector<?>>(Interpolation.STRAIGHT, IndexWrapMode.WRAP, pointsB), pointsB); example.render(Color.RED, true, new SplineCurve<BaseVector<?>>(Interpolation.SMOOTH, IndexWrapMode.REFLECT, pointsB), pointsB); example.render(Color.GREEN, true, new SplineCurve<BaseVector<?>>(Interpolation.SMOOTH, IndexWrapMode.WRAP, pointsB), pointsB); example.render(Color.BLUE, true, new SplineCurve<BaseVector<?>>(Interpolation.SMOOTH, IndexWrapMode.CLAMP, pointsB), pointsB); JFrame frame = new JFrame("Interpolation Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(example); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException x) { } example.repaint(); } } }).start(); } private BufferedImage frameBuffer; private Graphics2D graphics; private double time = 0; private double speed = 0.2; private long lastMillis; private List<Runnable> renderActions; public InterpolationExample(int width, int height) { frameBuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); graphics = frameBuffer.createGraphics(); setPreferredSize(new Dimension(width, height)); renderActions = new LinkedList<>(); lastMillis = System.currentTimeMillis(); } @Override public void paint(Graphics g) { time += (System.currentTimeMillis() - lastMillis) / 1000.0 * speed; lastMillis = System.currentTimeMillis(); for (Runnable r : renderActions) { r.run(); } g.drawImage(frameBuffer, 0, 0, getWidth(), getHeight(), this); } private void addRenderAction(Runnable r) { renderActions.add(r); r.run(); } private void clear() { addRenderAction(new Runnable() { @Override public void run() { graphics.setColor(Color.WHITE); graphics.fillRect(-1, -1, frameBuffer.getWidth() + 2, frameBuffer.getHeight() + 2); } }); } private void render(Color color, Curve<BaseVector<?>> curve, BaseVector<?>... points) { render(color, false, curve, points); } private void render(final Color color, final boolean nPlus1, final Curve<BaseVector<?>> curve, final BaseVector<?>... points) { addRenderAction(new Runnable() { @Override public void run() { doRender(color, nPlus1, curve, points); } }); } private void doRender(Color color, boolean nPlus1, Curve<BaseVector<?>> curve, BaseVector<?>... points) { Graphics2D g = this.graphics; g.setColor(color); g.setStroke(new BasicStroke(2.0f)); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int subdivisions = 25 * points.length; double timeMultiplier = 1.0 / subdivisions; if (nPlus1) { timeMultiplier = 1.0 / (subdivisions - 25); } for (int n = 0; n < subdivisions; n++) { BaseVector<?> pA = curve.sample((n + 0.0) * timeMultiplier); BaseVector<?> pB = curve.sample((n + 1.0) * timeMultiplier); int ax = (int) Math.round(pA.getX()), ay = (int) Math.round(pA.getY()); int bx = (int) Math.round(pB.getX()), by = (int) Math.round(pB.getY()); g.drawLine(ax, ay, bx, by); } int w = 6; int h = 6; for (int i = 0; i < points.length; i++) { int x = (int) Math.round(points[i].getX() - w / 2); int y = (int) Math.round(points[i].getY() - h / 2); g.setColor(Color.WHITE); g.fillOval(x, y, w, h); g.setColor(color); g.drawOval(x, y, w, h); } int x = (int) curve.sample(time).getX(); int y = (int) curve.sample(time).getY(); g.setColor(Color.WHITE); g.fillOval(x, y, w, h); g.setColor(color); g.drawOval(x, y, w, h); } }