2015-08-20 6 views
1

Я работаю над простым алгоритмом расинга, который я могу использовать для 2D-теней в будущих играх, которые я хочу сделать. У меня есть часть raycasting, выясненная, но проблема в том, что я действительно хочу нарисовать тени.Проблемы с соединением лучей в алгоритме Raycasting

Я знаю, что рисование теней включает в себя создание многоугольника из концов каждого луча, который был отлит и вычитал свою область из «теневой маски», чтобы вы только увидели, что находится в области многоугольника. Однако моя проблема заключается в том, что я не могу понять, как я должен сортировать лучи, чтобы полигон формировал правильную форму, а не соединялся со случайными лучами.

То, что я получаю, выглядит примерно так.

Improperly connected polygon.

Так что, если кто знаком с raycasting может сказать мне, как я должен соединить лучи в правильном порядке, чтобы достичь правильной формы, я ценю это. Если это имеет значение, вот мой алгоритм.

private void raycast(Point2D.Double target) { 
    double theta = Math.atan2((target.y - mousePos.y), (target.x - mousePos.x)); 
    Point2D.Double currLoc = new Point2D.Double(mousePos.x, mousePos.y); 
    boolean validRay = true; 

    while(validRay) { 
     double x = currLoc.x + Math.cos(theta); 
     double y = currLoc.y + Math.sin(theta); 

     // Check to see if the ray has gone out of the window. 
     if((x < 0) || (x >= Game.WIDTH) || 
      (y < 0) || (y >= Game.HEIGHT)) { 
      validRay = false; 
     } 

     // Check to see if the ray has collided with an object. 
     for(Polygon c : obstacles) { 
      if(c.contains(new Point2D.Double(x, y))) { 
       validRay = false; 
      } 
     } 

     if(validRay) { 
      currLoc.x = x; 
      currLoc.y = y; 
     } 
    } 

    rays.add(new Point2D.Double(currLoc.x, currLoc.y)); 
} 

И это в настоящее время, как я соединяю лучи в многоугольник.

if(rays.size() > 0) { // Create the shadow mask. 
    BufferedImage overlay = new BufferedImage(Game.WIDTH, Game.HEIGHT, BufferedImage.TYPE_INT_ARGB); 
    Graphics2D og2d = overlay.createGraphics(); 
    og2d.setColor(new Color(0.0f, 0.0f, 0.0f, 1.0f)); 
    og2d.clearRect(0, 0, Game.WIDTH, Game.HEIGHT); 

    // Create a polygon from the endpoints of all the rays. 
    Path2D.Double mask = new Path2D.Double(); 
    mask.moveTo(rays.get(0).x, rays.get(0).y); 
    for(Point2D.Double end : rays) { 
     mask.lineTo(end.x, end.y); 
    } 
    mask.closePath(); 

    og2d.setColor(Color.WHITE); 
    og2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 0.0f)); 
    og2d.fill(mask); 

    g2d.drawImage(overlay, 0, 0, null); 
} // End creation of shadow mask. 

Может ли кто-нибудь помочь?

ответ

1

Мне удалось «отсортировать» конечные точки, используя угол между конечной точкой и источником света в качестве критериев для сортировки. В основном, самый низкий угол пошел в начало списка и так далее.

Единственная проблема теперь в том, что у меня нет реальных конечных точек на некоторых вершинах, потому что алгоритм будет продолжать проходить через вершину, если он не столкнется с самим объектом, пока он не попадет на край экрана, поэтому когда я соединяю вершины, чтобы сделать многоугольник, он принимает «ярлыки». Вот скриншот, чтобы продемонстрировать, что я имею в виду.

Improperly connected polygon