I have, for a long time, had a problem. I often found myself looking up how to do ray casting, I might find something, but it would never really help, and everything I had seen looked awfully limited. The environment where rays were being cast had to be a grid because it depended on checking every square on the grid the ray intersected with along the way, and that meant that it would be slower if things were far apart. I also noticed a bizarre pattern of people only wanting to know what ray casting was in the context of rendering a 3D-looking environment. This was weird for me, because people seemed to ONLY refer to it that way, when it had quite a few more applications. Needless to say the internet was useless, and I worked on and developed my own method independently to find if a ray would intersect with a line. No grids, no binary searches. Just rays and lines and math.
Something still bothered me though. I thought it was pretty efficient as compared to some other methods, but I didn't know how efficient it was. I've seen other things ray cast, but I never knew how the did it, and I never knew if my method was better or not.
So, today, I present the algorithm in the form of C++ to programmers I think will be able to judge it based on their experiences with such things. It isn't optimized. (It will still check if the ray is pointing directly away from the line.) Also, the code contains some variation of a class that represents a 2D vector, so there really is no relation to SFML here. I'm asking here because I trust you folks to answer the question:
Is there a more efficient way to do what I've done here? (Not in regards to programming, more in regards to the math.):
#include <iostream>
#include <math.h>
using std::cout;
using std::endl;
//Define the behaviour of a 2D vector (geometry). How this works is mostly irrelevant.
class vec2 {
public:
vec2(float X, float Y){
x = X;
y = Y;
}
vec2 operator = (vec2 arg){
x = arg.x;
y = arg.y;
return *this;
}
vec2 operator * (float arg){
vec2 temp(0,0);
temp.x = x * arg;
temp.y = y * arg;
return temp;
}
vec2 operator + (vec2 arg){
vec2 temp(0,0);
temp.x = x + arg.x;
temp.y = y + arg.y;
return temp;
}
vec2 operator - (vec2 arg){
vec2 temp(0,0);
temp.x = x - arg.x;
temp.y = y - arg.y;
return temp;
}
vec2 operator * (vec2 arg){
vec2 temp(0,0);
temp.x = x * arg.x;
temp.y = y * arg.y;
return temp;
}
vec2 operator / (vec2 arg){
vec2 temp(0,0);
temp.x = x / arg.x;
temp.y = y / arg.y;
return temp;
}
float magnitude(){
return sqrt(x*x + y*y);
}
vec2 normal(){
float mag = this->magnitude();
return vec2(x/mag, y/mag);
}
float x,y;
};
//That's what most of the code is, and I haven't even gotten into the important part.
//This is what makes it happen *IMPORTANT THINGS START HERE*
void raycast(bool * retBool, float * retDis, vec2 * retVec, float Angle, vec2 Origin, vec2 PointA, vec2 PointB){
float aA, bA;
float factor;
vec2 pos(0,0);
aA = atan2(PointA.y, PointA.x);
bA = atan2(PointB.y, PointB.x);
factor = (Angle - aA)/(bA - aA);
*retBool = factor >= 0 && factor <= 1;
*retVec = (PointB-PointA)*factor + PointA;
*retDis = sqrt((retVec->x)*(retVec->x)+(retVec->y)*(retVec->y));
}
//That's it
int main(){
float distance;
bool hit;
vec2 pos(0,0);
raycast(&hit, &distance, &pos, 45.0 / 180.0 * 3.14159, vec2(0,0), vec2(1, 3), vec2(3, 1));
cout<<hit<<endl;
cout<<distance<<endl;
cout<<pos.x<<", "<<pos.y<<endl;
return 0;
}
Of course, I doubt you'll just get it if I post the code, so I'll give a little explanation of how it works in the form of an image. I don't guarantee it'll help because I'm apparently bad at explanations.
That probably didn't help much.
Well, if you think you can help me, feel free to post about it, I'd love to hear it.