2012-11-24 13 views
5

Do testów zderzeniowych potrzebuję rastra linii. Algorytm bresenham działa prawie jak trzeba, ale ma wadę, że jest produkuje linię jak: Line Rasterization/4-connected Bresenham

I potrzebuję:

mojego obecnego realizacji (w oparciu o http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#Simplification):

public boolean isInsideLine(int x1, int y1, int x2, int y2) { 
    final int dx = abs(x2 - x1), dy = abs(y2 - y1); 
    final int sx = x1 < x2 ? 1 : -1, sy = y1 < y2 ? 1 : -1; 
    int err = dx - dy; 

    while (true) { 
     if (isInside(x1, y1)) //Lookup in pixel array 
      return true; 
     if (x1 == x2 && y1 == y2) 
      break; 
     final int e2 = err << 1; 
     if (e2 > -dy) { 
      err -= dy; 
      x1 += sx; 
     } 
     if (e2 < dx) { 
      err += dx; 
      y1 += sy; 
     } 
    } 
    return false; 
} 

Czy istnieje inny algorytm rasteryzacji, z którego mógłbym skorzystać, czy też ktoś wie, jak zmodyfikować bresenham?

+0

Wydaje mi się, że surowa wydajność Bresenham jest 8-podłączona, ale wymaga 4-połączonych. Możesz wykonać przetwarzanie końcowe surowego wyjścia, aby wykryć przekątne łącze, a następnie zdecydować, który piksel jest najbliższy linii. – koan

+2

Zobacz http://stackoverflow.com/questions/5186939/algorithm-for-drawing-a-4-connected-line dla czegoś, co wygląda tak samo. – koan

+1

Ciekawe: dlaczego potrzebujesz rasteryzacji linii do wykrywania kolizji? Nie możesz po prostu obliczyć skrzyżowań? – Axel

Odpowiedz

1

Dzięki koan, czasami po prostu brakuje słów kluczowych, aby sprawdzić, Algorithm for drawing a 4-connected line wydaje się go rozwiązać:

public boolean isInsideLine(int x1, int y1, int x2, int y2) { 
    final int dx = abs(x2 - x1), dy = abs(y2 - y1); 
    final int sx = x1 < x2 ? 1 : -1, sy = y1 < y2 ? 1 : -1; 
    int err = dx - dy; 

    while (true) { 
     if (isInside(x1, y1)) //Lookup in pixel array 
      return true; 
     if (x1 == x2 && y1 == y2) 
      break; 
     final int e2 = err << 1; 
     if (e2 > -dy) { 
      err -= dy; 
      x1 += sx; 
     } else if (e2 < dx) { // else if instead of if 
      err += dx; 
      y1 += sy; 
     } 
    } 
    return false; 
} 
2

Może to być przydatne, nie jest moja wersja dla niecałkowitą punktów końcowych. Jest to metoda klasy GridMap, której używam do indeksowania przestrzennego kształtów geometrycznych w celu przyspieszenia wykrywania kolizji na mapie 2D.

int GridMap::insertLine(int lineId, double ax, double ay, double bx, double by){ 
    // get index of endpoints in GridMap 
    int ix = getIx(ax); 
    int iy = getIy(ay); 
    int ixb = getIx(bx); 
    int iyb = getIy(by); 
    // insert endpoints to GridMap 
    insert(lineId, ix, iy ); 
    insert(lineId, ixb, iyb); 
    // raster central part of the line 
    double dx = fabs(bx - ax); 
    double dy = fabs(by - ay); 
    int dix = (ax < bx) ? 1 : -1; 
    int diy = (ay < by) ? 1 : -1; 
    double x=0, y=0; 
    while ((ix != ixb) && (iy != iyb )) { 
     if (x < y) { 
      x += dy; 
      ix += dix; 
     } else { 
      y += dx; 
      iy += diy; 
     } 
     insert(lineId, ix, iy); 
    } 
};