I've made a few classes in Java, the ones that seem to relate to this are:
Line3d, a line in 3d space:
package com.funguscow.obj;
public class Line3d {
public Point3d start, end;
public Line3d(int a, int b, int c, int x, int y, int z){
start = new Point3d(a, b, c);
end = new Point3d(x, y, z);
}
public Line3d(Point3d s, Point3d e){
start = s;
end = e;
}
public Line3d scale(float f){
start.x *= f;
start.y *= f;
start.z *= f;
end.x *= f;
end.y *= f;
end.z *= f;
return this;
}
public Line3d translate(float x, float y, float z){
return translate(new Point3d(x, y, z));
}
public Line3d translate(Point3d p){
start.add(p);
end.add(p);
return this;
}
}
Cube, which contains 12 Line3d's, forming a cube:
package com.funguscow.model;
import com.funguscow.obj.Line3d;
import com.funguscow.obj.Point3d;
public class Cube extends Model{
public Cube(float s){
super(s);
init();
}
public void init(){
super.init();
lines.clear();
Point3d a = new Point3d(scale, scale, scale).add(position),
b = new Point3d(scale, scale, -scale).add(position),
c = new Point3d(scale, -scale, scale).add(position),
d = new Point3d(scale, -scale, -scale).add(position),
e = new Point3d(-scale, scale, scale).add(position),
f = new Point3d(-scale, scale, -scale).add(position),
g = new Point3d(-scale, -scale, scale).add(position),
h = new Point3d(-scale, -scale, -scale).add(position);
addLine(a, b);
addLine(a, c);
addLine(a, e);
addLine(b, d);
addLine(b, f);
addLine(c, d);
addLine(c, g);
addLine(d, h);
addLine(e, f);
addLine(e, g);
addLine(f, h);
addLine(g, h);
}
public Point3d getPosition(){
return Point3d.average(lines.get(0).start, lines.get(11).end);
}
}
CubeCollider, extending Collider(an abstract class), that looks like the following:
package com.funguscow.model;
import com.funguscow.obj.Point3d;
import com.funguscow.obj.Vector3d;
public class CubeCollider extends Collider{
public Point3d a, b, c, d, e, f, g, h;
public CubeCollider setCube(Cube cube){
return setCube((float)cube.lines.get(0).start.x,
(float)cube.lines.get(0).start.y, (float)cube.lines.get(0).start.z,
(float)cube.lines.get(11).end.x, (float)cube.lines.get(11).end.y, (float)cube.lines.get(11).end.z);
}
public CubeCollider setCube(float x, float y, float z, float m, float n, float o){
a.x = b.x = c.x = d.x = x;
e.x = f.x = g.x = h.x = m;
a.y = c.y = e.y = g.y = y;
b.y = d.y = f.y = h.y = n;
a.z = b.z = e.z = f.z = z;
c.z = d.z = g.z = h.z = o;
return this;
}
}
And TestCube, which extends another abstract class, Complex, containing two ArrayLists, one of Model(which Cube extends), and one of Collider(which CubeCollider exends):
package com.funguscow.model;
public class TestCube extends Complex{
public TestCube(){
super();
Cube c = (Cube) new Cube(100).position(100, 100, 40).setColor(0x00ffff);
c.init();
parts.add(c);
halts.add(new CubeCollider().setCube((Cube)c));
}
}
When I run it I get the following NullPointerException, pointing to the SetCube function in CubeCollider:
Exception in thread "main" java.lang.NullPointerException
at com.funguscow.model.CubeCollider.setCube(CubeCollider.java:16)
at com.funguscow.model.CubeCollider.setCube(CubeCollider.java:10)
at com.funguscow.model.TestCube.<init>(TestCube.java:10)
at com.funguscow.world.World.init(World.java:33)
at com.funguscow.world.World.<init>(World.java:24)
at com.funguscow.game.Game.<init>(Game.java:40)
at com.funguscow.game.Main.main(Main.java:20)
I can't figure out why on earth I'd be getting a NullPointerException there, I can't see why there'd be anything that's not initialized, but there's clearly some problem.
public Point3d a, b, c, d, e, f, g, h;
You don't initialize these Point3d members of the CubeCollider class, and you try to access them in setCube, causing NullPointerException.
This should work :
public CubeCollider setCube(float x, float y, float z, float m, float n, float o){
a = new Point3D(x,y,z);
b = new Point3D(x,n,z);
c = new Point3D(x,y,o);
...
return this;
}
When you see that you are getting a NullPointerException, the right thing to do is to look at the StackTrace (Your error message) and it will tell exactly what got called when. In this case, the line that caused the error was CubeCollider.setCube(CubeCollider.java:16)
Related
This question already has answers here:
Non-static method requires a target
(8 answers)
Closed 6 years ago.
I have 3 classes: Point, Polygon and ClientePolygon. Point creates an object, Point(double x, double y) with many nonstatic methods. Polygon creates an array of Point with non-static methods, i.e., write, move, and return the Point closest to the origin in the array. ClientePolygon executes Polygon. The problem is that when I run ClientePolygon it gives me Point class executed... and I want to run Polygon. Any suggestions? Thanks a lot.
ClientePolygon:
package k;
public class ClientePolygon {
public void main(String [] args){
Point origem = new Point (0,0);
Point [] vertices = new Point[4];
vertices[0] = new Point (1.0,1.0);
vertices[1] = new Point (1.0,5.0);
vertices[2] = new Point (2.0,5.0);
vertices[3] = new Point (2.0,1.0);
for (int i = 0; i < vertices.length; i++) {
vertices[i].translate(5.0,7.5);
}
}
}
Point:
package k;
public class Point {
private double x;
private double y;
public Point(double x, double y){
this.x = x;
this.y = y;
}
public double getX(){
return x;
}
public String toString(){
return "("+ this.x+", "+this.y+")";
}
public Point copy(){
Point copia = new Point(x, y);
return copia;
}
public static double distance(Point ponto1, Point ponto2){
double distX = ponto1.x + ponto2.x;
double distY = ponto1.y + ponto2.y;
return Math.sqrt(distX*distX + distY*distY);
}
public void translate(double dx, double dy){
double transX = this.x + dx;
double transY = this.y + dy;
System.out.println(toString()+" fica "+ transX +" e "+ transY);
}
public static void main(String[] args) {
Point ponto1 = new Point(2,1);
Point ponto2 = new Point(3,9);
System.out.println(ponto1.toString());
System.out.println(ponto2.toString());
System.out.println("A distancia entre os pontos eh: " +distance(ponto1, ponto2));
System.out.println("O ponto copiado eh: "+ponto2.copy());
ponto2.copy().translate(2, 3);
}
}
Polygon:
package k;
public class Polygon {
private Point [] vertices;
public Polygon(Point [] vertices){
this.vertices = vertices;
}
public String toString(){
return "Ponto 1 em: "+vertices;
}
public Point closestToOrigin(){
Point proximo = new Point(0, 0);
Point origem = new Point(0,0);
for (int i = 0; i < vertices.length; i++) {
double distancia = Point.distance(vertices[i], origem);
if(distancia<Point.distance(vertices[i-1], origem)){
proximo = vertices[i];
}
}
return proximo;
}
public void translate(double dx, double dy){
Point Trans = new Point(dx, dy);
System.out.println("Ponto 1 fica: "+vertices[0]+Trans+", Ponto 2 fica: "+vertices[1]+Trans+" e Ponto 3 fica: "+vertices[2]+Trans);
}
}
To call a nonstatic method you need to instantiate the other class by doing
Class object = new Class(parameters);
and then call the method on that object:
object.method();
You must instantiate the Polygon class before calling a nonstatic method:
Polygon poly = new Polygon(vertices);
Then you can do:
poly.translate(5.0,7.5);
Alright so I have created 2 methods called Point and LineSegment (they both work).
Point is this:
public class Point {
private double x;
private double y;
public Point(){
x=0;
y=0;
}
public Point(double a, double b){
x=a;
y=b;
}
public double getY(){
return y;
}
public double getX(){
return x;
}
public void setX(double newX){
x= newX;
}
public void sety(double newY){
y= newY;
}
public void setXY(double newX, double newY){
x = newX;
y = newY;
}
public String toString(){
return "("+x+" , "+y+")";
}
}
LineSegment is this :
public class LineSegment {
private Point A;
private Point B;
public LineSegment (){
A = new Point();
B = new Point();
}
public LineSegment (int x1, int y1, int x2, int y2){
A = new Point(x1, y1);
B = new Point(x2, y2);
}
public LineSegment(Point P, Point Q){
A = new Point(P.getX(), P.getY());
B = new Point(Q.getX(), Q.getY());
}
public double Length(){
double length = Math.sqrt(Math.pow( (B.getX() - A.getX()), 2) + Math.pow((B.getY() - A.getY()),2));
return length;
}
public double Slope(){
double slope = (B.getY() - A.getY() )/ (B.getX() - A.getX());
return slope;
}
public String toString(){
return "("+A.getX()+" , "+A.getY()+") + ("+B.getX()+" , "+B.getY()+") ";
}
}
As I said both of these codes work but now my task is to use Linesegment to create 2 line segments called AB and CD, and to output the slope of both of them, I am not sure how to do this, can anybody help?
They are called classes, not methods.
And you've already made class instances in your LineSegment class at
A = new Point();
B = new Point();
So now, in some other class,
public static void main(String[] args) {
Point A = new Point();
Point B = new Point();
Point C = new Point();
Point D = new Point();
LineSegment AB = new LineSegment(A, B);
LineSegment CD = new LineSegment(C, D);
// output the slope
System.out.println(AB.Slope());
}
Also, note that your Slope method will return a divide-by-zero error if you run this code as-is.
Create a class, regardless of its name, and put the main method.
The method called main is essentially your starting point, where your code will start running.
public static void main(String[]args){
LineSegment segment1 = new LineSegment(1,2,3,4);
LineSegment segment2 = new LineSegment(5,6,7,8);
System.out.println("The first slope is: " + segment1.Slope());
System.out.println("The second slope is: " + segment2.Slope());
}
What do I do wrong? I get incorrect results (coordinates).
A triangle (see the picture below: blue is the original triangle, lime is the rotated one: a clone. Edge A is a fixed point).
The classes I use:
A Point class:
public class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
#Override
public String toString() {
return "[(" + x + ") (" + y + ")]";
}
}
An abstract Object2D class:
public abstract class Object2D {
Point[] point;
public Point getPoint(int i) {
return point[i];
}
public double getLowestX() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getX)
.min().getAsDouble();
}
public double getHighestX() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getX)
.max().getAsDouble();
}
public double getLowestY() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getY)
.min().getAsDouble();
}
public double getHighestY() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getY)
.max().getAsDouble();
}
public double getLength() {
return getSide(getLowestX(), getHighestX());
}
public double getHeight() {
return getSide(getLowestY(), getHighestY());
}
private double getSide(double v1, double v2) {
return (v1 < v2) ? (0 - v1) + v2 : (0 - v2) + v1;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Point pt : point) sb.append(pt).append("\n");
return sb.toString();
}
}
A Line class:
public class Line extends Object2D {
public Line(Point point0, Point point1) {
point = new Point[2];
point[0] = point0;
point[1] = point1;
}
public double getLineLength() {
return Math.sqrt(Math.pow(getLength(), 2) + Math.pow(getHeight(), 2));
}
}
My Triangle class:
public class Triangle extends Object2D {
public Triangle(Point point0, Point point1, Point point2) {
point = new Point[3];
point[0] = point0;
point[1] = point1;
point[2] = point2;
}
public static Triangle getRotatedTriangle(Triangle triangle) {
Point point0 = triangle.getPoint(0);
Point point1 = triangle.getPoint(1);
Point point2 = triangle.getPoint(2);
Line baseLine = new Line(point0, point1);
double rotationHeight = baseLine.getHeight();
double baseLength = baseLine.getLineLength();
double sinA = rotationHeight / baseLength;
double angle = Math.asin(sinA);
double cosA = Math.cos(angle);
point1 = new Point(
(point1.getX() * cosA - point1.getY() * sinA),
(point1.getX() * sinA + point1.getY() * cosA));
point2 = new Point(
(point2.getX() * cosA - point2.getY() * sinA),
(point2.getX() * sinA + point2.getY() * cosA));
return new Triangle(point0, point1, point2);
}
}
And, of course, my main class:
public class TestDrive {
public static void main(String[] args) {
Triangle triangle = new Triangle (
new Point(-6.5, -1.5),
new Point(2.5, 7.5),
new Point(6.5, -5.5)
);
System.out.println(triangle);
System.out.println(Triangle.getRotatedTriangle(triangle));
}
}
You made 2 mistakes in your code:
You are trying to rotate with the angle α when you should be rotating with the angle -α (since you are rotating clockwise).
Your multiplication matrix is incorrect: your code will perform a rotation around the origin of the XY plane instead of rotating around the point A. For the point (x, y) rotated by the rotation matrix R around the center (a, b), the correct formula for the new rotated point (x', y') would be (x', y') = R * (x - a, y - b) + (a, b).
This should be enough for you to correct your code. As reference, here's the solution I get for the rotated triangle:
[(-6.5) (-1.5)]
[(6.227922061357855) (-1.5000000000000009)]
[(-0.1360389693210724) (-13.520815280171309)]
I wrote this Java class for doing rotational transforms about the x,y,z axes.
public class Coord {
private double x,y,z;
public Coord(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public Coord M(Coord[] M) {
return new Coord(
x*M[0].x + y*M[0].y + z*M[0].z,
x*M[1].x + y*M[1].y + z*M[1].z,
x*M[2].x + y*M[2].y + z*M[2].z);
}
public Coord xR(double theta) {
double s = Math.sin(theta);
double c = Math.cos(theta);
return M(new Coord[]{V(1,0,0), V(0,c,-s), V(0,s,c)});
}
public Coord yR(double theta) {
double s = Math.sin(theta);
double c = Math.cos(theta);
return M(new Coord[]{V(c,0,s), V(0,1,0), V(-s,0,c)});
}
public Coord zR(double theta) {
double s = Math.sin(theta);
double c = Math.cos(theta);
return M(new Coord[]{V(c,-s,0), V(s,c,0), V(0,0,1)});
}
public Coord V(double x, double y, double z) {
return new Coord(x,y,z);
}
}
It transforms a x,y,z coordinate, as given by the class Coord, to a new coord by the matrix multiplication M. It works OK, such as Coord c = new Coord(1,1,0).xR(0.1);, try System.out.printf("%f,%f,%f", c.x, c.y, c.z); will show a small rotation (theta=0.1 radians) about x, while keeping x constant.
Anyway, I want to know if there's any way of getting rid of all the Math.sin, Math.cos while still maintaining readability (preferably) - but just getting rid of them would be good!. They are annoying to look at, and, seem to be asking to be reduced somehow
As per Paul's comment, turns out to be pretty good
import static java.lang.Math.sin;
import static java.lang.Math.cos;
public class Coord {
private double x,y,z;
public Coord(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public Coord M(Coord[] M) {
return new Coord(
x*M[0].x + y*M[0].y + z*M[0].z,
x*M[1].x + y*M[1].y + z*M[1].z,
x*M[2].x + y*M[2].y + z*M[2].z);
}
public Coord xR(double t) {
return M(new Coord[]{V(1,0,0), V(0,cos(t),-sin(t)), V(0,sin(t),cos(t))});
}
public Coord yR(double t) {
return M(new Coord[]{V(cos(t),0,sin(t)), V(0,1,0), V(-sin(t),0,cos(t))});
}
public Coord zR(double t) {
return M(new Coord[]{V(cos(t),-sin(t),0), V(sin(t),cos(t),0), V(0,0,1)});
}
public Coord V(double x, double y, double z) {
return new Coord(x,y,z);
}
}
Answering my own Q .. happy to know of other ways, looks pretty syntax bare now though .... I think I can live with this
I am in pursuit of a lightning fast java method to check if a point is inside a triangle.
I found the following c++ code in a paper from Kasper Fauerby:
typedef unsigned int uint32;
#define in(a) ((uint32&) a)
bool checkPointInTriangle(const VECTOR& point, const VECTOR& pa,const VECTOR& pb, const VECTOR& pc) {
VECTOR e10=pb-pa;
VECTOR e20=pc-pa;
float a = e10.dot(e10);
float b = e10.dot(e20);
float c = e20.dot(e20);
float ac_bb=(a*c)-(b*b);
VECTOR vp(point.x-pa.x, point.y-pa.y, point.z-pa.z);
float d = vp.dot(e10);
float e = vp.dot(e20);
float x = (d*c)-(e*b);
float y = (e*a)-(d*b);
float z = x+y-ac_bb;
return (( in(z)& ~(in(x)|in(y)) ) & 0x80000000);
}
I was wondering if this code snippet could be converted to java, and if so, if it would outperform my Java code:
public class Util {
public static boolean checkPointInTriangle(Vector p1, Vector p2, Vector p3, Vector point) {
float angles = 0;
Vector v1 = Vector.min(point, p1); v1.normalize();
Vector v2 = Vector.min(point, p2); v2.normalize();
Vector v3 = Vector.min(point, p3); v3.normalize();
angles += Math.acos(Vector.dot(v1, v2));
angles += Math.acos(Vector.dot(v2, v3));
angles += Math.acos(Vector.dot(v3, v1));
return (Math.abs(angles - 2*Math.PI) <= 0.005);
}
public static void main(String [] args) {
Vector p1 = new Vector(4.5f, 0, 0);
Vector p2 = new Vector(0, -9f, 0);
Vector p3 = new Vector(0, 0, 4.5f);
Vector point = new Vector(2, -4, 0.5f);
System.out.println(checkPointInTriangle(p1, p2, p3, point));
}
}
and the Vector class:
public class Vector {
public float x, y, z;
public Vector(float x, float y, float z) {
this.x = x; this.y = y; this.z = z;
}
public float length() {
return (float) Math.sqrt(x*x + y*y + z*z);
}
public void normalize() {
float l = length(); x /= l; y /= l; z /= l;
}
public static float dot(Vector one, Vector two) {
return one.x*two.x + one.y*two.y + one.z*two.z;
}
public static Vector min(Vector one, Vector two) {
return new Vector(one.x-two.x, one.y-two.y, one.z-two.z);
}
}
or is there an even faster method for Java?
Thanks in advance!
The code you've found, if correct, should be quite a bit faster than what you've got. The return statement
return (( in(z)& ~(in(x)|in(y)) ) & 0x80000000);
is just a tricky way of checking the sign bit of the floating point numbers; if I'm not completely wrong it's equivalent to:
return z < 0 && x >= 0 && y >= 0;
The text of the paper should confirm this. The rest I would guess you can convert yourself.