如何在OpenGL中绘制2D新月形状?我尝试使用正弦和余弦来绘制圆形,但由于新月形状内部有一个“切口”,所以正弦和余弦看起来不够。我也无法想出如何在两个多边形之间进行交集。所以我在思考是否有绘制新月的数学公式?
这并不是数学上正确的,但可能已经足够满足您的需求:
void drawCrescentLine(float step,float scale,float fullness) {
float angle=0.0f;
while (angle<M_PI) {
glVertex2f(scale*sinf(angle),scale*cosf(angle));
angle+=step;
}
while (angle<(2.0f*M_PI)) {
glVertex2f(fullness*scale*sinf(angle),scale*cosf(angle));
angle+=step;
}
glVertex2f(0.0f,scale);
}
或者
void drawCrescentTriStrip(float step,float scale,float fullness) {
glVertex2f(0.0f,scale);
float angle=step;
while (angle<M_PI) {
float sinAngle=sinf(angle);
float cosAngle=cosf(angle);
glVertex2f(scale*sinAngle,scale*cosAngle);
glVertex2f(-fullness*scale*sinAngle,scale*cosAngle);
angle+=step;
}
glVertex2f(0.0f,-scale);
}
在fullness=1
时,它会绘制一个大小为scale
的圆形,而在fullness=-0.99f
时,它会绘制一个非常细的新月形。您可以使用两个不同的fullness
值,即rightFullness
和leftFullness
,并始终将其中一个设置为1.0f
,以便您可以更改新月形的方向。
GL_LINE_STRIP
。我已更新答案,包括一个应该适用于 GL_TRIANGLE_STRIP
的版本。 - IronMensan你可以画两个相交的垂直椭圆。从其中一个椭圆中切出一块空间,形成了一个新月形状。在绘制时,可以使用按位 NAND 逻辑运算符来移除交集。
glEnable(GL_COLOR_LOGIC_OP);
drawEllipse1();
glLogicOp(GL_NAND);
drawEllipse2();
一个较为繁琐的方法是指定一堆顶点,形成你所需的形状骨架。然后,你可以使用GL_LINES将这些点连接起来以绘制你的形状。如果你想要一个更平滑的形状,你可以使用这些顶点作为Bezier/Catmull-Rom样条的控制点,这将绘制一条平滑的曲线连接所有的顶点。
Vertex outside [N+1]; // Fill in N with the precision you want
Vertex inside [N+1]; // Fill in N with the precision you want
double neg_size = sqrt (1 + NEG_DIST); // Size of intescting circle.
// NEG_DIST is the distance between their centers
// Greater NEG_DIST => wider crecent
double start_angle = atan (1 / NEG_DIST); // Start angle for the inside edge
double arc = M_PI - (2 * start_angle); // Arc of the inside edge
for (int i = 0; i <= N; i++)
{
// Outside edge
outside [i].x = cos ((M_PI / N) * i) * SIZE;
outside [i].y = sin ((M_PI / N) * i) * SIZE;
// Inside edge
inside [i].x = (cos (start_angle + ((arc / N) * i)) * neg_size) * SIZE;
inside [i].y = (sin (start_angle + ((arc / N) * i)) * neg_size - NEG_DIST) * SIZE;
}
这将生成一个月牙形的交叉多边形版本。它会为月牙的内部和外部弧线提供一组坐标。然后,您可以通过您喜欢的绘图方法来处理它们。
注意:内部和外部的端点重叠(我这样做是为了避免到处都有+/- 1)。我相信GL程序不会有问题,但如果您在使用此功能时出现错误,可能就是问题所在。