2017-07-14 40 views
1

我有一個類Shape,它只包含頂點和函數來繪製自己, 是一個類Ray,它只是一個具有更多功能的Line2D(在這種情況下無關緊要),以及一個RayCaster,射線到每個形狀的每個頂點,檢查當前射線與每條線的交點,然後取這些交點,選擇最接近RayCaster的點並使用該交點創建新射線,然後繪製該射線。Java試圖在2D中進行光線投射

我已經嘗試過這樣做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函數

回答

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; 
}