如何在OpenGL中绘制2D新月形或月亮形?我尝试过使用sin和cos,就像我画圈子一样,但因为新月里面有一个“切”,所以罪和cos看起来不够。我无法弄清楚如何在2个多边形之间进行交叉。所以我在想是否有绘制新月的数学公式?
答案 0 :(得分:2)
这在数学上并不正确,但它可能足以满足您的需求:
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
时,它会绘制一个非常薄的圆圈。您可以使用两个不同的丰满度值rightFullness
和leftFullness
,并始终将其中一个设置为1.0f
,以便您可以更改新月的方向。
答案 1 :(得分:1)
您可以绘制两个相互交叉的垂直椭圆。形成新月形,其中空间从其中一个日食中切出。在绘制时,可以使用按位NAND逻辑运算符删除交集。
glEnable(GL_COLOR_LOGIC_OP);
drawEllipse1();
glLogicOp(GL_NAND);
drawEllipse2();
漫长的做法是指定一组顶点,这些顶点形成您想要的形状的骨架。然后,您可以使用GL_LINES“连接点”来绘制您的形状。如果想要更平滑的形状,可以使用顶点作为Bezier / Catmull-Rom样条曲线的控制点,绘制连接所有顶点的平滑曲线。
答案 2 :(得分:0)
你可以试试这个:
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程序会很好用它,但是如果你有一个围栏帖子错误,那可能就是它的来源