C 寻找一种快速轮廓线绘制算法

C 寻找一种快速轮廓线绘制算法,c,algorithm,line,bresenham,C,Algorithm,Line,Bresenham,我正在寻找一种快速算法来画轮廓线。对于此应用程序,轮廓仅需要1像素宽。无论是默认情况下还是通过选项,如果两条线共享一个公共点,则应该可以使它们无缝连接在一起 请原谅ASCII艺术,但这可能是最好的方式来证明它 正常线路: ## ## ## ## ## ## “概述”行: 我正在研制一台dsPIC33FJ128GP802。它是一个小型微控制器/数字信号处理器,能够处理40 MIPS(每秒百万条指令)。它只能够进行整数运算(加

我正在寻找一种快速算法来画轮廓线。对于此应用程序,轮廓仅需要1像素宽。无论是默认情况下还是通过选项,如果两条线共享一个公共点,则应该可以使它们无缝连接在一起

请原谅ASCII艺术,但这可能是最好的方式来证明它

正常线路:

 ##
   ##
     ##
       ##
         ##
           ##
“概述”行:

我正在研制一台dsPIC33FJ128GP802。它是一个小型微控制器/数字信号处理器,能够处理40 MIPS(每秒百万条指令)。它只能够进行整数运算(加法、减法和乘法:它可以进行除法运算,但需要约19个周期)。它被用于同时处理OSD层,并且只有3-4 MIPS的处理时间可用于计算,因此,速度至关重要。像素占据三种状态:黑色、白色和透明;视频场为192x128像素。这是一个开源项目Super OSD:

我想到的第一个解决方案是绘制3x3个矩形,第一个过程中有轮廓像素,第二个过程中有普通像素,但这可能会很慢,因为每个像素至少有3个像素被覆盖,并且绘制它们所花费的时间被浪费。所以我在寻找一种更快的方法。每个像素的成本约为30个周期。目标是我建议这样(C/伪代码混合):


我的方法是使用Bresenham绘制多条线。看看你的ASCII艺术,你会注意到轮廓线和Bresenham线一样,只是上下移动了1个像素——加上第一个点左边和最后一个点右边的一个像素


对于一般版本,你需要确定你的线条是平坦的还是陡峭的——也就是说,
abs(y1-y0)我不认为这是重复的,但它可能是相关的。+1&感谢链接。这涉及到轮廓线,所以我正在寻找一种有效的方法来画一条带边框的线。画一条粗线,然后再画一条细线,这与我给出的选项基本相同。是的。这条线像普通的布雷森汉姆,宽1像素。我想在这条线上画一个1像素的轮廓线,因此这条线总共有3像素宽。这显然不是要求提供非现场资源,也没有提供非现场资源。亲爱的亲密选民,请学会阅读。有了爱,基本上就是这样——这个例子没有使用快速Bresenham算法,但是这个想法可以调整。用文字而不是伪代码:每个“线”像素需要一个上、下、左、右的“轮廓”像素。因此,对于每个水平段,在左侧放置一个轮廓像素,沿着绘制直线并在上方+下方绘制轮廓的段,然后在右侧放置一个轮廓像素。下一个水平段也是如此。但是您可以进行优化,因为此水平段的上边框与最后一个水平段的右边框重叠,所以您只需要为第一个/最后一个段绘制L/R像素。@psmears:您确实想为所有段绘制L/R边框,因为您可能有一个从左到右的段,后面跟着一个从右到左的段,例如,在绘制类似“>”符号的图形时,如果处理器无法在硬件中执行浮点运算,我将使用定点计算斜率。然后,假设可以为小数部分留出16位,y的计算将变成:
hi_res_y+=slope;y=高分辨率>>16。这只是一个加法和一个位移位。我将初始化hi_res_y=(y谢谢:)我将进一步研究这个问题。另外,感谢多段线函数-这将非常有用。我想我必须通过放置像素来手动更正它。
 **
*##**
 **##**
   **##**
     **##**
       **##**
         **##*
           **
void draw_outline(int x1, int y1, int x2, int y2)
{
    int x, y;
    double slope;

    if (abs(x2-x1) >= abs(y2-y1)) {
        // line closer to horizontal than vertical
        if (x2 < x1) swap_points(1, 2);
        // now x1 <= x2
        slope = 1.0*(y2-y1)/(x2-x1);
        draw_pixel(x1-1, y1, '*');
        for (x = x1; x <= x2; x++) {
            y = y1 + round(slope*(x-x1));
            draw_pixel(x, y-1, '*');
            draw_pixel(x, y+1, '*');
            // here draw_line() does draw_pixel(x, y, '#');
        }
        draw_pixel(x2+1, y2, '*');
    }
    else {
        // same as above, but swap x and y
    }
}
void draw_polyline(point p[], int n)
{
    int i;

    for (i = 0; i < n-1; i++)
        draw_outline(p[i].x, p[i].y, p[i+1].x, p[i+1].y);
    for (i = 0; i < n-1; i++)
        draw_line(p[i].x, p[i].y, p[i+1].x, p[i+1].y);
}