Function to inverse 3d point not working - java

Alright, I have Poin3d class that takes x y and z:
public class Point3d {
public double x, y, z;
public Point3d(double a, double b, double c){
x = a;
y = b;
z = c;
}
public Point3d inverse(){
System.out.println("XYZ: " + x + ", " + y + ", " + z);
return new Point3d(-x, -y, -z);
}
}
And I also have a class calling this function in one of its own functions, and prints the X,Y,Z of the original point, and the inverted point:
public Model mirror(boolean x, boolean y, boolean z){
init();
Point3d pos = getPosition();
System.out.println("Position: " + pos.x + ", " + pos.y + ", " + pos.z);
Point3d negPos = pos.inverse();
for(Line3d l : lines){
l.start.add(negPos);
l.end.add(negPos);
if(x){l.start.x*=-1;l.end.x*=-1;angleX = !angleX;}
if(y){l.start.y*=-1;l.end.y*=-1;angleY = !angleY;}
if(z){l.start.z*=-1;l.end.z*=-1;angleZ = !angleZ;}
l.start.add(pos);
l.end.add(pos);
}
System.out.println("Inverse: " + pos.x + ", " + pos.y + ", " + pos.z);
return this;
}
Just looking at the println's, here's the sort of results I'm getting:
Position: 500.0, 65.0, 725.0
XYZ: 500.0, 65.0, 725.0
Inverse: 500.0, 65.0, 725.0
Position: 500.0, 460.0, 500.0
XYZ: 500.0, 460.0, 500.0
Inverse: -3000.0, -920.0, -3000.0
Position: 500.0, 460.0, 500.0
XYZ: 500.0, 460.0, 500.0
Inverse: -3000.0, -920.0, -3000.0
So basically, why on earth is the inverse this seemingly random set of numbers rather than just the negatives of the original point? Where are -3000 and -920 coming from?
EDIT: So I messed around with the code a bit and found that, for the first few iterations of the for loop, each value(x, y, z) of pos is reduced by its initial value. Anyone know why?
Point3d.add():
public Point3d add(Point3d add){
x += add.x;
y += add.y;
z += add.z;
return this;
}

Related

Calculate Euclidean Distance Between Two Points Using Constructor

I'm working on an assignment to write a java program which implements a Point data type with the following constructor:
Point(double x, double y, double z)
and, the following API:
double distanceto(Point q)
it returns the Euclidean distance between this and q.
The Euclidean distance between (x1, y1, z1) and (x2, y2, z2) is defined as sqrt( (x1-x2)^2 + (y1-y2)^2) + (z1-z2)^2).
String toString() – it returns the string representation of the point. An example would be (2.3,4.5,3.0).
Write a main method in the class that is used to test it.
It should create two Point objects using input provided by the user on the command-line.
Then it should print out the two points followed by their Euclidean distance
A sample run would be as follows.
java Point 2.1 3.0 3.5 4 5.2 3.5
The first point is (2.1,3.0,3.5)
The second point is (4.0,5.2,3.5)
Their Euclidean distance is 2.90
The program won't compile, but I'm not sure why. I'm new to programming, so I followed some steps from online and Codecademy to try and access objects in the constructor, but I think I'm doing it wrong. Any suggestions would be greatly appreciated.
public class Point {
double x1;
double y1;
double z1;
double x2;
double y2;
double z2;
public Point(double x, double y, double z){
x1 = x;
y1 = y;
z1 = z;
x2 = x;
y2 = y;
z2 = z;
}
public double distanceTo(Point q){
return Math.sqrt(Math.pow((x1-x2), 2.0) + Math.pow((y1-y2), 2.0) + Math.pow((z1-z2), 2.0));
}
double x3 = x1-x2;
double y3 = y1-y2;
double z3 = z1-z2;
public String toString() {
return "(" + x3 + ", " + y3 + ", " + z3 + ")";
}
public static void main (String[]args){
Point pointOne = new Point(args[0]);
Point pointTwo = new Point(args[1]);
Point distance = new distanceTo();
System.out.println("The first point is " + "(" + pointOne + ")");
System.out.println("The second point is " + "(" + pointTwo + ")");
System.out.println("Their Euclidean distance is " + distance);
}
}
A couple of things:
First, you should only need one set of variables for your Point class. Just make one set and construct two point objects.
In the distanceTo() method, access the other point's coordinates by doing q.x1, q.y1, and so on.
In the main method, distance should be double that's pointOne's distance to pointTwo.
Here's the code that worked for me
class Point {
double x1;
double y1;
double z1;
public Point(double x, double y, double z){
//each point object only needs one x, y and z
x1 = x;
y1 = y;
z1 = z;
}
public double distanceTo(Point pointTwo){
return Math.sqrt(Math.pow(pointTwo.x1-x1, 2.0) + Math.pow(pointTwo.y1-y1, 2.0) + Math.pow(pointTwo.z1-z1, 2.0));
//formula is sqrt((p2.x-p1)^2 + (p2.y-p1.y)^2 + (p2.z - p1.z)^2
}
public String toString() {
return "(" + x1 + ", " + y1 + ", " + z1 + ")";
//we don't need a diff set of variables here
}
public static void main (String[]args){
//make two diff points with coords
Point pointOne = new Point(2.1, 3.0, 3.5);
Point pointTwo = new Point(4.0,5.2, 3.5);
double distance = pointOne.distanceTo(pointTwo);
//uses point two as the parameter (x2, y2, z2 in formula)
System.out.println("The first point is " + "(" + pointOne + ")");
System.out.println("The second point is " + "(" + pointTwo + ")");
System.out.println("Their Euclidean distance is " + distance);
}
}

Attempting to return a float[] from a method in Java

I'm writing a game and working on collisions. Currently, I'm trying to use the tileCollision function to return a 1-dimensional array containing 2 numbers; the coordinates of the corner. (represented in the program by cX and cY)
I expected this to run smoothly: that is, to return {-999, -999} if it wasn't colliding, and to return a valid set of coordinates otherwise. Unfortunately, IntelliJ tells me that the goodCX and goodCY variables "might not have been initialised" which I do not know how to solve. Running the program gives me the same error.
The Tile class can be treated as a class containing an X value, a Y value, and a texture. The t.texture.width & t.texture.height should be set to 50 to make it simpler to understand. Entity can be assumed as a class containing variables named x, y, vx, vy, and a "texture" whose dimensions should be 20x20. I use Java with the Processing 3 library to render my code and am happy to provide extra info if needed.
The main problem is less with those rather than the "might not have been initialised" problem, though.
Please, go easy on me, and if possible, don't use anything wildly outside the realm of what is demonstrated in my code. I am an amateur programmer, and while I have been programming for a while, am not exactly professional.
Here's my code:
public float[] tileCollision(Tile t)
{
boolean isCollide = false;
float tX = t.eX;
float tX2 = t.eX + t.texture.width;
float tY = t.eY;
float tY2 = t.eY + t.texture.height;
float[] cX = new float[]{this.x + this.vx, this.x + this.texture.width + this.vx};
float[] cY = new float[]{this.y + this.vy, this.y + this.texture.height + this.vy};
float[] bad = new float[]{-999, -999};
float goodCX, goodCY;
System.out.println("\nCollisions Testing Names:");
System.out.println(this);
System.out.println(t);
for(int i = 0; i < 2; i ++)
{
for(int i_ = 0; i_ < 2; i_ ++)
{
System.out.println("\nCollisions Testing:");
System.out.println("Entity X: " + cX[i]);
System.out.println("Entity Y: " + cY[i_]);
System.out.println("Tile Xs: " + tX + ", " + tX2);
System.out.println("Tile Ys: " + tY + ", " + tY2);
if( ( (tX <= cX[i]) && (cX[i] <= tX2) ) && ( (tY <= cY[i_]) && (cY[i_] <= tY2) ) )
{
isCollide = true;
goodCX = cX[i];
goodCY = cY[i_];
}
}
}
System.out.println("Am I colliding?\n>>> " + isCollide);
if(isCollide)
{
return new float[]{goodCX, goodCY};
}
else { return(bad); }
}
The problem resides in the fact that you only assign (and first-assign, and hence, initialize) your goodCX and goodCY variables inside a complex if nested inside your for loops. Then, if(isCollide), you will attempt to return them, but there is no way the compiler can infer any kind of connection between the complex if condition you have, and the isCollide condition, so you may be returning unassigned references.
To resolve this, simply make a default initialization of your float references at the top, as follows:
float goodCX = 0.0;
float goodCY = 0.0;
If the collision check do not evaluate true GoodCX and GoodCY will never be initialized. You will have problems trying to return "new float[]{goodCX, goodCY}". Try initializing your GoodCX and GoodCY with -999. You will also be able to simplify your code with that:
public float[] tileCollision(Tile t)
{
boolean isCollide = false;
float tX = t.eX;
float tX2 = t.eX + t.texture.width;
float tY = t.eY;
float tY2 = t.eY + t.texture.height;
float[] cX = new float[]{this.x + this.vx, this.x + this.texture.width + this.vx};
float[] cY = new float[]{this.y + this.vy, this.y + this.texture.height + this.vy};
float goodCX = -999;
float goodCY = -999;
System.out.println("\nCollisions Testing Names:");
System.out.println(this);
System.out.println(t);
for(int i = 0; i < 2; i ++)
{
for(int i_ = 0; i_ < 2; i_ ++)
{
System.out.println("\nCollisions Testing:");
System.out.println("Entity X: " + cX[i]);
System.out.println("Entity Y: " + cY[i_]);
System.out.println("Tile Xs: " + tX + ", " + tX2);
System.out.println("Tile Ys: " + tY + ", " + tY2);
if( ( (tX <= cX[i]) && (cX[i] <= tX2) ) && ( (tY <= cY[i_]) && (cY[i_] <= tY2) ) )
{
goodCX = cX[i];
goodCY = cY[i_];
}
}
}
return new float[]{goodCX, goodCY};
}
Intellij is giving you that response because the variables are declared but not initialized. You need to define them with some default state or modify the code that follows to ensure they're initialized.

Is it possible to display double with larger precision than a float via String Formatter?

How can I keep precision when working with doubles in Java? I have the following test case:
double x = -1.0 / 3.0;
double y = 1.0000000001;
Point2 p = new Point2(x, y);
String expected = "(" + x + ", " + y + ")";
assertEquals(expected, p.toString());
Point2 constructor:
public Point2(double x, double y) {
this.x = x;
this.y = y;
}
toString Override:
#Override
public String toString() {
return String.format("(%f, %f)", this.x, this.y);
}
Which is failing: org.junit.ComparisonFailure: expected:<(-0.333333[3333333333, 1.0000000001])> but was:<(-0.333333[, 1.000000])>
Problem was in my toString() method. Makes sense that they were being formatted as floats now. Ended up updated it to :
#Override
public String toString() {
return "(" + this.x + ", " + this.y + ")";
}

fixing errors on a program to call methods in java

The following program contains 9 errors. Correct the errors and submit a working version of the program. The corrected version of the program should produce the following output:
x = 10.01 and y = 8.0
x = 10.01 and y = 867.5309
The value from main is: 867.5309
z = 5
I have already made some changes on this, but I can figure out why x and y aren't being called.
public class Oops3 {
public static void main(String[] args) {
double y = 867.5309;
double x = 10.01;
printer(double x, double y);
printer(x);
printer(y);
System.out.println("z = " + z);
}
public static void printer(double x, double y) {
int z = 5;
System.out.println("x = " + double x + " and y = " + double y);
System.out.println("The value from main is: " + y);
}
}
Try this: (not sure how many changes you have already made)
public class Oops3 {
public static void printer(double x, double y) {
System.out.println("x = " + x + " and y = " + y);
System.out.println("The value from main is: " + y);}
public static void main(String[] args) {
int z = 5;
double y = 867.5309;
double x = 10.01;
System.out.println("x= " + x + " and y = 8.0");
printer( x,y);
System.out.println("z = " + z);
}}
The following is the working code you are looking for
public class Oops3
{
public static void printer(double x, double y, int z) {
System.out.println("x = " + x + " and y = " + y);
System.out.println("The value from main is: " + y);
System.out.println("z = " + z);
}
public static void main(String[] args) {
Oops3 O=new Oops3();
double y = 867.5309;
double x = 10.01;
int z = 5;
O.printer(x, y, z);
}
}
This code worked for me
public class Oops3 {
public static void main(String [] args) {
Oops3 i = new Oops3();
double bubble = 867.5309;
double x = 10.01;
double y = 8.0;
int z = 5;
i.printer(x, y);
i.printer(x, bubble);
System.out.println("The value from main is: " + bubble);
System.out.println("z = " + z);
}
public static void printer(double x, double y) {
System.out.println("x = " + x + " and y = " + y);
}
}

LWJGL Ray Picking (gluUnProject)

So I have been looking through tutorials (And questions on this site) and have found nothing to solve my problem. Here is the current code I am trying to implement:
private void pick() {
float[] matModelView = new float[16], matProjView = new float[16];
int[] view = new int[16];
float mouseX = width / 2;
float mouseY = height / 2;
Vector3f start = new Vector3f();
Vector3f end = new Vector3f();
FloatBuffer modelBuffer = compileBuffer(matModelView);
FloatBuffer projBuffer = compileBuffer(matProjView);
FloatBuffer startBuffer = compileBuffer(new float[]{start.x, start.y, start.z, 1});
FloatBuffer endBuffer = compileBuffer(new float[]{end.x, end.y, end.z, 1});
IntBuffer viewBuffer = compileBuffer(view);
glGetFloat(GL_MODELVIEW_MATRIX, modelBuffer);
glGetFloat(GL_PROJECTION_MATRIX, projBuffer);
glGetInteger(GL_VIEWPORT, viewBuffer);
gluUnProject(mouseX, mouseY, 0.0f, modelBuffer, projBuffer, viewBuffer, startBuffer);
gluUnProject(mouseX, mouseX, 1.0f, modelBuffer, projBuffer, viewBuffer, endBuffer);
start = new Vector3f(startBuffer.get(0), startBuffer.get(1), startBuffer.get(2));
end = new Vector3f(endBuffer.get(0), endBuffer.get(1), endBuffer.get(2));
picks.add(new Vector3f[]{start, end});
System.out.println("Mouse Coords: " + mouseX + ", " + mouseY);
System.out.println("Position: " + position.x + ", " + position.y + ", " + position.z);
System.out.println("Rotation: " + rotation.x + ", " + rotation.y + ", " + rotation.z);
System.out.println("Near Plane: " + start.x + ", " + start.y + ", " + start.z);
System.out.println("Far Plane: " + end.x + ", " + end.y + ", " + end.z);
}
I have the mouseX and Y set the way I do because my mouse is grabbed. Here is an image and some output for you. (I can't really explain the problem)
Mouse Coords: 400.0, 350.0
Position: 0.0, 0.0, 0.0
Rotation: 0.0, 0.0, 0.0
Near Plane: 0.0, 0.0, -0.1
Far Plane: 0.0, 4.2315264, -99.99771
So, for a rotation of X:0 Y:0 Z:0, the expected output of the Y coord should be the same as the input. It is higher. Here is a picture of that output.
Can anyone give me some kind of hint or explanation on why this would happen?
EDIT: Facepalms violently: I was pushing mouseX in the Y parameter of the second gluUnProject

Categories

Resources