2017-10-11 127 views
0

如何找出一條線段經過的網格單元?例如,線段可以作爲(8.3555 9.1654) -> (1.4123 5.6312)(以任意精度)給出。如何離散線段

我要像頂部的第二圖像中看到,改造成一個基於網格的表示這樣的:

example

我目前正在研究CGAL。它有包裝Snap Rounding哪種做我正在尋找的,但僅用於細分市場的起點和終點。

+0

HTTPS:/ /en.wikipedia.org/wiki/Line_drawing_algorithm? –

+0

有檢測2條線(矢量)交叉的公式,在你的情況下,隱含線和網格線,你問的是那個東西? – Surt

+0

[Precise subpixel line drawing algorithm(rasterization algorithm)]的可能的副本](https://stackoverflow.com/questions/24679963/precise-subpixel-line-drawing-algorithm-rasterization-algorithm) – Spektre

回答

0

我最終實現了自己的算法。基本上,因爲沒有任何計算機圖形算法符合我實際包括所有網格單元的要求,所以這條線觸及。

注意,我使用CGAL和兩個不同的內核來表示浮動prcision點作爲Point和離散網格細胞作爲Pixel

#include <CGAL/Simple_cartesian.h> 
#include <CGAL/Point_2.h> 

typedef CGAL::Simple_cartesian<double> KernelDouble; 
typedef KernelDouble::Point_2 Point; 
typedef KernelDouble::Segment_2 Segment; 

typedef CGAL::Simple_cartesian<uint16_t> KernelInt; 
typedef KernelInt::Point_2 Pixel; 

這是函數:

void get_pixels_for_segment(std::list<Pixel>* res, Segment seg) { 
    assert(res->size() == 0); 
    Point start = seg.source(); 
    Point goal = seg.target(); 
    uint8_t swapped = 0; 
    if(start.x() > goal.x()) { // swap 
     start = seg.target(); 
     goal = seg.source(); 
     swapped = 1; 
    } 
    Pixel startp, goalp; 
    startp = point_to_pixel(&start); 
    goalp = point_to_pixel(&goal); 
    int8_t sx = sgn<int>(goalp.x() - startp.x()); 
    assert(sx >= 0); 
    int8_t sy = sgn<int>(goalp.y() - startp.y()); 
    if(startp == goalp) { 
     res->push_back(startp); 
     return; 
    } 
    double d = (goal.y() - start.y())/(goal.x() - start.x()); 
    double ysec = start.y() - d * start.x(); 
    std::list<int> xs; 
    range(&xs, startp.x(), goalp.x()); 
    std::list<int>::iterator xsit = xs.begin(); 
    for(; xsit != xs.end(); ++xsit) { 
     int xl = *xsit; 
     int xr = *xsit + 1; 
     double yl = d * xl + ysec; 
     double yr = d * xr + ysec; 
     if(startp.y() == goalp.y()) { 
      yl = startp.y(); 
      yr = goalp.y(); 
     } 
     if(
      ((startp.y() - floor(yl)) * sy) > 0 
     ) yl = (double) startp.y(); 
     if(
      ((goalp.y() - floor(yr)) * sy) < 0 
     ) yr = (double) goalp.y(); 
     std::list<int> ys; 
     range(&ys, floor(yl), floor(yr)); 
     std::list<int>::iterator ysit = ys.begin(); 
     for(; ysit != ys.end(); ++ysit) { 
      assert(*xsit >= 0); 
      assert(*ysit >= 0); 
      res->push_back(Pixel(*xsit, *ysit)); 
     } 
    } 
    if(swapped) res->reverse(); 
    return; 
} 
0

第一張圖像顯示了像Bresenham或DDA一樣的線柵格化算法。

第二個圖像顯示體素化 - 獲取所有網格單元格接觸的行。考慮Amanatides and Woo的算法。

enter image description here

+0

謝謝你,尤其是細胞以藍色顯示,我需要包括在內。我的起點和終點都需要浮點精度。 – Christian

+0

起點和終點座標是浮動的。當然,藍色細胞是通過算法註冊的。我只是給了他們另一種顏色(一些應用程序應該忽略這樣的點) – MBo

+0

好的,謝謝你指出。我將再次研究它。 – Christian