Reputation: 2665
http://www.redblobgames.com/articles/visibility/
It's the first part:
Calculate the angles where walls begin or end.
Cast a ray from the center along each angle.
Fill in the triangles generated by those rays.
I'm doing something like this:
vector<float> angles;
for(int i = 0; i < polygonCoordinates.size(); i++)
{
for(int j = 0; i < polygonCoordinates[i].size(); j++)
{
angles.push_back(AngleBetweenPoints(LIGHT_POSITION, polygonCoordinates[i][j]));
}
}
Where polygonCoordinates is a 2D vector, basically each polygon is a vector of Point2D structs and all polygons are inside a bigger vector.So after I find the angles, how do I proceed?Why do I need raycasting?How will that help me generate the "light polygon"?
Upvotes: 1
Views: 2164
Reputation: 2288
First things first: Sort your angles and their corresponding vertices from least to greatest.
Start with your viewer 'aiming' to the left, and store the nearest visible point (which happens to be on the wall) in tmpPoint or something like that.
Then, you go through your list of angles you calculated. You are going to sweep out the whole area of the screen, clockwise (do this by iterating through your list of sorted angles). The first ray you are testing is the bottom left of the little rectangle (it has the lowest angle that you calculated). The nearest visible point is on the left wall somewhere. Your visible triangle list, add the triangle formed by the viewer, tmpPoint, and the point you just found. (see picture) Finally, store that point in tmpPoint.
The next point we check is the upper left of the little rectangle. Here is where we really need to check for visibility. The nearest point is the visible one. (see picture) Then, add your triangle (composed again of the point you just found, the viewer, and tmpPoint). Just repeat this process over and over, and you will eventually fill your whole screen with triangles representing visibility.
I hope this helps. I made some nice pseudocode, but I was doing it wrong, so here are just the graphics. :P
Edit:
So you have your verticy array all calculated out, and by calculated I mean visibility of the rays. What you do is something almost like this:
for(int i = 0; i < calculatedVertices.size()-1; i++) {
triangle t = triangle(
calculatedVertices[i],
calculatedVertices[i+1],
centerViewer);
triangleArray.add(t);
}
//the loop above misses one triangle, so just add the last one
triangle final = triangle(
calculatedVertices[0]
calculatedVertices[calculatedVertices.size()-1],
centerViewer);
triangleArray.add(final);
This nearly fully works, except for one terrible issue:
You see, when you have your far-wall cast triangle, the intersection should occur on the wall, but when you have your triangle cast to the rectangle, the intersection should occur on the rectangle itself. If the intersections don't occur in this manner, this will happen:
I'm not entirely sure if this is an actual problem, or if its just something i'm thinking of, but a way you can solve it is by adding a slight bias (of your intersection detection) towards your other vertex, if you know what I mean. That should fix this problem.
Upvotes: 6