我有一个类Shape,它只包含绘制自身的顶点和函数, 一个Ray类,它只是一个具有更多函数的Line2D(在这种情况下是无关紧要的),以及一个将光线投射到每个形状的每个顶点的RayCaster,检查当前光线与每条线的交点,然后采取这些交叉点,选择最接近RayCaster的那个,并使用该交点创建一个新的Ray,然后绘制该光线。
我已经尝试过这样做3次而且从来没有完全正确,有些光线甚至不会出现在某些位置。我已经测试了我的代码来计算交叉点位置并且它可以工作:
public static Point2D getLineIntersection(Line2D ray, Line2D segment) {
if(ray.intersectsLine(segment)){
double rx1 = ray.getX1(),
ry1 = ray.getY1(),
rx2 = ray.getX2(),
ry2 = ray.getY2(),
sx1 = segment.getX1(),
sy1 = segment.getY1(),
sx2 = segment.getX2(),
sy2 = segment.getY2(),
rdx = Math.abs(rx2 - rx1),
rdy = Math.abs(ry2 - ry1),
sdx = Math.abs(sx2 - sx1),
sdy = Math.abs(sy2 - sy1),
t1, t2,
ix, iy;
t2 = (rdx * (sy1 - ry1) + rdy * (rx1 - sx1)) / (sdx * rdy - sdy * rdx);
t1 = (sx1 + sdx * t2 - rx1) / rdx;
if(t1 > 0 && 1 > t2 && t2 > 0){
ix = rx1 + rdx * t1;
iy = ry1 + rdy * t1;
return new Point2D.Float((int) ix, (int) iy);
}else
return null;
}else
return null;
}
所以我把它缩小到我投射光线的地方,但我不知道错误:
public void castRays(Graphics g, ArrayList<Shape> map){
ArrayList<Ray> rays = new ArrayList<>();
ArrayList<Point2D> vertices = new ArrayList<>();
ArrayList<Line2D> segments = new ArrayList<>();
//populate vertices and segments
for(Shape s : map){
vertices.addAll(Arrays.asList(s.getPoints()));
segments.addAll(s.getLines());
}
for(Point2D v : vertices){
Ray ray = new Ray(x, y, (int) v.getX(), (int) v.getY());
ArrayList<Point2D> rayIntersects = new ArrayList<>();
Point2D closestIntersect = null;
for(Line2D s : segments)
if(Utils.getLineIntersection(ray.getLine(), s) != null)
rayIntersects.add(Utils.getLineIntersection(ray.getLine(), s));
if(rayIntersects.size() > 0){
for(int i = 0; i < rayIntersects.size(); i++){
if(i == 0)
closestIntersect = rayIntersects.get(0);
else{
if(Utils.getLineLength(new Line2D.Float(x, y, (int) closestIntersect.getX(), (int) closestIntersect.getY()))
> Utils.getLineLength(new Line2D.Float(x, y, (int) rayIntersects.get(i).getX(), (int) rayIntersects.get(i).getY())))
closestIntersect = rayIntersects.get(i);
}
}
}
if(closestIntersect != null)
rays.add(new Ray(x, y, (int) closestIntersect.getX(), (int) closestIntersect.getY()));
}
for(Ray r : rays)
r.render(g, Color.WHITE);
}
public static double getLineLength(Line2D line){
double dx = Math.abs(line.getX2() - line.getX1()),
dy = Math.abs(line.getY2() - line.getY1());
return Math.sqrt(dx * dx + dy * dy);
}
如果您需要更多代码,请询问,但我认为问题出在castRays函数
答案 0 :(得分:2)
发现我的错误。事实证明我错了:
public static Point2D getLineIntersection(Line2D ray, Line2D segment) {
if(ray.intersectsLine(segment)){
double rx1 = ray.getX1(),
ry1 = ray.getY1(),
rx2 = ray.getX2(),
ry2 = ray.getY2(),
sx1 = segment.getX1(),
sy1 = segment.getY1(),
sx2 = segment.getX2(),
sy2 = segment.getY2(),
rdx = rx2 - rx1,
rdy = ry2 - ry1,
sdx = sx2 - sx1,
sdy = sy2 - sy1,
t1, t2,
ix, iy;
t2 = (rdx * (sy1 - ry1) + rdy * (rx1 - sx1)) / (sdx * rdy - sdy * rdx);
t1 = (sx1 + sdx * t2 - rx1) / rdx;
if(t1 > 0/* && 1 > t2 && t2 > 0*/){
ix = rx1 + rdx * t1;
iy = ry1 + rdy * t1;
return new Point2D.Float((int) ix, (int) iy);
}else
return null;
}else
return null;
}