This is a class i made after looking for some fine looking ray-box collision in 3d code and not finding any.
Or just some 2d code that could be nicely extended to 3d, but i don’t really like Tmin and Tmax.
So far it looks foolproof to me. Please report bugs to me in PM after you’ve verified they’re not yours.
Yes I’m guilty of testing all six faces. It doesn’t care how long the ray is just whether if extended long enough that it would hit the boundaries and will accurately return the hit position even when the origin is inside the bounds. No need to normalize any rays. The hit position isn’t relative to anything and the test return type is boolean.
Here’s an example in use:
RlPWjK_BoTQ
Overall it’s used like this:
Boxen box=new Boxen(4,6,8,5,10,0);//(4,6,8) is pointA. (5,10,0) is pointB. They only have to be opposite corners.
box.pointA(0,0,0);//you can change the corners
box.pointB(-1,-1,-1);//at any time to any size
if(box.test(0,0,0,6,2,5)){//(0,0,0) is ray origin. (6,2,5) is ray direction.
distance(0,0,0,box.getx(),box.gety(),box.getz())//doing something with the hit point x,y,z
}
Finally the bacon
public class Boxen{
double ax,ay,az;double x0,y0,z0;double x1,y1,z1;
public Boxen(double x,double y,double z,double a,double b,double c){
x0=x;y0=y;z0=z;x1=a;y1=b;z1=c;
}
public void pointA(double x,double y,double z){x0=x;y0=y;z0=z;}
public void pointB(double x,double y,double z){x1=x;y1=y;z1=z;}
public boolean test(double a,double b,double c,double x,double y,double z){
double x0=this.x0-a,y0=this.y0-b,z0=this.z0-c,x1=this.x1-a,y1=this.y1-b,z1=this.z1-c,
Adx,Ady,Adz,var,xx=Double.MAX_VALUE,tt;boolean hit=false;x-=a;y-=b;z-=c;//.000000000000002 the original difference
if(x0*x>0){
var=x0/x;Adx=x*var;Ady=y*var;Adz=z*var;
if(((Adz<z0&&Adz>z1)||(Adz>z0&&Adz<z1))&&((Ady<y0&&Ady>y1)||(Ady>y0&&Ady<y1))){
tt=sdist(Adx,Ady,Adz);if(tt<xx){xx=tt;ax=Adx+a;ay=Ady+b;az=Adz+c;hit=true;}
}
}
if(x1*x>0){
var=x1/x;Adx=x*var;Ady=y*var;Adz=z*var;
if(((Adz<z0&&Adz>z1)||(Adz>z0&&Adz<z1))&&((Ady<y0&&Ady>y1)||(Ady>y0&&Ady<y1))){
tt=sdist(Adx,Ady,Adz);if(tt<xx){xx=tt;ax=Adx+a;ay=Ady+b;az=Adz+c;hit=true;}
}
}
if(z0*z>0){
var=z0/z;Adx=x*var;Ady=y*var;Adz=z*var;
if(((Adx<x0&&Adx>x1)||(Adx>x0&&Adx<x1))&&((Ady<y0&&Ady>y1)||(Ady>y0&&Ady<y1))){
tt=sdist(Adx,Ady,Adz);if(tt<xx){xx=tt;ax=Adx+a;ay=Ady+b;az=Adz+c;hit=true;}
}
}
if(z1*z>0){
var=z1/z;Adx=x*var;Ady=y*var;Adz=z*var;
if(((Adx<x0&&Adx>x1)||(Adx>x0&&Adx<x1))&&((Ady<y0&&Ady>y1)||(Ady>y0&&Ady<y1))){
tt=sdist(Adx,Ady,Adz);if(tt<xx){xx=tt;ax=Adx+a;ay=Ady+b;az=Adz+c;hit=true;}
}
}
if(y0*y>0){
var=y0/y;Adx=x*var;Ady=y*var;Adz=z*var;
if(((Adx<x0&&Adx>x1)||(Adx>x0&&Adx<x1))&&((Adz<z0&&Adz>z1)||(Adz>z0&&Adz<z1))){
tt=sdist(Adx,Ady,Adz);if(tt<xx){xx=tt;ax=Adx+a;ay=Ady+b;az=Adz+c;hit=true;}
}
}
if(y1*y>0){
var=y1/y;Adx=x*var;Ady=y*var;Adz=z*var;
if(((Adx<x0&&Adx>x1)||(Adx>x0&&Adx<x1))&&((Adz<z0&&Adz>z1)||(Adz>z0&&Adz<z1))){
tt=sdist(Adx,Ady,Adz);if(tt<xx){xx=tt;ax=Adx+a;ay=Ady+b;az=Adz+c;hit=true;}
}
}
return hit;
}
private static double sdist(double x1,double y1,double z1){return StrictMath.sqrt(Math.pow(x1,2)+Math.pow(y1,2)+Math.pow(z1,2));}
public double getx(){return ax;}public double gety(){return ay;}public double getz(){return az;}
}