开发者

Drawing a crescent shape in OpenGL

开发者 https://www.devze.com 2023-03-31 21:19 出处:网络
How can I draw a 2D crescent or moon shape in OpenGL? I have tried using sin and cos like how I did for drawing circles but because a crescent has a \"cut\" inside it, the sin and cos don\'t look enou

How can I draw a 2D crescent or moon shape in OpenGL? I have tried using sin and cos like how I did for drawing circles but because a crescent has a "cut" inside it, the sin and cos don't look enough. I couldn't figure out how I could do an intersection between 2 polygons either. So I'm thinking if there a mathematical formula for drawing the cresc开发者_高级运维ent?


This isn't mathematically correct, but it may be close enough to meet your needs:

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

or

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

At fullness=1, it will draw a circle of size scale while at fullness=-0.99f, it will draw a very thin cresent. You could use two different fullness values, rightFullness and leftFullness, and always set one of them to 1.0f so you can change the direction of the crescent.


You can draw two perpendicular ellipses that intersect each other. A crescent is formed with the space that is cut out from one of the eclipses. The intersection can be removed by using a bitwise NAND logical operator when drawing.

glEnable(GL_COLOR_LOGIC_OP);
drawEllipse1(); 
glLogicOp(GL_NAND);
drawEllipse2();

The long way of doing it is to specify a bunch of vertices that form a skeleton for the shape that you want. You can then 'connect the dots' with GL_LINES to draw your shape. If you want a smoother shape, you can use the vertices as control points for a Bezier/Catmull-Rom spline that would draw a smooth curve joining all your vertices.


You can try this:

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

This produces the intersected polys version of a crescent. It will give you an array of coordinates for an inside and outside arc for a crescent. Then you can feed these through your favorite draw method.

NOTE: The endpoints of inside and outside overlap (I did this so that I wouldn't have +/- 1's all over the place). I'm pretty sure a GL program will be fine with it, but if you have a fence post error with this, that may be where it came from

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号