1

我做了简单的方法来绘制固定厚度的线。这是我的功能:

void ColoringScene::drawThickLine(int x1, int y1, int x2, int y2, int r, int g, int b, int a, float wd, bool began, unsigned char* data, unsigned char* areasData){

    if(began){
        //if just began draw "dot" with filled circle
        drawFilledCircle(x1, y1, 1, wd, r, g, b, a, data, areasData);
        return;
    }

    //otherwise calculate angle between two points
    int angle = (int)(atan2(-y2 + y1, x2 - x1) * 180 / M_PI);

    int a1 = angle - 90;
    int a2 = angle + 90;

    //calculate a distance between two points
    float diff = sqrtf(powf(x1 - x2, 2) + powf(y1 - y2, 2));
    if(diff > wd) diff = wd;

    //find all points in arc from angle - 90 to angle + 90
        for(float _r = a1; _r < a2; _r+=1.0f){

            float _x1 = cos(CC_DEGREES_TO_RADIANS(_r)) * wd + x1;
            float _y1 = -sin(CC_DEGREES_TO_RADIANS(_r)) * wd + y1;

            float _x2 = cos(CC_DEGREES_TO_RADIANS(_r)) * wd + x2;
            float _y2 = -sin(CC_DEGREES_TO_RADIANS(_r)) * wd + y2;

            //connect point from 2 arcs with line
            drawLine(floor(_x1), floor(_y1), floor(_x2), floor(_y2), r, g, b, a, data, areasData);
        }

}

它应该用颜色 (r, g, b, a) 和厚度 wd 从 (x1, y1) 到 (x2, y2) 画线。我在屏幕上移动手指时使用此方法进行绘图,因此我还添加了额外的参数“began”,表示它是触摸开始还是触摸移动。data 是一个像素数组。区域数据无关紧要。

但它没有按预期工作,这是一个示例结果:

在此处输入图像描述

可能会有一点压缩,但是您可以看到 2 个点,它们绘制得很好,并且由许多带有孔的“粗”线构建了一条曲线。

如果“wd”不够大,则问题不存在。我几乎可以肯定这是精度方面的某种问题。

我试过: - 将 for 循环从 0 更改为 360(不是角度 90,角度 + 90)。- 使用圆形而不是地板 - 使用 sin 而不是 -sin(在我的情况下,y 无论如何都是倒置的) - 使用低于 1.0 的 _r,例如:0.05。

并且通过给定的固定厚度(在此示例中为 60 像素),无法设置诸如 _r 增量或角度之类的参数以不绘制没有孔。

我决定编写自己的函数来做到这一点,因为我在网上找到的其他方法并没有按预期工作(尤其是抗锯齿,这对我来说是完美的解决方案)。

这是从网站上获取的 drawLine 函数:http ://willperone.net/Code/codeline.php

void ColoringScene::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int a, unsigned char* data, unsigned char* areasData){
    int dy = y2 - y1;
    int dx = x2 - x1;
    int stepx, stepy;

    if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
    if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
    dy <<= 1;        // dy is now 2*dy
    dx <<= 1;        // dx is now 2*dx

    setPixelWithCheckingArea(x1, y1, r, g, b, a, data, areasData);

    if (dx > dy)
    {
        int fraction = dy - (dx >> 1);  // same as 2*dy - dx
        while (x1 != x2)
        {
            if (fraction >= 0)
            {
                y1 += stepy;
                fraction -= dx;          // same as fraction -= 2*dx
            }
            x1 += stepx;
            fraction += dy;              // same as fraction -= 2*dy
            setPixelWithCheckingArea(x1, y1, r, g, b, a, data, areasData);
        }
    } else {
        int fraction = dx - (dy >> 1);
        while (y1 != y2) {
            if (fraction >= 0) {
                x1 += stepx;
                fraction -= dy;
            }
            y1 += stepy;
            fraction += dx;
            setPixelWithCheckingArea(x1, y1, r, g, b, a, data, areasData);
        }
    }
}
4

0 回答 0