package com.mathorama.wumpus; import java.awt.Point; import java.awt.Rectangle; public class Vertex implements Comparable { private double x,y,z; public static final double CamX=0;//3d viewpoint coords public static final double CamY=0;//3d viewpoint coords public static final double CamZ=-3;//3d viewpoint coords //public int xfac=90, zfac=90; public static final double RADIANS=Math.PI/180.0;//degree to radian conversion public Vertex(double x, double y, double z){ this.x=x; this.y=y; this.z=z; } public boolean equals(Vertex o) { return x==o.getX() && y==o.getY() && z==o.getZ(); } public double getZ() { return z; } public double getY() { return y; } public double getX() { return x; } public int compareTo(Vertex other) { return (int)(Math.round(distance(other))); } public double distance(Vertex o) { return Math.sqrt( Math.pow(x-o.getX(), 2)+ Math.pow(y-o.getY(), 2)+ Math.pow(z-o.getZ(), 2) ); } public int screenX(Rectangle r){ double x0 = r.width/2*(x - CamX) /(z-CamZ); return r.x+r.width/2+(int)Math.round(x0); } public int screenY(Rectangle r){ double y0 = r.height/2*(y - CamY) /(z-CamZ); return r.y+r.height/2-(int)Math.round(y0); } public Point screenXY(Rectangle r, double yAxis, double xAxis){ double a = 2*yAxis*RADIANS; double b = 2*xAxis*RADIANS; //rotation around y axis double z0 = z*Math.cos(a)-x*Math.sin(a); double x0 = z*Math.sin(a)+x*Math.cos(a); //rotation around x axis double y0 = y*Math.cos(b)-z0*Math.sin(b); double z1 = y*Math.sin(b)+z0*Math.cos(b); //projection double px = r.width/2*(x0 - CamX) /(z1-CamZ); double py = r.height/2*(y0 - CamY) /(z1-CamZ); int sy = r.y+r.height/2-(int)Math.round(py); int sx = r.x+r.width/2+(int)Math.round(px); return new Point(sx,sy); } public Point orthoXY(Rectangle r, double yAxis, double xAxis){ double a = 2*yAxis*RADIANS; double b = 2*xAxis*RADIANS; //rotation around y axis double z0 = z*Math.cos(a)-x*Math.sin(a); double x0 = z*Math.sin(a)+x*Math.cos(a); //rotation around x axis double y0 = y*Math.cos(b)-z0*Math.sin(b); double z1 = y*Math.sin(b)+z0*Math.cos(b); //orthogonal projection of x0,y0,z1 double theta= Math.PI/8; double phi= -1*Math.PI/15; double s=r.width/4; double xf=s*.89; double zf=s*.68; double px = xf*Math.cos(phi)*(x0 - CamX) + zf*Math.cos(theta)*(z1-0); double py = s*(y0 - CamY) + zf*Math.sin(theta)*(z1-0)+xf*Math.sin(phi)*(x0 - CamX); int sy = r.y+r.height/2-(int)Math.round(py); int sx = r.x+r.width/2+(int)Math.round(px); return new Point(sx,sy); } /** * change the point by rotation around the y axis * @param degrees */ public void rotateAxisY(double degrees){ double a = 2*degrees*RADIANS; double z0 = z*Math.cos(a)-x*Math.sin(a); double x0 = z*Math.sin(a)+x*Math.cos(a); z=z0; x=x0; } public void rotateAxisX(double degrees){ double a = 2*degrees*RADIANS; double y0 = y*Math.cos(a)-z*Math.sin(a); double z0 = y*Math.sin(a)+z*Math.cos(a); y=y0; z=z0; } public static Vertex midpoint(Vertex v1, Vertex v2){ double xm = 0.5*(v1.getX()+v2.getX()); double ym = 0.5*(v1.getY()+v2.getY()); double zm = 0.5*(v1.getZ()+v2.getZ()); return new Vertex(xm,ym,zm); } public static Vertex spike(Vertex v1, Vertex v2){ double xm = 0.5*(v1.getX()+v2.getX()); double ym = 0.5*(v1.getY()+v2.getY()); double zm = 0.5*(v1.getZ()+v2.getZ()); return new Vertex(v2.getX()+xm/2,v2.getY()+ym/2,v2.getZ()+zm/2); } /** * * @param v1 * @param percent of vertex to origin * @return a vertex a percentage away from origin */ public static Vertex spike(Vertex v1, double percent){ double xm = percent*(v1.getX()); double ym = percent*(v1.getY()); double zm = percent*(v1.getZ()); return new Vertex(v1.getX()+xm,v1.getY()+ym,v1.getZ()+zm); } public String toString(){ return String.format("(%.3f, %.3f, %.3f)", x,y,z); } }