Рисование толстой линии имеет отверстия

Я сделал простой способ нарисовать линию с фиксированной толщиной.
Вот моя функция:

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);
}

}

он должен провести линию от (x1, y1) до (x2, y2) с цветом (r, g, b, a) и толщиной wd. Я использую этот метод при рисовании, перемещая палец по экрану, поэтому я также добавил дополнительный параметр «начал», который говорит, началось ли касание или движение касанием. Данные это массив пикселей. AreaData не имеет значения.

Но это не работает, как ожидалось, вот пример результата:

введите описание изображения здесь

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

Если «wd» недостаточно велико, то проблемы нет. Я почти уверен, что это какая-то проблема с точностью.

Я старался:
— изменение цикла от 0 до 360 (не угол-90, угол + 90).
— используя круглый вместо пола
— используя грех вместо -sin (у меня все равно инвертировано в моем случае)
— используя _r ниже 1,0, например: 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);
}
}
}

1

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector