/* * Copyright (c) 2002 Aravind Krishnaswamy. 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. * * -Redistribution in binary form must reproduct 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 "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that Software is not designed, licensed or intended for * use in the design, construction, operation or maintenance of any nuclear * facility. */ /* * @(#)Bezier.java 1.00 08/29/2002 */ import java.awt.*; import java.awt.event.*; import java.util.Vector; import java.applet.*; import risej.Math3D.Vector3; public class Bezier extends Applet { BezierDrawPanel panel; public void init() { setLayout(new BorderLayout()); panel = new BezierDrawPanel(); add("Center", panel); } public void destroy() { remove(panel); } public static void main(String args[]) { Frame f = new Frame("Bezier Curve Test"); Bezier bez = new Bezier(); bez.init(); bez.start(); f.add("Center", bez); f.setSize(400, 400); f.show(); } public String getAppletInfo() { return "Bezier Curve tesselation by Aravind Krishnaswamy"; } } class BezierDrawPanel extends Panel implements MouseListener, MouseMotionListener { private int nPointClicked; BezierCurve curve = new BezierCurve(); public BezierDrawPanel() { addMouseListener(this); addMouseMotionListener(this); curve.recomputePoints(); } private void clampControlPoints() { // Clamps all the control points so they don't leave the screen if (curve.p1.x > this.getSize().width) curve.p1.x = this.getSize().width; if (curve.p1.x < 0) curve.p1.x = 0; if (curve.p2.x > this.getSize().width) curve.p2.x = this.getSize().width; if (curve.p2.x < 0) curve.p2.x = 0; if (curve.p3.x > this.getSize().width) curve.p3.x = this.getSize().width; if (curve.p3.x < 0) curve.p3.x = 0; if (curve.p4.x > this.getSize().width) curve.p4.x = this.getSize().width; if (curve.p4.x < 0) curve.p4.x = 0; if (curve.p1.y > this.getSize().height) curve.p1.y = this.getSize().height; if (curve.p1.y < 0) curve.p1.y = 0; if (curve.p2.y > this.getSize().height) curve.p2.y = this.getSize().height; if (curve.p2.y < 0) curve.p2.y = 0; if (curve.p3.y > this.getSize().height) curve.p3.y = this.getSize().height; if (curve.p3.y < 0) curve.p3.y = 0; if (curve.p4.y > this.getSize().height) curve.p4.y = this.getSize().height; if (curve.p4.y < 0) curve.p4.y = 0; } /** * Called when the user clicks the mouse **/ public void mousePressed(MouseEvent e) { e.consume(); // Calculate the closest point to which the user clicked... this.nPointClicked = 1; int nDist = distanceBetweenPoints2D( (int) e.getX(), (int) e.getY(), (int) curve.p1.x, (int) curve.p1.y); int nTemp = distanceBetweenPoints2D( (int) e.getX(), (int) e.getY(), (int) curve.p2.x, (int) curve.p2.y); if (nTemp < nDist) { nDist = nTemp; nPointClicked = 2; } nTemp = distanceBetweenPoints2D( (int) e.getX(), (int) e.getY(), (int) curve.p3.x, (int) curve.p3.y); if (nTemp < nDist) { nDist = nTemp; nPointClicked = 3; } nTemp = distanceBetweenPoints2D( (int) e.getX(), (int) e.getY(), (int) curve.p4.x, (int) curve.p4.y); if (nTemp < nDist) { nDist = nTemp; nPointClicked = 4; } } public void mouseDragged(MouseEvent e) { e.consume(); if (nPointClicked == 1) { curve.p1.x = e.getX(); curve.p1.y = e.getY(); } if (nPointClicked == 2) { curve.p2.x = e.getX(); curve.p2.y = e.getY(); } if (nPointClicked == 3) { curve.p3.x = e.getX(); curve.p3.y = e.getY(); } if (nPointClicked == 4) { curve.p4.x = e.getX(); curve.p4.y = e.getY(); } clampControlPoints(); curve.recomputePoints(); repaint(); } public void mouseMoved(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public int distanceBetweenPoints2D(int p1x, int p1y, int p2x, int p2y) { int nT1, nT2; nT1 = p2x - p1x; nT2 = p2y - p1y; return (int) (java.lang.Math.sqrt( (double) (nT1 * nT1 + nT2 * nT2))); } public void paint(Graphics g) { g.clearRect(0, 0, this.getSize().width, this.getSize().height); for (int i = 0; i < curve.CurvePoints1.size(); i++) { Vector3 v = (Vector3) curve.CurvePoints1.elementAt(i); Vector3 v2 = (Vector3) curve.CurvePoints2.elementAt(i); g.drawLine( (int) v.x, (int) v.y, (int) v2.x, (int) v2.y); } g.draw3DRect( (int) curve.p1.x - 1, (int) curve.p1.y - 1, 3, 3, true); g.draw3DRect( (int) curve.p2.x - 1, (int) curve.p2.y - 1, 3, 3, true); g.draw3DRect( (int) curve.p3.x - 1, (int) curve.p3.y - 1, 3, 3, true); g.draw3DRect( (int) curve.p4.x - 1, (int) curve.p4.y - 1, 3, 3, true); } } class BezierCurve { public Vector CurvePoints1 = new Vector(256, 256); public Vector CurvePoints2 = new Vector(256, 256); public Vector3 p1 = new Vector3(100, 200, 0); public Vector3 p2 = new Vector3(175, 100, 0); public Vector3 p3 = new Vector3(230, 300, 0); public Vector3 p4 = new Vector3(300, 200, 0); int nDetail = 50; public BezierCurve() { } public BezierCurve(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, int detail) { this.p1 = new Vector3(v1.x, v1.y, v1.z); this.p2 = new Vector3(v2.x, v2.y, v2.z); this.p3 = new Vector3(v3.x, v3.y, v3.z); this.p4 = new Vector3(v4.x, v4.y, v4.z); nDetail = detail; } public void recomputePoints() { CurvePoints1.clear(); CurvePoints2.clear(); int numsteps = this.nDetail; double xdelta, xdelta2, xdelta3; double ydelta, ydelta2, ydelta3; double zdelta, zdelta2, zdelta3; double deltastep, deltastep2, deltastep3; double ax, ay, az; double bx, by, bz; double cx, cy, cz; Vector3 v1, v2; deltastep = (double) 1.0 / (double) numsteps; deltastep2 = deltastep * deltastep; deltastep3 = deltastep2 * deltastep; ax = -p1.x + 3.0 * p2.x - 3.0 * p3.x + p4.x; ay = -p1.y + 3.0 * p2.y - 3.0 * p3.y + p4.y; az = -p1.z + 3.0 * p2.z - 3.0 * p3.z + p4.z; bx = 3.0 * p1.x - 6.0 * p2.x + 3.0 * p3.x; by = 3.0 * p1.y - 6.0 * p2.y + 3.0 * p3.y; bz = 3.0 * p1.z - 6.0 * p2.z + 3.0 * p3.z; cx = -3.0 * p1.x + 3.0 * p2.x; cy = -3.0 * p1.y + 3.0 * p2.y; cz = -3.0 * p1.z + 3.0 * p2.z; xdelta = ax * deltastep3 + bx * deltastep2 + cx * deltastep; ydelta = ay * deltastep3 + by * deltastep2 + cy * deltastep; zdelta = az * deltastep3 + bz * deltastep2 + cz * deltastep; xdelta3 = 6.0 * ax * deltastep3; ydelta3 = 6.0 * ay * deltastep3; zdelta3 = 6.0 * az * deltastep3; xdelta2 = xdelta3 + 2.0 * bx * deltastep2; ydelta2 = ydelta3 + 2.0 * by * deltastep2; zdelta2 = zdelta3 + 2.0 * cz * deltastep2; v1 = new Vector3(p1.x, p1.y, p1.z); v2 = new Vector3(0, 0, 0); for (int i = 0; i < numsteps; i++) { v2.x = v1.x + xdelta; xdelta += xdelta2; xdelta2 += xdelta3; v2.y = v1.y + ydelta; ydelta += ydelta2; ydelta2 += ydelta3; v2.z = v1.z + zdelta; zdelta += zdelta2; zdelta2 += zdelta3; // Draw line here, v1 and v2 CurvePoints1.addElement(new Vector3(v1.x, v1.y, v1.z)); CurvePoints2.addElement(new Vector3(v2.x, v2.y, v2.z)); v1.x = v2.x; v1.y = v2.y; v1.z = v2.z; } } }