Cocos2d-x - Ошибка рисования кубических кривых безье

Я пытаюсь нарисовать кубический путь безье с определенной толщиной, но кривая появляется как последовательность отключенных сегментов (3 в моем случае). Это скриншот (синие круги - контрольные точки кривой).

Cubic bezier curve

Я заметил, что тот же эффект возникает в "примитивах рисования" в тестах cocos2d-x. В любом случае, я уверен, что должен быть обходной путь, но я не могу найти его сам. Кроме того, на строку влияет эффект сглаживания, и я не уверен, как применить альфа-тень, чтобы избежать этого.

Это код, который я использовал:

glLineWidth(24.0f);

Vec2 cp1 = Vec2(200, 200);
Vec2 cp2 = Vec2(1300, 150);
Vec2 cp3 = Vec2(170, 1200);
Vec2 cp4 = Vec2(1400, 1000);

//Draw control points
DrawPrimitives::setDrawColor4B(0, 0, 255, 255);
DrawPrimitives::drawSolidCircle(cp1, 50, 360, 120, 1, 1);
DrawPrimitives::drawSolidCircle(cp2, 50, 360, 120, 1, 1);
DrawPrimitives::drawSolidCircle(cp3, 50, 360, 120, 1, 1);
DrawPrimitives::drawSolidCircle(cp4, 50, 360, 120, 1, 1);

//Draw cubic red bezier curve
DrawPrimitives::setDrawColor4B(255, 0, 0, 255);
DrawPrimitives::drawCubicBezier(cp1, cp2, cp3, cp4, 50);

Ответ 1

Этот сломанный эффект вызван отсутствием соединения путей между конечными точками линейных полос.

OpenGL предназначен для быстрой растеризации растровых изображений в первую очередь и не всегда так красив, если вы хотите использовать его таким образом.

Быстрые и грязные способы обхода пути могут получить разумный результат, например, рисовать круги в конечных точках, чтобы попытаться заполнить все.

Правильная библиотека, в которой красивые пути рисования важны, часто будет предлагать варианты соединения между линиями/кривыми, такими как закругленные, скошенные или митральные, а также варианты для концевых колпачков, где сегменты не соединяются вместе. Это может быть проще и эффективнее для той работы, которую вы делаете, чтобы использовать, скажем, приличный растеризатор SVG для такого рода работ. Если вам нужно собрать результаты по элементам, растрированным OGL, вы можете перенести результаты изображения в текстуру и сделать это.

Вы также можете получить довольно сложную и бросить довольно сложное решение (или, возможно, найти его в другом месте) через OpenGL. Вот пример: https://www.mapbox.com/blog/drawing-antialiased-lines/

Ответ 2

У меня есть другое решение, но я не знаю, замедляет ли производительность? кто-нибудь, пожалуйста, дайте мне совет!

void DrawNode::drawCubicBezier(const Vec2 &origin, const Vec2 &control1, const Vec2 &control2, const Vec2 &destination, unsigned int segments, const Color4F &color)

{

Vec2* vertices = new (std::nothrow) Vec2[segments + 1];
if( ! vertices )
    return;

float t = 0;
for (unsigned int i = 0; i < segments; i++)
{
    vertices[i].x = powf(1 - t, 3) * origin.x + 3.0f * powf(1 - t, 2) * t * control1.x + 3.0f * (1 - t) * t * t * control2.x + t * t * t * destination.x;
    vertices[i].y = powf(1 - t, 3) * origin.y + 3.0f * powf(1 - t, 2) * t * control1.y + 3.0f * (1 - t) * t * t * control2.y + t * t * t * destination.y;

    t += 1.0f / segments;
    **///begin  adddd
    drawLine(Vec2(vertices[i].x, vertices[i].y - 3), Vec2(vertices[i].x, vertices[i].y + 3), color);
    /// end addddd**
}
vertices[segments].x = destination.x;
vertices[segments].y = destination.y;
**drawLine(Vec2(vertices[segments].x, vertices[segments].y - 3), Vec2(vertices[segments].x, vertices[segments].y + 3), color);**

CC_SAFE_DELETE_ARRAY(vertices);


}

вот мой результат Special Cubic Bezier