我在java中制作2D游戏,我正在使用2D光线投射阴影。我使用这个算法来找到一条射线和一条线之间的交叉点,我在这里找到How do you detect where two line segments intersect?
// Returns 1 if the lines intersect, otherwise 0. In addition, if the lines
// intersect the intersection point may be stored in the floats i_x and i_y.
char get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y,
float p2_x, float p2_y, float p3_x, float p3_y, float *i_x, float *i_y)
{
float s1_x, s1_y, s2_x, s2_y;
s1_x = p1_x - p0_x; s1_y = p1_y - p0_y;
s2_x = p3_x - p2_x; s2_y = p3_y - p2_y;
float s, t;
s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y);
t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);
if (s >= 0 && s <= 1 && t >= 0 && t<=1)
{
// Collision detected
if (i_x != NULL)
*i_x = p0_x + (t * s1_x);
if (i_y != NULL)
*i_y = p0_y + (t * s1_y);
return 1;
}
return 0; // No collision
}
问题是如果光线和线都是垂直的,并且光线和线都在同一条线上,我需要得到光线击中线的点。例如,从(10,10)到(10,30)开始的光线交叉和从(10,20)到(10,40)开始的线应该给我(10,20),但它返回null。
这是我的java代码
public static Point2D.Double get_line_intersection(Line2D.Double ray, Line2D.Double line){
double s1_x, s1_y, s2_x, s2_y;
s1_x = ray.x2 - ray.x1; s1_y = ray.y2 - ray.y1;
s2_x = line.x2 - line.x1; s2_y = line.y2 - line.y1;
double s, t;
s = (-s1_y * (ray.x1 - line.x1) + s1_x * (ray.y1 - line.y1)) / (-s2_x * s1_y + s1_x * s2_y);
t = ( s2_x * (ray.y1 - line.y1) - s2_y * (ray.x1 - line.x1)) / (-s2_x * s1_y + s1_x * s2_y);
if (s >= 0 && s<=1 && t >= 0)
{
// Collision detected
Point2D.Double intersection = new Point2D.Double();
intersection.x = ray.x1 + (t * s1_x);
intersection.y = ray.y1 + (t * s1_y);
return intersection;
}
return null;
}
我只删除了第一个if语句中的条件t <= 1,因为光线是无限的。
首先,您必须检查光线和线段是否平行 - 在这种情况下,交叉积为零:
(-s2_x * s1_y + s1_x * s2_y) = 0
如果确实如此,请考虑第一个和第二个案例来自四个案例,在您链接的优秀答案中描述。您的示例是第一种情况(共线对象)