Как нарисовать коническую дугу (кривую с уменьшающейся толщиной) в OpenGL?

У меня есть следующий код для рисования произвольной дуги:

void CenteredArc::drawPolygonArc(float radius, float thickness, float startAngle, float arcAngle) {
float num_segments = 360.0;

float radiusOuter = radius + thickness / 2;
float radiusInner = radius - thickness / 2;
float theta = arcAngle / num_segments;
float tangetial_factor = tanf(theta);//calculate the tangential factor

float radial_factor = cosf(theta);//calculate the radial factor

float xxOuter = radiusOuter * cosf(startAngle);
float yyOuter = radiusOuter * sinf(startAngle);
float xxInner = radiusInner * cosf(startAngle);
float yyInner = radiusInner * sinf(startAngle);

float prevXXOuter = -1;
float prevYYOuter = -1;
float prevXXInner = -1;
float prevYYInner = -1;

glPolygonMode(GL_FRONT, GL_FILL);
for(int ii = 0; ii < num_segments; ii++)
{
if (prevXXOuter != -1) {
glBegin(GL_POLYGON);
glVertex2f(prevXXOuter, prevYYOuter);
glVertex2f(xxOuter,     yyOuter);
glVertex2f(xxInner,     yyInner);
glVertex2f(prevXXInner, prevYYInner);
glEnd();
}

//calculate the tangential vector
//remember, the radial vector is (x, y)
//to get the tangential vector we flip those coordinates and negate one of them

float txOuter = -yyOuter;
float tyOuter =  xxOuter;
float txInner = -yyInner;
float tyInner =  xxInner;

//add the tangential vector

prevXXOuter = xxOuter;
prevYYOuter = yyOuter;
prevXXInner = xxInner;
prevYYInner = yyInner;

xxOuter += txOuter * tangetial_factor;
yyOuter += tyOuter * tangetial_factor;
xxInner += txInner * tangetial_factor;
yyInner += tyInner * tangetial_factor;

//correct using the radial factor
xxOuter *= radial_factor;
yyOuter *= radial_factor;
xxInner *= radial_factor;
yyInner *= radial_factor;
}
}

Однако я бы хотел, чтобы дуга начиналась с указанной толщины на одном конце и постепенно уменьшалась до нуля на другом конце. Какие-либо предложения?

Изменить: я не использую GL_LINE_STRIP потому что я стараюсь избегать перекрывающихся линий и пропусков, например:

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

0

Решение

Я бы использовал line strip с уменьшением glLineWidth,

Это моя реализация, она не уменьшает lineWidth но это можно изменить, чтобы сделать это. Извините за лишние вещи, это из моего игрового движка.

for(int i=0;i<arcs().size();i++)
{
Entities::Arc temp = arcs().at(i);
glLineWidth(temp.LW.value); // change LWidth

glColor3f( temp.CL.R, temp.CL.G, temp.CL.B );

// theta is now calculated from the arc angle instead, the
// - 1 part comes from the fact that the arc is open
float theta = temp.A.value*DEG2RAD / float(WW_SPLINE_ACCURACY - 1);

float tan = tanf(theta);
float cos = cosf(theta);

// we are now at the starting angle
double x = temp.R.value * cosf(temp.A.value*DEG2RAD);
double y = temp.R.value * sinf(temp.A.value*DEG2RAD);

// since the arc is not a closed curve, this is a strip now
glBegin(GL_LINE_STRIP);
for(int ii = 0; ii < WW_SPLINE_ACCURACY; ii++)
{
glVertex2d(x + temp.C.X, y + temp.C.Y);
double tx = -y;
double ty = x;
x += tx * tan;
y += ty * tan;
x *= cos;
y *= cos; //y = ( y + (ty*tan) )*cos;
}
glEnd();
glLineWidth(WW_DEFAULT_LWIDTH); // reset LWidth
}

Я также использовал эти значения

#define WW_SPLINE_ACCURACY  72 // 72 for extra smooth arcs/circles, 32 minimum
#define WW_BEZIER_ACCURACY  20

/* Math stuff */
#define DEG2RAD 3.14159/180
#define PI  3.1415926535897932384626433832795;

...

glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_COLOR_MATERIAL);
glEnable (GL_LINE_SMOOTH);
glEnable (GL_BLEND);
//glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glEnable(GL_POLYGON_SMOOTH);
glClearColor(0.188f, 0.169f, 0.329f, 1.0f); //#302b54

Мне не разрешено выпускать полный исходный код, так как я написал его для компании, но разделение части или двух никому не повредит: D

0

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

Других решений пока нет …

По вопросам рекламы [email protected]