import com.sun.j3d.utils.geometry.Text2D; import com.sun.j3d.utils.universe.SimpleUniverse; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.media.j3d.Appearance; import javax.media.j3d.BranchGroup; import javax.media.j3d.Geometry; import javax.media.j3d.GeometryArray; import javax.media.j3d.GeometryUpdater; import javax.media.j3d.LineArray; import javax.media.j3d.Locale; import javax.media.j3d.Shape3D; import javax.vecmath.Color3f; import org.apache.commons.math3.linear.MatrixUtils; import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.util.FastMath; public class notusingtransform3D { public static void main(String[] args) { System.setProperty("sun.awt.noerasebackground", "true"); new notusingtransform3D(); } float x=0, y=0, z=0, dX=1, dY=1, dZ=1; double rotX=0, rotY=0, rotZ=0, dRotX=0.05, dRotY=0.05, dRotZ=0.05; double zoomScaleX=0, zoomScaleY=0; LineArray cube_one, cube_two, cube_three; String legendText = "a"; float[] cube_oneData, cube_twoData, cube_threeData; float[][] cube1_pt = { { -2, +0, -10 }, { -2, +0, -11 }, { -2, +1, -11 }, { -2, +1, -10 }, { -1, +1, -10 }, { -1, +0, -10 }, { -1, +0, -11 }, { -1, +1, -11 } }; float[][] cube2_pt = { { -3, +0, -12 }, { -3, +0, -14 }, { -3, +2, -14 }, { -3, +2, -12 }, { -1, +2, -12 }, { -1, +0, -12 }, { -1, +0, -14 }, { -1, +2, -14 } }; float[][] cube3_pt = { { -2, +0, -15 }, { -2, +0, -17 }, { -2, +3, -17 }, { -2, +3, -15 }, { -1, +3, -15 }, { -1, +0, -15 }, { -1, +0, -17 }, { -1, +3, -17 } }; public RealMatrix translationM(double tx, double ty, double tz) { double[][] matrixData = { { 1, 0, 0, tx }, { 0, 1, 0, ty }, { 0, 0, 1, tz }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix rotateX(double fi) { double[][] matrixData = { { 1, 0, 0, 0 }, { 0, FastMath.cos(fi), -FastMath.sin(fi), 0 }, { 0, FastMath.sin(fi), FastMath.cos(fi), 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix rotateY(double fi) { double[][] matrixData = { { FastMath.cos(fi), 0, FastMath.sin(fi), 0 }, { 0, 1, 0, 0 }, { -FastMath.sin(fi), 0, FastMath.cos(fi), 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix rotateZ(double fi) { double[][] matrixData = { { FastMath.cos(fi), -FastMath.sin(fi), 0, 0 }, { FastMath.sin(fi), FastMath.cos(fi), 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix scale(double scaleX, double scaleY, double scaleZ) { double[][] matrixData = { { scaleX, 0, 0, 0 }, { 0, scaleY, 0, 0 }, { 0, 0, scaleZ, 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix quaternion(float x, float y, float z, float w) { double[][] quatData = { { x }, { y }, { z }, { w } }; RealMatrix quat = MatrixUtils.createRealMatrix(quatData); return quat; } public void translateArray(float[] cube, float deltaX, float deltaY, float deltaZ) { RealMatrix quat; for (int i = 0; i < 24; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(translationM(deltaX, deltaY, deltaZ)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void rotateArrayX(float[] cube, double fi) { RealMatrix quat; for (int i = 0; i < 24; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(rotateX(fi)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void rotateArrayY(float[] cube, double fi) { RealMatrix quat; for (int i = 0; i < 24; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(rotateY(fi)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void rotateArrayZ(float[] cube, double fi) { RealMatrix quat; for (int i = 0; i < 24; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(rotateZ(fi)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void zoom(float[] cube, double scaleX, double scaleY, double scaleZ) { RealMatrix quat; for (int i = 0; i < 24; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(scale(scaleX, scaleY, scaleZ)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public static LineArray ccr1(float cube_pts[][]) { LineArray cube = new LineArray(24, GeometryArray.COORDINATES | GeometryArray.BY_REFERENCE); cube.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE); ccr2(cube, cube_pts); return cube; } public static void ccr2(LineArray geom, float cube_pts[][]) { float[][] cube_edges = new float[24][3]; int offset = 0; for (int i = 0; i < 7; i++) { for (int j = i + 1; j < 8; j++) { int counter = 0; if (cube_pts[i][0] == cube_pts[j][0]) counter++; if (cube_pts[i][1] == cube_pts[j][1]) counter++; if (cube_pts[i][2] == cube_pts[j][2]) counter++; if (counter == 2) { for (int l = 0; l < 3; l++) { cube_edges[offset + 0][l] = cube_pts[i][l]; cube_edges[offset + 1][l] = cube_pts[j][l]; } offset += 2; } } } float[] flat_pts = new float[cube_edges.length * 3]; for (int i = 0; i < cube_edges.length; i++) { flat_pts[i * 3 + 0] = cube_edges[i][0]; flat_pts[i * 3 + 1] = cube_edges[i][1]; flat_pts[i * 3 + 2] = cube_edges[i][2]; } geom.setCoordRefFloat(flat_pts); } public notusingtransform3D() { SimpleUniverse uni = new SimpleUniverse(); BranchGroup group = new BranchGroup(); Appearance app = new Appearance(); Locale loc = new Locale(uni); cube_one = ccr1(cube1_pt); cube_oneData = cube_one.getCoordRefFloat(); cube_two = ccr1(cube2_pt); cube_twoData = cube_two.getCoordRefFloat(); cube_three = ccr1(cube3_pt); cube_threeData = cube_three.getCoordRefFloat(); Shape3D cube1 = new Shape3D(cube_one, app); // creates Shape3D from Geometry and Appearance Shape3D cube2 = new Shape3D(cube_two, app); Shape3D cube3 = new Shape3D(cube_three, app); Text2D legend = new Text2D(legendText,new Color3f(1,1,1), "Arial", 12, 0); group.addChild(cube1); // adding Shape3D to BranchGroup group.addChild(cube2); group.addChild(cube3); group.addChild(legend); loc.addBranchGraph(group); uni.getViewingPlatform().setNominalViewingTransform(); uni.getCanvas().addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_A) { x-=dX; System.out.println("x = " + x); cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cube_oneData, dX, 0, 0); translateArray(cube_twoData, dX, 0, 0); translateArray(cube_threeData, dX, 0, 0); legendText = "x = " + x; } }); } if (e.getKeyCode() == KeyEvent.VK_D) { x+=dX; System.out.println("x = " + x); cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cube_oneData, -dX, 0, 0); translateArray(cube_twoData, -dX, 0, 0); translateArray(cube_threeData, -dX, 0, 0); } }); } if (e.getKeyCode() == KeyEvent.VK_Q) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cube_oneData, 0, dY, 0); translateArray(cube_twoData, 0, dY, 0); translateArray(cube_threeData, 0, dY, 0); } }); } if (e.getKeyCode() == KeyEvent.VK_E) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cube_oneData, 0, -dY, 0); translateArray(cube_twoData, 0, -dY, 0); translateArray(cube_threeData, 0, -dY, 0); } }); } if (e.getKeyCode() == KeyEvent.VK_W) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cube_oneData, 0, 0, dZ); translateArray(cube_twoData, 0, 0, dZ); translateArray(cube_threeData, 0, 0, dZ); } }); } if (e.getKeyCode() == KeyEvent.VK_S) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cube_oneData, 0, 0, -dZ); translateArray(cube_twoData, 0, 0, -dZ); translateArray(cube_threeData, 0, 0, -dZ); } }); } if (e.getKeyCode() == KeyEvent.VK_DOWN) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cube_oneData, dRotX); rotateArrayX(cube_twoData, dRotX); rotateArrayX(cube_threeData, dRotX); } }); } if (e.getKeyCode() == KeyEvent.VK_UP) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cube_oneData, -dRotX); rotateArrayX(cube_twoData, -dRotX); rotateArrayX(cube_threeData, -dRotX); } }); } if (e.getKeyCode() == KeyEvent.VK_RIGHT) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cube_oneData, dRotY); rotateArrayY(cube_twoData, dRotY); rotateArrayY(cube_threeData, dRotY); } }); } if (e.getKeyCode() == KeyEvent.VK_LEFT) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cube_oneData, -dRotY); rotateArrayY(cube_twoData, -dRotY); rotateArrayY(cube_threeData, -dRotY); } }); } if (e.getKeyCode() == KeyEvent.VK_C) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cube_oneData, dRotZ); rotateArrayZ(cube_twoData, dRotZ); rotateArrayZ(cube_threeData, dRotZ); } }); } if (e.getKeyCode() == KeyEvent.VK_V) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cube_oneData, -dRotZ); rotateArrayZ(cube_twoData, -dRotZ); rotateArrayZ(cube_threeData, -dRotZ); } }); } if (e.getKeyCode() == KeyEvent.VK_Z) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cube_oneData, 0.95, 0.95, 1); zoom(cube_twoData, 0.95, 0.95, 1); zoom(cube_threeData, 0.95, 0.95, 1); } }); } if (e.getKeyCode() == KeyEvent.VK_X) { cube_one.updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cube_oneData, 1.05, 1.05, 1); zoom(cube_twoData, 1.05, 1.05, 1); zoom(cube_threeData, 1.05, 1.05, 1); } }); } } }); } }