Created
August 6, 2011 15:20
-
-
Save timaschew/1129426 to your computer and use it in GitHub Desktop.
3D Animation with Java 2D API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Point3D { | |
public double x; | |
public double y; | |
public double z; | |
public Point3D(double xPos, double yPos, double zPos) { | |
this.x = xPos; | |
this.y = yPos; | |
this.z = zPos; | |
} | |
public Point3D(Point3D p) { | |
this.x = p.x; | |
this.y = p.y; | |
this.z = p.z; | |
} | |
public boolean equals(Point3D p) { | |
if (this.x != p.x) | |
return false; | |
if (this.y != p.y) | |
return false; | |
return this.z == p.z; | |
} | |
public String toString() { | |
return this.x + "/" + this.y + "/" + this.z; | |
} | |
} | |
public class GeometryObject3D { | |
public List<Point3D> points; | |
public GeometryObject3D() { | |
points = new ArrayList<Point3D>(); | |
} | |
public void add(Point3D p) { | |
points.add(p); | |
} | |
} | |
public abstract class WireframeGeometry { | |
public MDDA<Point3D> pointMatrix; | |
public GeometryObject3D points; | |
public List<Line> lineList; | |
public GeometryObject3D getPoints() { | |
return points; | |
} | |
abstract public void init(); | |
} | |
/** | |
* 3dim plane with 3d coordinates | |
* <pre> | |
* | |
* a ___ b ____ c | |
* / / / | | |
* 1- - -2 - - 3 f | |
* | | | /| | |
* 4 - - 5 - - 6 i | |
* | | | / | |
* 7 - - 8 - - 9 | |
* | |
* a ___ b ___ c | |
* / | / | / | | |
* * -d- * -e -* -f | |
* | /| | /| | /| | |
* | -g- * -h- * -i | |
* | / | / | / | |
* * - - * - - * | |
* | |
* a ___ b ___ c | |
* / | / | / | | |
* 1 -d- 2 -e -3 -f | |
* | /| | /| | /| | |
* 4 -g- 5 -h- 6 -i | |
* | / | / | / | |
* 7 - - 8 - - 9 | |
* </pre> | |
* | |
*/ | |
public class GridCube extends WireframeGeometry { | |
public GeometryObject3D points; | |
private int maxHeight; | |
private int maxWidth; | |
private int maxDepth; | |
private int cols; | |
private int rows; | |
private int layers; | |
public GridCube(int rows, int cols, int layers, int maxWidth, int maxHeight, int maxDepth) { | |
pointMatrix = new MDDA<Point3D>(rows, cols, layers); | |
lineList = new ArrayList<Line>(); | |
points = new GeometryObject3D(); | |
this.cols = cols; | |
this.rows = rows; | |
this.layers = layers; | |
this.maxWidth = maxWidth; | |
this.maxHeight = maxHeight; | |
this.maxDepth = maxDepth; | |
init(); | |
} | |
public void init() { | |
lineList.clear(); | |
points.points.clear(); | |
Random rand = new Random(); | |
// points | |
for (int l=0; l<layers; l++) { | |
for (int r=0; r<rows; r++) { | |
for (int c=0; c<cols; c++) { | |
Point3D p = new Point3D(r*maxWidth/rows, c*maxHeight/cols, l*maxDepth/layers); | |
pointMatrix.set(p, r,c,l); | |
points.add(p); | |
} | |
} | |
} | |
// grid cube | |
for (int l=0; l<layers; l++) { | |
for (int r=0; r<rows; r++) { | |
for (int c=0; c<cols; c++) { | |
if (l>0) { | |
Line deep = new Line(pointMatrix.get(r,c,l), pointMatrix.get(r,c,l-1)); | |
lineList.add(deep); | |
} | |
if (r>0) { | |
Line up = new Line(pointMatrix.get(r,c,l), pointMatrix.get(r-1,c,l)); | |
lineList.add(up); | |
} | |
if (c>0) { | |
Line left = new Line(pointMatrix.get(r,c,l), pointMatrix.get(r,c-1,l)); | |
lineList.add(left); | |
} | |
} | |
} | |
} | |
} | |
public GeometryObject3D getPoints() { | |
return points; | |
} | |
} | |
/* | |
* Calculates the 3D to 2D transformation with an rotation | |
* <pre> | |
* | |
* [ 1 0 0 ] [ x ] [ x ] | |
* [ 0 cos(ax) -sin(ax) ] . [ y ] = [ y*cos(ax)-z*sin(ax) ] | |
* [ 0 sin(ax) cos(ax) ] [ z ] [ y*sin(ax)+z*cos(ax) ] | |
* | |
* [ cos(ay) 0 sin(ay) ] [ x ] [ x*cos(ay)+z*sin(ay) ] | |
* [ 0 1 0 ] . [ y ] = [ y ] | |
* [-sin(ay) 0 cos(ay) ] [ z ] [-x*sin(ay)+z*cos(ay) ] | |
* | |
* [ cos(az) -sin(az) 0 ] [ x ] [ x*cos(az)-y*sin(az) ] | |
* [ sin(az) cos(az) 0 ] . [ y ] = [ y*cos(az)+x*sin(az) ] | |
* [ 0 0 1 ] [ z ] [ z ] | |
* </pre> | |
* @param geo | |
* @param cam | |
* @param thetaX | |
* @param thetaY | |
* @param thetaZ | |
*/ | |
/** | |
* @param geo list of points / coordinates to transform / project | |
* @param thetaX orientation x axis | |
* @param thetaY orientation y axis | |
* @param thetaZ orientation z axis | |
* @param camX x position of camera | |
* @param camY y position of camera | |
* @param camZ z position of camera | |
*/ | |
public void transform3DTo2D(GeometryObject3D geo, double thetaX, double thetaY, | |
double thetaZ, double camX, double camY, double camZ) { | |
double aX, aY, aZ; // temp point | |
for (Point3D p : geo.points) { | |
aX = p.x; | |
aY = p.y; | |
aZ = p.z; | |
// 3D -> 2D transformation matrix calculation with rotation | |
// and camera coordinate parameters | |
aY = p.y; | |
aZ = p.z; | |
// Rotation um x-Achse | |
//p[i][x] = px; | |
p.y = (aY-camY)*Math.cos(thetaX)-(aZ-camZ)*Math.sin(thetaX); | |
p.z = (aY-camY)*Math.sin(thetaX)+(aZ-camZ)*Math.cos(thetaX); | |
aX = p.x; | |
aZ = p.z; | |
// Rotation um y-Achse | |
p.x = (aX-camX)*Math.cos(thetaY)+(aZ-camZ)*Math.sin(thetaY); | |
//p[i][y]= py; | |
p.z =-(aX-camX)*Math.sin(thetaY)+(aZ-camZ)*Math.cos(thetaY); | |
aY = p.y; | |
aX = p.x; | |
// Rotation um z-Achse | |
p.x = (aX-camX)*Math.cos(thetaZ)-(aY-camY)*Math.sin(thetaZ); | |
p.y = (aY-camY)*Math.cos(thetaZ)+(aX-camX)*Math.sin(thetaZ); | |
} | |
} | |
public static void paint(Graphics2D g2d, WireframeGeometry geom, int[] offset2D) { | |
int wx = offset2D[0]; | |
int wy = offset2D[1]; | |
for (Line line : geom.lineList) { | |
g2d.drawLine((int)line.from.x + wx, (int)line.from.y + wy, | |
(int)line.to.x + wx, (int)line.to.y + wy); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment