Ray Casting (Well, kind of...)

So I’ve made a voxel engine (runs quite well!!!). However I am currently using a 2d line on the x and z axis to select blocks:

double px=camera.X()-sin((camera.YR()+180.0)/(180.0/3.14))*dis;
double pz=camera.Z()+cos((camera.YR()+180.0)/(180.0/3.14))*dis;

This works fine, however I’m not quite sure how to do this with a 3d line. Pretty much I just need to check a few 3d points along a 3d line to see if there is a block in that position. The last math class I took was pre-calculus, and I do not think I remember dealing with cos() and sin() much (except for circles/ovals, which is how I know how to calculate points on a 2d plane). I’ve been googling a lot of different things, but I haven’t come up with a solution as of yet. I see a lot of ray casting tutorials out there, but they aren’t what I need (or at least I do not think so). I’m assuming there is a bunch of different ways of doing this, but I’m just not sure where to start!

Something like this ?

http://www.presence-pc.com/tests/rendu-raycasting-voxels-23160/
(it’s a french link but you can certainly find an english version of this somewhere in the Net)

Although it has some interesting points and theories, I didn’t see anything for calculating a point in 3d space. I’m looking for something like:


class vec3d
{
     public:
          vec3d(const double x,const double y,const double z):
               _x(x),_y(y),_z(z){}

          double X() const
          {
               return _x;
          }

          double Y() const
          {
               return _y;
          }

          double Z() const
          {
               return _z;
          }

     private:
          double _x;
          double _y;
          double _z;
};

vec3d getPointFromDirection(const vec3d pos,const vec3d dir,const double dis)
{
     return vec3d(/*calc the 3d point relative to 
     position pos in direction dir at a distance of dis*/);
}

I’m sure someone has used something like this before, shooting seems to be a good use for this…

vec3 result = pos + dir*dist;

When you say dir do you mean some kind of equation with sin/cos? I’m just not seeing how multiplying the direction by the distance would give the desired result. Lets say the distance is 1 (just to make things easy), the starting position vector (10,15,20), and the direction vector is (0,90,0). Then the return vector would be:
(10+01,15+901,20+0*1)=(10,105,20)

Which is obviously not what was wanted. Now if it was in radians it would be (10,57.3,20). So being it more than likely has something to do with cos and sin, I’m going to go on a limb and say your only going to need two directions (because on a two dimensional plane you only need one instead of two). In this case Y and Z. So maybe something like:

double x=pos.X()-(cos(dir.X()/(180.0/3.14))*sin(dir.Y()/(180.0/3.14))*dis);
double y=pos.Y()-(sin(dir.X()/(180.0/3.14))*dis);
double z=pos.Z()+(cos(dir.Y()/(180.0/3.14))*dis);

I can’t test this at the moment, since I do not have current access to a compiler, but I’ll check later tonight, I’m pretty sure I have something wrong in there…

EDIT:
Alright I got it working, I fixed it above.

If your direction vector is not unit length, you must normalize it first. “result = pos + dir * dist” requires that dir is normalized.

I’m not quite sure I understand what normalization is, or how to do it. Can you show me an example of what you mean? When I spawn blocks it does it where I look, but it is off when I am further from (0,0,0), so if there is a better way of doing this I am all ears!!! Well, all eyes I guess…

Vector normalization is discussed at the bottom of this page.

Well, I think there are some misunderstandings.

What people here said about direction vectors are vectors. And to do the calculations they said, the direction vector must have an unit lenght (normalized).

What you use as “direction vector” is a 3-uplet of angles (angle around x,y and z axis respectively).

The problem with your approach is that there is no general angles. An angle is measurable between two vectors (x and dir for example). But you can’t say there’s an angle of pi over 3 (angle between what and what ??).

So as long as you keep the same “base” vectors on which you define your “dir” angles, there will have no problems. If this base vector is x (1,0,0 in world coordinates) for the first angle, always keep x. If you change it, you’ll have issues and wrong results.

And as long as you do so and as long as you ensure your trigonometric functions to transform your angles into a vector produces an unit-lenght vector, you will have no problem.