I have a cube and there is a need to add a 3D coordinate system to it.
There is an example my coordinate system with a cube should approximtely look like:
Unfortunately, my progress seems so far from this example:
Maybe, I can find out how to draw X and Y axis, but I have no idea how to add the Z axis.
So, how to build the right coordinate sytem?
My code:
import java.awt.*;
import static java.lang.Math.*;
import javax.swing.*;
public class Cube extends JPanel {
double[][] nodes = {{-1, -1, -1}, {-1, -1, 1}, {-1, 1, -1}, {-1, 1, 1},
{1, -1, -1}, {1, -1, 1}, {1, 1, -1}, {1, 1, 1}};
int[][] edges = {{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6},
{6, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}};
public Cube() {
setPreferredSize(new Dimension(640, 640));
setBackground(Color.white);
scale(50);
rotateCube(Math.toRadians(60), Math.toRadians(10), Math.toRadians(0));
}
final void scale(double s) {
for (double[] node : nodes) {
node[0] *= s;
node[1] *= s;
node[2] *= s;
}
}
final void rotateCube(double angleX, double angleY, double angleZ) {
double sinX = sin(angleX);
double cosX = cos(angleX);
double sinY = sin(angleY);
double cosY = cos(angleY);
double sinZ = sin(angleZ);
double cosZ = cos(angleZ);
for (double[] node : nodes) {
double x = node[0];
double y = node[1];
double z = node[2];
node[0] = x * cosX - z * sinX;
node[2] = z * cosX + x * sinX;
z = node[2];
node[1] = y * cosY - z * sinY;
node[2] = y * sinY + z * cosY;
x = node[0];
y = node[1];
node[0] = x * cosZ + y * sinZ;
node[1] = y * cosZ - x * sinZ;
}
}
void drawCube(Graphics2D g) {
g.translate(getWidth() / 2, getHeight() / 2);
g.setColor(Color.BLACK);
for (int[] edge : edges) {
double[] xy1 = nodes[edge[0]];
double[] xy2 = nodes[edge[1]];
g.drawLine((int) round(xy1[0]), (int) round(xy1[1]),
(int) round(xy2[0]), (int) round(xy2[1]));
}
for (double[] node : nodes)
g.fillOval((int) round(node[0]) - 4, (int) round(node[1]) - 4, 8, 8);
}
void drawAxis(Graphics2D g) {
int x_c = getWidth() / 2;
int y_c = getHeight() / 2;
// X - axis
g.setColor(Color.green);
g.drawLine(round(x_c + 300), round(y_c), round(x_c), round(y_c));
// Y- axis
g.setColor(Color.blue);
g.drawLine(round(x_c), round(y_c), round(x_c), round(y_c) + 300);
}
#Override
public void paintComponent(Graphics gg) {
super.paintComponent(gg);
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawAxis(g);
drawCube(g);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Rotating Cube");
f.setResizable(false);
f.add(new Cube(), BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
Related
I'm following javidx9's tutorial on youtube about making a 3D graphics engine (I'm doing it in java, rather than C++, but I'm pretty closely following his steps), and I'm at the point where we move the cube away from the 'camera' to better see it (35:49, if you're curious), but as soon as I add the relevant lines of code and run it, nothing shows up. When I take them away, it comes back, and I have no idea what's happening. Code is below, sorry it's kind of long and probably poorly written (using Graphics2D for display):
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
static Frame frame;
static double FOV = Math.PI / 2;
static int w = 400;
static int h = 400;
static double a = h / w;
static double f = 1 / Math.tan(FOV / 2);
static double zFar = 1000;
static double zNear = 0.1;
static double q = zFar / (zFar - zNear);
static double[][] matProj = new double[4][4];
public static void main(String[] args) {
frame = new Frame();
}
static void draw() {
Mesh cubeMesh = new Mesh();
//south
cubeMesh.addTri(0, 0, 0, 0, 1, 0, 1, 1, 0);
cubeMesh.addTri(0, 0, 0, 1, 1, 0, 1, 0, 0);
//east
cubeMesh.addTri(1, 0, 0, 1, 1, 0, 1, 1, 1);
cubeMesh.addTri(1, 0, 0, 1, 1, 1, 1, 0, 1);
//north
cubeMesh.addTri(1, 0, 1, 1, 1, 1, 0, 1, 1);
cubeMesh.addTri(1, 0, 1, 0, 1, 1, 0, 0, 1);
//west
cubeMesh.addTri(0, 0, 1, 0, 1, 1, 0, 1, 0);
cubeMesh.addTri(0, 0, 1, 0, 1, 0, 0, 0, 0);
//top
cubeMesh.addTri(0, 1, 0, 0, 1, 1, 1, 1, 1);
cubeMesh.addTri(0, 1, 0, 1, 1, 1, 1, 1, 0);
//bottom
cubeMesh.addTri(1, 0, 1, 0, 0, 1, 0, 0, 0);
cubeMesh.addTri(1, 0, 1, 0, 0, 0, 1, 0, 0);
matProj[0][0] = a * f;
matProj[1][1] = f;
matProj[2][2] = q;
matProj[3][2] = -1 * q * zNear;
matProj[2][3] = 1;
matProj[3][3] = 0;
frame.graphics.g2D.setColor(Color.WHITE);
frame.graphics.g2D.setStroke(new BasicStroke(2));
for(TrianglePoints i : cubeMesh.triangles) {
TrianglePoints translated = i;
translated.p1[2] = i.p1[2] + 3; //when I comment out these lines, it works, but then of course the cube isn't translated
translated.p2[2] = i.p2[2] + 3;
translated.p3[2] = i.p3[2] + 3;
int[] xPoints = {(int) MultiplyMatrixVector(translated.p1, matProj)[0], (int) MultiplyMatrixVector(translated.p2, matProj)[0], (int) MultiplyMatrixVector(translated.p3, matProj)[0]};
int[] yPoints = {(int) MultiplyMatrixVector(translated.p1, matProj)[1], (int) MultiplyMatrixVector(translated.p2, matProj)[1], (int) MultiplyMatrixVector(translated.p3, matProj)[1]};
for(int j = 0; j < xPoints.length; j++) {
xPoints[j] += 1;
xPoints[j] *= (0.5 * w);
yPoints[j] += 1;
yPoints[j] *= (0.5 * w);
}
frame.graphics.g2D.drawPolygon(xPoints, yPoints, 3);
}
}
private static double[] MultiplyMatrixVector(double[] i, double[][] m) {
double[] o = new double[3];
o[0] = i[0] * m[0][0] + i[1] * m[1][0] + i[2] * m[2][0] + m[3][0];
o[1] = i[0] * m[0][1] + i[1] * m[1][1] + i[2] * m[2][1] + m[3][1];
o[2] = i[0] * m[0][2] + i[1] * m[1][2] + i[2] * m[2][2] + m[3][2];
double w = i[0] * m[0][3] + i[1] * m[1][3] + i[2] * m[2][3] + m[3][3];
if(w != 0) { //I think this might be where the issue is, when I translate it w won't be 0, but I don't know how that would make it not work, I have to divide by w here.
o[0] /= w;
o[1] /= w;
o[2] /= w;
}
return o;
}
}
class Frame extends JFrame {
private static final long serialVersionUID = 1L;
GraphicsC graphics = new GraphicsC();
Frame(){
this.setSize(Main.w, Main.h);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(graphics);
this.setVisible(true);
}
}
class GraphicsC extends JPanel {
private static final long serialVersionUID = 1L;
Graphics2D g2D;
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
g2D = (Graphics2D) g;
Main.draw();
}
}
class TrianglePoints {
double[] p1 = new double[3];
double[] p2 = new double[3];
double[] p3 = new double[3];
TrianglePoints(double[] p1, double[] p2, double[] p3) {
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
}
}
class Mesh {
List<TrianglePoints> triangles = new ArrayList<TrianglePoints>();
void addTri(double a, double b, double c, double d, double e, double f, double g, double h, double i) {
double[] p1 = {a, b, c};
double[] p2 = {d, e, f};
double[] p3 = {g, h, i};
triangles.add(new TrianglePoints(p1, p2, p3));
}
}
I highly suspect your issue to be that in C++, doing (timestamp)
triTranslated = tri;
will in fact make a copy of the triangle, whereas your code merely gets a reference, therefore your triangles drift away at pace of 3 units per render, likely vanishing out of view before you could see anything.
The output of the code at the moment is the rectangle design and the first line of the array repeated. The wanted output is the rectangle design and the whole array rather than just the first line.
public class design
{
public static void main (String[] args)
{
JFrame window = new JFrame ("Game Screen");
window.getContentPane ().add (new drawing ());
window.setSize (500, 500);
window.setVisible (true);
window.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
}
class drawing extends JComponent
{
public void paint (Graphics g)
{
int[] [] word = {{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 9, 0, 0, 7, 9}};
int r = 0;
int c = 0;
Graphics2D g2 = (Graphics2D) g;
Rectangle rect;
for (int x = 5 ; x < 450 ; x += 50)
{
for (int y = 5 ; y < 450 ; y += 50)
{
rect = new Rectangle (x, y, 50, 50);
g2.draw (rect);
g.drawString (Integer.toString (word [r] [c]), x + 25, y + 25);
}
c++;
if (c == 9)
{
c = 0;
r++;
}
}
rect = new Rectangle (150, 5, 150, 450);
g2.draw (rect);
rect = new Rectangle (5, 150, 450, 150);
g2.draw (rect);
}
}
Try to put r++; in the second for loop after calling g.drawString. r must also be set to 0 inside the first for loop and before entering the second one.
for (int x = 5 ; x < 450 ; x += 50){
r = 0;
for (int y = 5 ; y < 450 ; y += 50){
rect = new Rectangle (x, y, 50, 50);
g2.draw (rect);
g.drawString (Integer.toString (word [r] [c]), x + 25, y + 25);
r++;
}
c++;
}
It would be more readable (and logical in my opinion) to use only two variables for the loops, x and y in your case, and increment them only by one. You can use them to calculate the positions of your rectangles and place your numbers:
for (int x = 0 ; x < 9 ; x++){
for (int y = 0 ; y < 9 ; y++){
rect = new Rectangle (5+x*50, 5+y*50, 50, 50);
g2.draw (rect);
g.drawString (Integer.toString (word [y] [x]), 5+x*50 + 25, 5+y*50 + 25);
r++;
}
c++;
}
Avoid using magic numbers, it's better to define constant variables and give them an appropriate name. You can then easily change their values, and your code is clearer.
What are "magic numbers" in computer programming?
The issue with your logic is that increment of c doesn't follow increment of y(y-axis). i.e. as per your logic c represents y axis in your 2-dimensional array, but you are incrementing it in the for loop of x axis. Solution to this is, move your logic of c increment in inner for loop
for (int x = 5; x < 450; x += 50) {
for (int y = 5; y < 450; y += 50) {
rect = new Rectangle(x, y, 50, 50);
g2.draw(rect);
g.drawString(Integer.toString(word[r][c]), x + 25, y + 25);
c++;
}
if (c == 9) {
c = 0;
r++;
}
}
As your loop will only increment 9 times, moving of if condition along with c++ is not required.
This question already has answers here:
MyClass cannot be cast to java.lang.Comparable: java.lang.ClassCastException
(3 answers)
Closed 4 years ago.
I have implemented Dijkstra's Algorithm using PriorityQueue. However on running the code, I get the following exception :
Exception in thread "main" java.lang.ClassCastException: Dijkstra$Vertex cannot be cast to java.lang.Comparable
at java.util.PriorityQueue.siftUpComparable(Unknown Source)
at java.util.PriorityQueue.siftUp(Unknown Source)
at java.util.PriorityQueue.offer(Unknown Source)
at java.util.PriorityQueue.add(Unknown Source)
at Dijkstra.dijkstra(Dijkstra.java:55)
at Dijkstra.main(Dijkstra.java:89)
The code used is :
import java.util.HashSet;
import java.util.PriorityQueue;
public class Dijkstra {
static class Vertex{
private int vertexid;
private Double distance;
public Vertex(int vertexid, Double distance) {
this.vertexid = vertexid;
this.distance = distance;
}
public int getVertexid() {
return vertexid;
}
public Double getDistance() {
return distance;
}
public int compareTo(Vertex other) {
return this.getDistance().compareTo(other.getDistance());
}
public boolean equals(Object o) {
if (o instanceof Vertex) {
Vertex v = (Vertex) o;
return vertexid == v.vertexid && distance == v.distance;
}
return false;
}
}
public static void dijkstra(double g[][], int n, int m, int source) {
// g is the adjacency matrix
// n is the number of nodes
// m is the number of edges
// initialize shortest path
double d[] = new double[n];
d[source] = 0;
for (int i = 0; i < n; i++) {
d[i] = Double.POSITIVE_INFINITY;
}
HashSet<Integer> s = new HashSet<Integer>();
PriorityQueue<Vertex> q = new PriorityQueue<Vertex>();
// initialize q
for (int i = 0; i < n; i++) {
q.add(new Vertex(i, d[i]));
}
Vertex u;
while (!q.isEmpty()) {
u = q.remove();
System.out.println(u.getVertexid() + "\t" + u.getDistance());
s.add(u.getVertexid());
for (int i = 0; i < n; i++) {
if (i != u.getVertexid() && g[u.getVertexid()][i] != Double.POSITIVE_INFINITY) {
if (u.getDistance().doubleValue() + g[u.getVertexid()][i] < d[i]) {
q.remove(new Vertex(i, d[i]));
d[i] = u.getDistance().doubleValue() + g[u.getVertexid()][i];
q.add(new Vertex(i, d[i]));
}
}
}
}
}
public static void main(String[] args) {
double graph[][] = {{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}
};
Dijkstra.dijkstra(graph, 8, 14, 0);
}
}
The Vertex class is used to create a structure that basically stores the vertex and its label distance. The priority queue will work on objects of this class, and will use the distance value as the ordering value for remove operations. How to rectify the exception?
Try this instead:
static class Vertex implements Comparable<Vertex> {
i write the following code for a cube, that rotates on mouse motion,
but when i rotate the cube, or resize the Frame, the cube shrinks successively.
Is this the code or Frame, that is to be changed..
Pls Help,,
public class Cube extends javax.swing.JPanel implements MouseMotionListener {
int node0[] = {-100, -100, -100};
int node1[] = {-100, -100, 100};
int node2[] = {-100, 100, -100};
int node3[] = {-100, 100, 100};
int node4[] = {100, -100, -100};
int node5[] = { 100, -100, 100};
int node6[] = {100, 100, -100};
int node7[] = {100, 100, 100};
int nodes[][] = {node0, node1, node2, node3, node4, node5, node6, node7};
int edge0[] = {0, 1};
int edge1[] = {1, 3};
int edge2[] = {3, 2};
int edge3[] = {2, 0};
int edge4[] = {4, 5};
int edge5[] = {5, 7};
int edge6[] = {7, 6};
int edge7[] = {6, 4};
int edge8[] = {0, 4};
int edge9[] = {1, 5};
int edge10[] = {2, 6};
int edge11[] = {3, 7};
int edges[][] = {edge0, edge1, edge2, edge3, edge4, edge5, edge6, edge7, edge8, edge9, edge10, edge11};
// Rotate shape around the z-axis
public void rotateZ3D(int theta) {
double sinTheta = Math.sin(theta);
double cosTheta = Math.cos(theta);
for (int n=0; n<8; n++) {
int[] node = nodes[n];
int x = node[0];
int y = node[1];
node[0] = (int) (x * cosTheta - y * sinTheta);
node[1] = (int) (y * cosTheta + x * sinTheta);
}
};
public void rotateX3D(int theta) {
double sinTheta = Math.sin(theta);
double cosTheta = Math.cos(theta);
for (int n=0; n<8; n++) {
int[] node = nodes[n];
int y = node[1];
int z = node[2];
node[1] = (int) (y * cosTheta - z * sinTheta);
node[2] = (int) (z * cosTheta + y * sinTheta);
}
};
public void rotateY3D(int theta) {
double sinTheta = Math.sin(theta);
double cosTheta = Math.cos(theta);
for (int n=0; n<8; n++) {
int[] node = nodes[n];
int x = node[0];
int z = node[2];
node[0] = (int) (x * cosTheta - z * sinTheta);
node[2] = (int) (z * cosTheta + x * sinTheta);
}
};
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw edges
g.translate(150, 150);
rotateZ3D(60);
rotateY3D(60);
rotateX3D(60);
for (int e=0; e<12; e++) {
int n0 = edges[e][0];
int n1 = edges[e][1];
int node0[] = nodes[n0];
int node1[] = nodes[n1];
g.drawLine(node0[0], node0[1], node1[0], node1[1]);
}
// Draw nodes
for (int n=0; n<8; n++) {
int node[] = nodes[n];
g.drawOval(node[0], node[1], 5,5);
g.drawString(n+"", node[0], node[1]);
}
};
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
JFrame j = new JFrame();
Cube p = new Cube();
j.add(p);
j.addMouseMotionListener(p);
j.setSize(500,500);
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.show();
// TODO code application logic here
}
#Override
public void mouseDragged(MouseEvent me) {
int x0 = me.getX();
int y0 = me.getY();
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
Logger.getLogger(Cube.class.getName()).log(Level.SEVERE, null, ex);
}
int x1 = me.getX();
int y1 = me.getX();
rotateY3D(x1 - x0);
rotateX3D(y1 - y0);
repaint();
}
#Override
public void mouseMoved(MouseEvent me) {
}
}
suggest the solution code for it..
It's working fine , except that the cube is shrinking
You're storing the coordinates as ints.
Each time you do a rotation, you do a calculation which doesn't yield an integer; when you cast, you truncate the integer, rounding towards zero. Hence the shrinkage.
Use double instead, or, better, simply calculate a rotation matrix and apply that to the coordinates when you are rendering it.
I have this code in C from this source:
#import <Foundation/Foundation.h>
#import "OpenGLCommon.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableString *result = [NSMutableString string];
static const Vertex3D vertices[]= {
{0, -0.525731, 0.850651}, // vertices[0]
{0.850651, 0, 0.525731}, // vertices[1]
{0.850651, 0, -0.525731}, // vertices[2]
{-0.850651, 0, -0.525731}, // vertices[3]
{-0.850651, 0, 0.525731}, // vertices[4]
{-0.525731, 0.850651, 0}, // vertices[5]
{0.525731, 0.850651, 0}, // vertices[6]
{0.525731, -0.850651, 0}, // vertices[7]
{-0.525731, -0.850651, 0}, // vertices[8]
{0, -0.525731, -0.850651}, // vertices[9]
{0, 0.525731, -0.850651}, // vertices[10]
{0, 0.525731, 0.850651} // vertices[11]
};
static const GLubyte icosahedronFaces[] = {
1, 2, 6,
1, 7, 2,
3, 4, 5,
4, 3, 8,
6, 5, 11,
5, 6, 10,
9, 10, 2,
10, 9, 3,
7, 8, 9,
8, 7, 0,
11, 0, 1,
0, 11, 4,
6, 2, 10,
1, 6, 11,
3, 5, 10,
5, 4, 11,
2, 7, 9,
7, 1, 0,
3, 9, 8,
4, 8, 0,
};
Vector3D *surfaceNormals = calloc(20, sizeof(Vector3D));
// Calculate the surface normal for each triangle
for (int i = 0; i < 20; i++)
{
Vertex3D vertex1 = vertices[icosahedronFaces[(i*3)]];
Vertex3D vertex2 = vertices[icosahedronFaces[(i*3)+1]];
Vertex3D vertex3 = vertices[icosahedronFaces[(i*3)+2]];
Triangle3D triangle = Triangle3DMake(vertex1, vertex2, vertex3);
Vector3D surfaceNormal = Triangle3DCalculateSurfaceNormal(triangle);
Vector3DNormalize(&surfaceNormal);
surfaceNormals[i] = surfaceNormal;
}
Vertex3D *normals = calloc(12, sizeof(Vertex3D));
[result appendString:#"static const Vector3D normals[] = {\n"];
for (int i = 0; i < 12; i++)
{
int faceCount = 0;
for (int j = 0; j < 20; j++)
{
BOOL contains = NO;
for (int k = 0; k < 3; k++)
{
if (icosahedronFaces[(j * 3) + k] == i)
contains = YES;
}
if (contains)
{
faceCount++;
normals[i] = Vector3DAdd(normals[i], surfaceNormals[j]);
}
}
normals[i].x /= (GLfloat)faceCount;
normals[i].y /= (GLfloat)faceCount;
normals[i].z /= (GLfloat)faceCount;
[result appendFormat:#"\t{%f, %f, %f},\n", normals[i].x, normals[i].y, normals[i].z];
}
[result appendString:#"};\n"];
NSLog(result);
[pool drain];
return 0;
}
Can some one point me to Java code that does the same thing as above? I would also need to modify it so that it works not just for isohadron but for any vertex array with associated index array.
This works for any triangle based mesh.
for(int i = 0; i < indices.Length; i += 3)
{
Vector3 v0 = vertices[indicies[i]].Position;
Vector3 v1 = vertices[indicies[i+1]].Position;
Vector3 v2 = vertices[indicies[i+2]].Position;
Vector3 normal = Vector3.Normalize(Vector3.Cross(v2 - v0, v1 - v0));
vertices[indicies[i]].Normal += normal;
vertices[indicies[i+1]].Normal += normal;
vertices[indicies[i+2]].Normal += normal;
}
for(int i = 0; i < vertices.Length; i++)
{
vertices[i].Normal = Vector3.Normalize(vertices[i].Normal);
}
Heres a stripped down version of the Vector3 struct
public struct Vector3
{
float X, Y, Z;
public Vector3(float x, float y, float z)
{
X = x; Y = y; Z = z;
}
public static Vector3 Cross(Vector3 v1, Vector3 v2)
{
Vector3 result;
result.X = (v1.Y * v2.Z) - (v1.Z * v2.Y);
result.Y = (v1.Z * v2.X) - (v1.X * v2.Z);
result.Z = (v1.X * v2.Y) - (v1.Y * v2.X);
return result;
}
public static Vector3 Normalize(Vector3 v1)
{
float length = v1.X * v1.X + v1.Y * v1.Y + v1.Z * v1.Z;
length = Math.Sqrt(length);
v1.X /= length; v1.Y /= length; v1.Z /= length;
}
}
I hope that helps.