package primitives3D; import graphicsUtilities.Polygon2D; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.Point2D; import math3D.Window3D; import drawing3D.Object3DViewer; /** * A class which fills the outline created by the sillhouette of an elongated * square rod. * * @author Curran Kelleher * */ public class SolidRod3D extends LineSegment3D { /** * A global flag which, when true, causes all SolidRod3D objects to draw * themselves as simple 2D lines. They will appear exactly as LineSegment3D * objects. * * When false, high precision polygons will represent the lines instead. */ public static boolean drawAsSimpleLine = false; /** * The thickness of the rod; the length of one edge of the square which is * elogated between p1 and p2 to create the rod. */ double thickness; /** * A temporary variable used in calculating the widths at the endpoints. */ Point2D.Float tempPoint = new Point2D.Float(); /** * A temporary variable used in calculating the widths for the endpoints. */ Vector3D temp = new Vector3D(0, 0, 0); /** * The 2D polygon which will be drawn on the screen to represent this 3D * "rod" */ Polygon2D polygon = new Polygon2D(new float[4], new float[4], 4); /** * Creates a rod with the specified endpoints, thickness, and color * * @param p1 * The first endpoint of the 3D rod. * @param p2 * The second endpoint of the 3D rod. * @param thickness * The thickness of the rod; the length of one edge of the square * which is elogated between p1 and p2 to create the rod. * @param color * The color of the rod. */ public SolidRod3D(Vector3D p1, Vector3D p2, double thickness, Color color) { super(p1, p2, color); this.thickness = thickness; } /** * Called on each object before sorting and drawing them, allows them to * calculate the rotated points and whatever else would help. * * @param window * the window used for the rotation (use * window.getRotatedVector3D(Vector3D p)) */ public void calculateRotation(Window3D w) { if (drawAsSimpleLine) super.calculateRotation(w); else { // rotate the endpoints, using centerPoint as an intremediate value // so // it can be used for proper z-sorting. w.getRotatedVector3D(p1, centerPoint); // get the first endpoint in pixel space w.getPixelFromRotatedPoint3D(centerPoint, A); // figure out the thickness at the first endpoint temp.x = centerPoint.x - thickness; temp.y = centerPoint.y; temp.z = centerPoint.z; w.getPixelFromRotatedPoint3D(temp, tempPoint); // TODO the 3D graphics are flipped! make 3D and 2D consistent. double p1Width = Math.abs(A.x - tempPoint.x); // get the second endpoint in pixel space, again using centerPoint // as an // intermediate w.getRotatedVector3D(p2, centerPoint); w.getPixelFromRotatedPoint3D(centerPoint, B); // figure out the thickness at the second endpoint temp.x = centerPoint.x - thickness; temp.y = centerPoint.y; temp.z = centerPoint.z; w.getPixelFromRotatedPoint3D(temp, tempPoint); // TODO the 3D graphics are flipped! make 3D and 2D consistent. double p2Width = Math.abs(B.x - tempPoint.x); double distance = Math.sqrt(Math.pow(B.x - A.x, 2) + Math.pow(B.y - A.y, 2)); double unitX = -(double) (B.x - A.x) / distance; double unitY = (double) (B.y - A.y) / distance; polygon.xpoints[0] = (float) (A.x + unitY * p1Width); polygon.xpoints[1] = (float) (B.x + unitY * p2Width); polygon.xpoints[2] = (float) (B.x - unitY * p2Width); polygon.xpoints[3] = (float) (A.x - unitY * p1Width); polygon.ypoints[0] = (float) (A.y + unitX * p1Width); polygon.ypoints[1] = (float) (B.y + unitX * p2Width); polygon.ypoints[2] = (float) (B.y - unitX * p2Width); polygon.ypoints[3] = (float) (A.y - unitX * p1Width); } } /** * Draws this Object3D onto the specified Graphics. * * @param g * the Graphics on which to draw this 3D object */ public void drawOnThis(Graphics2D g) { if (drawAsSimpleLine) super.drawOnThis(g); // If the rotated Vector3D is not drawable on the screen, the x // coordinate of pointToPutResultIn gets set to Integer.MIN_VALUE by the // method Window.getPixelFromTranslatedVector3D else if (A.x != Integer.MIN_VALUE && B.x != Integer.MIN_VALUE) { g.setColor(Object3DViewer.shadeColor(color, centerPoint.z)); g.fill(polygon); } } }