package ip.raul;
import ip.gui.dialog.DoubleLog;
import ip.gui.frames.ImageFrame;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.ColorModel;
public class ObjectView extends ImageFrame
implements MouseListener, MouseMotionListener, WindowListener {
MenuBar mb = new MenuBar();
Menu SettingsMenu = new Menu("Settings");
Menu ProjectionMenu = new Menu("Projection");
Menu ParallelProjectionMenu = new Menu("Parallel");
Menu PerspectiveProjectionMenu = new Menu("Perspective");
Menu AxonometricParallelProjectionMenu = new Menu("Axonometric");
MenuItem wireframe_mi = addMenuItem(SettingsMenu, "[w]ireframe...");
MenuItem textured_mi = addMenuItem(SettingsMenu, "[t]extured...");
MenuItem orthometric_mi = addMenuItem(ParallelProjectionMenu, "[1] Orthometric");
MenuItem oblique_mi = addMenuItem(ParallelProjectionMenu, "[2] Oblique");
MenuItem trimetric_mi = addMenuItem(AxonometricParallelProjectionMenu, "[1] Trimetric");
MenuItem dimetric_mi = addMenuItem(AxonometricParallelProjectionMenu, "[2] Dimetric");
MenuItem isometric_mi = addMenuItem(AxonometricParallelProjectionMenu, "[3] Isometric");
MenuItem _1point_mi = addMenuItem(PerspectiveProjectionMenu, "[1] 1 Point ");
MenuItem _2point_mi = addMenuItem(PerspectiveProjectionMenu, "[2] 2 Point ");
MenuItem _3point_mi = addMenuItem(PerspectiveProjectionMenu, "[3] 3 Point ");
private short rn[][] = new short[0][0];
private short gn[][] = new short[0][0];
private short bn[][] = new short[0][0];
private ColorModel cm = ColorModel.getRGBdefault();
public Object3D objects[];
public int maxObjects;
public String textures[];
public int maxTextures;
public int view;
public int projection = 1;
public int mode = 1;
public int index = -1;
public boolean hidden = true;
public boolean busy = false;
private Image img = null;
private Image img1 = null;
private Graphics imgG = null;
private double theta = 0;
private double thetaC = 0;
private double thetaS = 0;
private double phi = 0;
private double phiC = 0;
private double phiS = 0;
private double xProj = 1;
private double yProj = 1;
private double zProj = 1;
private double depthFactor = 1;
private DoubleLog DLog = null;
private float xCenter = 150;
private float yCenter = 150;
private float xK = 100; private float yK = 100;
public void projectionEvent(ActionEvent e) {
try {
Button b = (Button) e.getSource();
if (b == DLog.setButton) {
double d[] = DLog.getUserInputAsDouble();
if (projection == 2) {
theta = (double) (d[0] * Math.PI / 180d);
phi = (double) (d[1] * Math.PI / 180d);
thetaC = Math.cos(theta);
thetaS = Math.sin(theta);
phiC = Math.cos(phi);
phiS = Math.sin(phi);
}
if (projection == 3) {
phi = (double) (45 * Math.PI / 180d);
phiC = Math.cos(phi);
phiS = Math.sin(phi);
theta = (double) (d[0] * Math.PI / 180d);
thetaC = Math.cos(theta);
thetaS = Math.sin(theta);
}
if (projection == 4) {
switch ((int) d[0]) {
case 1:
theta = (double) (-35d * Math.PI / 180d);
phi = (double) (45d * Math.PI / 180d);
thetaC = Math.cos(theta);
thetaS = Math.sin(theta);
phiC = Math.cos(phi);
phiS = Math.sin(phi);
break;
case 2:
theta = (double) (35d * Math.PI / 180d);
phi = (double) (-45d * Math.PI / 180d);
thetaC = Math.cos(theta);
thetaS = Math.sin(theta);
phiC = Math.cos(phi);
phiS = Math.sin(phi);
break;
case 3:
theta = (double) (35d * Math.PI / 180d);
phi = (double) (45d * Math.PI / 180d);
thetaC = Math.cos(theta);
thetaS = Math.sin(theta);
phiC = Math.cos(phi);
phiS = Math.sin(phi);
break;
case 4:
theta = (double) (-35d * Math.PI / 180d);
phi = (double) (-45d * Math.PI / 180d);
thetaC = Math.cos(theta);
thetaS = Math.sin(theta);
phiC = Math.cos(phi);
phiS = Math.sin(phi);
break;
default:
System.out.println("Your option was not understood, 1 assumed");
theta = (double) (-35d * Math.PI / 180d);
phi = (double) (45d * Math.PI / 180d);
thetaC = Math.cos(theta);
thetaS = Math.sin(theta);
phiC = Math.cos(phi);
phiS = Math.sin(phi);
break;
}
}
if ((projection == 6)) {
if (d[0] != 0) zProj = d[0];
yProj = 1;
xProj = 1;
}
if ((projection == 7)) {
if (d[0] != 0) xProj = d[0];
if (d[1] != 0) zProj = d[1];
yProj = 1;
}
if ((projection == 8)) {
if (d[0] != 0) xProj = d[0];
if (d[1] != 0) yProj = d[1];
if (d[2] != 0) zProj = d[2];
}
repaint();
}
} catch (Exception ex) {
}
if (match(e, orthometric_mi)) {
projection = 1;
repaint();
return;
}
if (match(e, trimetric_mi)) {
trimetricView();
return;
}
if (match(e, dimetric_mi)) {
dimetricView();
return;
}
if (match(e, isometric_mi)) {
isometricView();
return;
}
if (match(e, oblique_mi)) {
projection = 5;
repaint();
return;
}
if (match(e, _1point_mi)) {
_1pointView();
return;
}
if (match(e, _2point_mi)) {
_2pointView();
return;
}
if (match(e, _3point_mi)) {
_3pointView();
return;
}
}
public void trimetricView() {
String prompts[] = {"Theta (degrees)", "Phi (degrees)"};
String defaults[] = {"0.0", "0.0"};
DLog = new DoubleLog(this,
"Trimetric Projection Dialog", prompts, defaults, 6);
DLog.setVisible(true);
DLog.setButton.addActionListener(this);
projection = 2;
repaint();
}
public void dimetricView() {
String prompts[] = {"Theta (degrees)"};
String defaults[] = {"0.0"};
DLog = new DoubleLog(this,
"Dimetric Projection Dialog", prompts, defaults, 6);
DLog.setVisible(true);
DLog.setButton.addActionListener(this);
projection = 3;
repaint();
}
public void isometricView() {
System.out.println("Please select from the dialog one of the values:");
System.out.println("1: Theta=-45, Phi=35");
System.out.println("2: Theta=45, Phi=-35");
System.out.println("3: Theta=45, Phi=35");
System.out.println("4: Theta=-45, Phi=-35");
String prompts[] = {"Choose 1, 2, 3 or 4"};
String defaults[] = {"1"};
DLog = new DoubleLog(this,
"Isometric Projection Dialog", prompts, defaults, 6);
DLog.setVisible(true);
DLog.setButton.addActionListener(this);
projection = 4;
repaint();
}
public void _1pointView() {
String prompts[] = {"Z = "};
String defaults[] = {"1.0"};
DLog = new DoubleLog(this,
"1 Point Projection Dialog", prompts, defaults, 6);
DLog.setVisible(true);
DLog.setButton.addActionListener(this);
projection = 6;
repaint();
}
public void _2pointView() {
String prompts[] = {"X = ", "Z = "};
String defaults[] = {"1.0", "1.0"};
DLog = new DoubleLog(this,
"2 Point Projection Dialog", prompts, defaults, 6);
DLog.setVisible(true);
DLog.setButton.addActionListener(this);
projection = 7;
repaint();
}
public void _3pointView() {
String prompts[] = {"X = ", "Y = ", "Z = "};
String defaults[] = {"1.0", "1.0", "1.0"};
DLog = new DoubleLog(this,
"3 Point Projection Dialog", prompts, defaults, 6);
DLog.setVisible(true);
DLog.setButton.addActionListener(this);
projection = 8;
repaint();
}
public void actionPerformed(ActionEvent e) {
projectionEvent(e);
if (match(e, wireframe_mi)) {
mode = 1;
repaint();
return;
}
if (match(e, textured_mi)) {
mode = 2;
repaint();
return;
}
super.actionPerformed(e);
}
ObjectView(String title, Object3D _objects[], int _maxObjects, String _textures[], int _maxTextures, int _view) {
super(title);
objects = _objects;
textures = _textures;
maxTextures = _maxTextures;
maxObjects = _maxObjects;
view = _view;
addMouseListener(this);
addMouseMotionListener(this);
addWindowListener(this);
ProjectionMenu.add(ParallelProjectionMenu);
ProjectionMenu.add(PerspectiveProjectionMenu);
ParallelProjectionMenu.add(AxonometricParallelProjectionMenu);
mb.add(SettingsMenu);
mb.add(ProjectionMenu);
setMenuBar(mb);
setSize(300, 300);
hidden = false;
}
private void init() {
}
public void update(Graphics g) {
paint(g);
}
private void Line3D(Point3D p1, Point3D p2, Graphics g) {
Point q1 = get2Dfrom3D(p1);
Point q2 = get2Dfrom3D(p2);
g.drawLine(q1.x, q1.y, q2.x, q2.y);
}
private void setPoint3D(Point3D p, short r1, short g1, short b1, Graphics g) {
Point q = get2Dfrom3D(p);
g.setColor(new Color(r1, g1, b1));
g.drawLine(q.x, q.y, q.x, q.y);
}
int Dist(Point a, Point b) {
return (int) (Math.sqrt(((b.x - a.x) * (b.x - a.x)) + ((b.y - a.y) * (b.y - a.y))));
}
private Point3D getProjection(Point3D p) {
float tmp = 0;
Point3D _p = new Point3D(0, 0, 0);
switch (projection) {
case 1:
_p = p;
break;
case 2:
_p = p;
if (thetaS != 0) {
_p.x = p.x + (float) (p.z * phiC * thetaC / thetaS);
_p.y = p.y + (float) (p.z * phiS * thetaC / thetaS);
}
break;
case 3:
_p = p;
if (thetaS != 0) {
_p.x = p.x + (float) (p.z * phiC * thetaC / thetaS);
_p.y = p.y + (float) (p.z * phiS * thetaC / thetaS);
}
break;
case 4:
_p = p;
if (thetaS != 0) {
_p.x = p.x + (float) (p.z * phiC * thetaC / thetaS);
_p.y = p.y + (float) (p.z * phiS * thetaC / thetaS);
}
break;
case 5:
break;
case 6:
depthFactor = -(p.z / zProj) + 1;
_p.x = (float) (p.x / depthFactor);
_p.y = (float) (p.y / depthFactor);
_p.z = p.z;
break;
case 7:
depthFactor = (-p.x / xProj) - (p.z / zProj) + 1;
_p.x = (float) (p.x / depthFactor);
_p.y = (float) (p.y / depthFactor);
_p.z = p.z;
break;
case 8:
depthFactor = -(p.x / xProj) - (p.y / yProj) - (p.z / zProj) + 1;
_p.x = (float) (p.x / depthFactor);
_p.y = (float) (p.y / depthFactor);
_p.z = p.z;
break;
}
return (_p);
}
private Point get2Dfrom3D(Point3D p) {
Point3D pp = new Point3D(0, 0, 0);
switch (view) {
case 1: pp.x = p.x;
pp.y = -p.z;
pp.z = p.y;
break;
case 2: pp.x = -p.x;
pp.y = -p.z;
pp.z = -p.y;
break;
case 3: pp.x = p.x;
pp.y = -p.y;
pp.z = p.z;
break;
case 4: pp.x = p.x;
pp.y = p.y;
pp.z = -p.z;
break;
case 5: pp.x = -p.y;
pp.y = -p.z;
pp.z = p.x;
break;
case 6: pp.x = p.y;
pp.y = -p.z;
pp.z = -p.x;
break;
}
pp = getProjection(pp);
pp.x = xCenter + pp.x * xK;
pp.y = yCenter + pp.y * yK;
return new Point((int) pp.x, (int) pp.y);
}
private Point3D get3Dfrom2D(Point q) {
float xx1 = 0;
float yy1 = 0;
float zz1 = 0;
float x = 0;
float y = 0;
x = q.x;
y = q.y;
x = x - xCenter;
y = y - yCenter;
x = (float) (x / xK);
y = (float) (y / yK);
switch (view) {
case 1: xx1 = x;
zz1 = -y;
break;
case 2: xx1 = -x;
zz1 = -y;
break;
case 3: xx1 = x;
yy1 = -y;
break;
case 4: xx1 = x;
yy1 = y;
break;
case 5: yy1 = -x;
zz1 = -y;
break;
case 6: yy1 = x;
zz1 = -y;
break;
}
return new Point3D(xx1, yy1, zz1);
}
private void drawSphere(Object3D o, Graphics g1, int mode) {
float Radius = o.Radius;
float deltaTheta = (float) ((float) Math.PI / 9f);
float sini, cosi, sinj, cosj;
Point3D s[][] = new Point3D[18][18];
switch (mode) {
case 1:
for (int i = 0; i < 18; i++)
for (int j = -8; j < 10; j++) {
sini = (float) Math.sin((float) (i * deltaTheta));
cosi = (float) Math.cos((float) (i * deltaTheta));
sinj = (float) Math.sin((float) (j * deltaTheta));
cosj = (float) Math.cos((float) (j * deltaTheta));
float x = o.Pos.x + (float) (Radius * cosi * sinj);
float y = o.Pos.y + (float) (Radius * sini * sinj);
float z = o.Pos.z + (float) (Radius * cosj);
s[i][j + 8] = new Point3D(x, y, z);
}
for (int i = 0; i < 17; i++)
for (int j = 0; j < 17; j++) {
Line3D(s[i][j], s[i + 1][j], g1);
Line3D(s[i + 1][j], s[i + 1][j + 1], g1);
}
break;
case 2:
break;
}
}
private void drawCylinder(Object3D o, Graphics g1, int mode) {
float Radius = o.Radius;
float Height = o.Height;
float deltaTheta = (float) ((float) Math.PI / 8.5f);
float sini, cosi;
Point3D s[][] = new Point3D[18][10];
switch (mode) {
case 1:
for (int i = 0; i < 18; i++)
for (int j = 0; j < 10; j++) {
sini = (float) Math.sin((float) (i * deltaTheta));
cosi = (float) Math.cos((float) (i * deltaTheta));
float x = o.Pos.x + (float) (Radius * cosi);
float y = o.Pos.y + (float) (Height * j / 9f);
float z = o.Pos.z + (float) (Radius * sini);
s[i][j] = new Point3D(x, y, z);
}
for (int i = 0; i < 17; i++) {
for (int j = 0; j < 9; j++) {
Line3D(s[i][j], s[i + 1][j], g1);
Line3D(s[i + 1][j], s[i + 1][j + 1], g1);
}
Line3D(s[i][9], s[i + 1][9], g1);
}
break;
case 2:
break;
}
}
private void drawParalelipiped(Object3D o, Graphics g1, int mode) {
float W = o.Width;
float H = o.Height;
float L = o.Length;
float x, y, z;
Point3D s[][] = new Point3D[4][2];
switch (mode) {
case 1:
x = o.Pos.x - (float) (W / 2f);
y = o.Pos.y - (float) (H / 2f);
z = o.Pos.z - (float) (L / 2f);
s[0][0] = new Point3D(x, y, z);
x = o.Pos.x + (float) (W / 2f);
s[1][0] = new Point3D(x, y, z);
z = o.Pos.z + (float) (L / 2f);
s[2][0] = new Point3D(x, y, z);
x = o.Pos.x - (float) (W / 2f);
s[3][0] = new Point3D(x, y, z);
y = o.Pos.y + (float) (H / 2f);
s[3][1] = new Point3D(x, y, z);
x = o.Pos.x + (float) (W / 2f);
s[2][1] = new Point3D(x, y, z);
z = o.Pos.z - (float) (L / 2f);
s[1][1] = new Point3D(x, y, z);
x = o.Pos.x - (float) (W / 2f);
s[0][1] = new Point3D(x, y, z);
Line3D(s[0][0], s[1][0], g1);
Line3D(s[1][0], s[2][0], g1);
Line3D(s[2][0], s[3][0], g1);
Line3D(s[3][0], s[0][0], g1);
Line3D(s[0][1], s[1][1], g1);
Line3D(s[1][1], s[2][1], g1);
Line3D(s[2][1], s[3][1], g1);
Line3D(s[3][1], s[0][1], g1);
Line3D(s[0][0], s[0][1], g1);
Line3D(s[1][0], s[1][1], g1);
Line3D(s[2][0], s[2][1], g1);
Line3D(s[3][0], s[3][1], g1);
break;
case 2:
break;
}
}
private void drawAxes(Graphics g1, Rectangle r) {
switch (view) { case 1: g1.drawLine(30, r.height - 30, 20, r.height - 20);
g1.drawLine(20, r.height - 20, 20, r.height - 30);
g1.drawLine(20, r.height - 20, 30, r.height - 20);
g1.drawString("z", 18, r.height - 32);
g1.drawString("x", 32, r.height - 18);
g1.drawString("y", 32, r.height - 32);
break;
case 2: g1.drawLine(12, r.height - 12, 20, r.height - 20);
g1.drawLine(20, r.height - 20, 20, r.height - 30);
g1.drawLine(20, r.height - 20, 10, r.height - 20);
g1.drawString("z", 18, r.height - 32);
g1.drawString("x", 6, r.height - 18);
g1.drawString("y", 6, r.height - 6);
break;
case 3: g1.drawLine(12, r.height - 12, 20, r.height - 20);
g1.drawLine(20, r.height - 20, 20, r.height - 30);
g1.drawLine(20, r.height - 20, 30, r.height - 20);
g1.drawString("y", 18, r.height - 32);
g1.drawString("x", 32, r.height - 18);
g1.drawString("z", 6, r.height - 6);
break;
case 4: g1.drawLine(30, r.height - 30, 20, r.height - 20);
g1.drawLine(20, r.height - 20, 20, r.height - 10);
g1.drawLine(20, r.height - 20, 30, r.height - 20);
g1.drawString("y", 22, r.height - 6);
g1.drawString("x", 32, r.height - 18);
g1.drawString("z", 32, r.height - 32);
break;
case 5: g1.drawLine(30, r.height - 30, 20, r.height - 20);
g1.drawLine(20, r.height - 20, 20, r.height - 30);
g1.drawLine(20, r.height - 20, 10, r.height - 20);
g1.drawString("z", 18, r.height - 32);
g1.drawString("y", 6, r.height - 18);
g1.drawString("x", 32, r.height - 32);
break;
case 6: g1.drawLine(12, r.height - 12, 20, r.height - 20);
g1.drawLine(20, r.height - 20, 20, r.height - 30);
g1.drawLine(20, r.height - 20, 30, r.height - 20);
g1.drawString("z", 18, r.height - 32);
g1.drawString("y", 32, r.height - 18);
g1.drawString("x", 6, r.height - 6);
break;
}
switch (projection) {
case 1:
g1.drawString("orthometric", 40, r.height - 16);
break;
case 2:
g1.drawString("trimetric", 40, r.height - 16);
break;
case 3:
g1.drawString("dimetric", 40, r.height - 16);
break;
case 4:
g1.drawString("isometric", 40, r.height - 16);
break;
case 5:
g1.drawString("oblique", 40, r.height - 16);
break;
case 6:
g1.drawString("1 point", 40, r.height - 16);
break;
case 7:
g1.drawString("2 point", 40, r.height - 16);
break;
case 8:
g1.drawString("3 point", 40, r.height - 16);
break;
}
}
double linearY(double x1, double x2, double t) {
double dx = 0;
dx = (double) (x2 - x1);
return (double) (x1 + (double) (dx * t));
}
public void paint(Graphics g) {
Rectangle r = getBounds();
img = createImage(r.width, r.height);
imgG = img.getGraphics();
xCenter = (float) (r.width / 2);
yCenter = (float) (r.height / 2);
xK = (float) (r.width / 3);
yK = (float) (r.height / 3);
for (int i = 0; i <= maxObjects; i++) {
if ((i == index) && (busy))
imgG.setColor(new Color(255, 0, 0));
else
imgG.setColor(new Color(0, 0, 0));
switch (objects[i].Type) {
case 1:
drawSphere(objects[i], imgG, mode);
break;
case 2:
drawCylinder(objects[i], imgG, mode);
break;
case 3:
drawParalelipiped(objects[i], imgG, mode);
break;
}
}
imgG.setColor(new Color(0, 0, 0));
drawAxes(imgG, r);
if (img != null) {
g.drawImage(img, 0, 0, r.width, r.height, this);
}
}
public void mouseDragged(MouseEvent e) {
e.consume();
double dx = getX(e);
double dy = getY(e);
double sx = 0;
double sy = 0;
double ray = 100000;
if (!busy) {
busy = true;
index = -1;
for (int i = 0; i <= maxObjects; i++) {
Point s = get2Dfrom3D(objects[i].Pos);
sx = (double) s.x;
sy = (double) s.y;
sx = sx - dx;
sx = sx * sx;
sy = sy - dy;
sy = sy * sy;
if ((sx + sy) < ray) {
ray = sx + sy;
index = i;
}
}
}
if (index != -1) {
objects[index].Pos = get3Dfrom2D(new Point((int) dx, (int) dy));
repaint();
return;
}
}
private int getX(MouseEvent e) {
return (int) (e.getX());
}
private int getY(MouseEvent e) {
return (int) (e.getY());
}
public void mouseReleased(MouseEvent e) {
busy = false;
repaint();
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void windowClosing(WindowEvent e) {
hidden = true;
dispose();
}
public void windowClosed(WindowEvent e) {
};
public void windowDeiconified(WindowEvent e) {
};
public void windowIconified(WindowEvent e) {
};
public void windowActivated(WindowEvent e) {
};
public void windowDeactivated(WindowEvent e) {
};
public void windowOpened(WindowEvent e) {
};
}