How draw Hyperboloids with OpenGL C++? - c++

I'm trying to draw quadrics in C ++ with OpenGL.
Quadrics are the Sphere, and Hyperboloides of a leaf and two leaves. To draw them I use only the parametric equations of each. The sphere if I drew
Example: The parametric equations of the Sphere are:
To draw the sphere with these equations, what I do in OpenGL is simply this for a sphere that is draw on the origin x0, y0 and z0 equal to zero:
void Sphere(){
GLfloat x, y, z, alpha, beta; // Storage for coordinates and angles
GLfloat radius = 1.0f;
int gradation = 20;
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
for (float alpha = 0.0; alpha < PI; alpha += PI/gradation)
{
glBegin(GL_TRIANGLE_STRIP);
for (beta = 0.0; beta < 2.01*PI; beta += PI/gradation)
{
x = radius*cos(beta)*sin(alpha);
y = radius*sin(beta)*sin(alpha);
z = radius*cos(alpha);
glVertex3f(x, y, z);
}
glEnd();
}
glutSwapBuffers();
}
I the result is this (a sphere):
Problem:
By applying the same logic to the draw hyperboloids, I do not get what I want. The parametric equations of the Hyperboloides are as follows:
When attempting to draw the hyperboloid of one sheet with the equations shown in the picture, this is the result:
If anyone knows anything about it, please if you can help me with this. Thank you all.
Note: I know there are other ways to draw a hyperboloid, but the way I draw them is through its parametric equations.

What is the code that produces this output, not the code that produces your sphere? Please provide a MCVE.
Here is my guess: the range of your loops produces only positive values of z, and you might try the range -PI to PI instead.

Related

opengl not filling in polygon

I'm trying to draw a filled in circle, but when I draw this, it only shows in wireframe, here is the code I'm using to draw:
void render_circle(Vec2 position, float radius, Vec4 colour) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColor4f(colour.x, colour.y, colour.z, colour.w);
glBegin(GL_LINE_LOOP);
int num_segments = 30; //#todo: make this scale for larger radius
for(int i = 0; i < num_segments; i++) {
float theta = 2.0f * math_pi * (float)i / (float)num_segments;
float x = radius * cosf(theta);
float y = radius * sinf(theta);
glVertex2f(position.x + x, position.y + y);
}
glEnd();
}
GL_LINE_LOOP is a line primitive type. If you want to draw a filled polygon, then you have to use a polygon primitive type. For instance GL_TRINAGLE_FAN.
It is only possible to correctly draw convex geometry. Concave polygons may not be represented correctly, by a primitive. A possibility to deal with this, is to split concave polygons into convex parts.

How to fill the shape, made up of GL_LINE_LOOP

I'm trying to make do water simulation. But I'm restricted to use 2D, So i started with just making the boundary of the sea by using sine wave, through Gl_Line_loop. but I'm just unable to fill it. I have tried changing it to the Gl_polygon mode but then i don't get the proper shape. here is the code:
here is the image of wave, i want to get filled
To tessellate the above, specify a top then a bottom vertex right along the line, then draw a triangle strip. i.e. for each (x, y) position along the sin wave, emit two vertices, the same x but y = 0 (the bottom). Then render a triangle strip.
Something like this:
glBegin(GL_TRIANGLE_STRIP);
for(x=-50;x<=50;x+=inc){
k = 2 * 3.14 / wavelength;
y = amplitude * sin(k * x);
glVertex3f(x, y-35, 0);
glVertex3f(x, y, 0);
}
glEnd();

OpenGL circle radius issue when drawing square

I have a function that draws a circle.
glBegin(GL_LINE_LOOP);
for(int i = 0; i < 20; i++)
{
float theta = 2.0f * 3.1415926f * float(i) / float(20);//get the current angle
float rad_x = ratio*(radius * cosf(theta));//calculate the x component
float rad_y = radius * sinf(theta);//calculate the y component
glVertex2f(x + rad_x, y + rad_y);//output vertex
}
glEnd();
This works dandy. I save the x, y and radius values in my object.
However when I try and draw a square with the following function call:
newSquare(id, red, green, blue, x, (x + radius), y, (y + radius));
I get the following image.
As you see, the square is nearly double as wide (looks more like the diameter). The following code is how I create my square box. As you can see it starts in the center of the circle in which it should. And should stretch out to the edge of the circle.
glBegin(GL_QUADS);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glEnd();
I can't seem to understand why this is!
If you're correcting the x-position for one object, you have to do it for all others as well.
However, if you continue this, you'll get into trouble very soon. In your case, only the width of objects is corrected but not their positions. You can solve all your problems by setting an orthographic projection matrix and you won't ever need to correct positions again. E.g. like so:
glMatrixMode(GL_PROJECTION); //switch to projection matrix
glOrtho(-ratio, ratio, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW); //switch back to model view
where
ratio = windo width / window height
This constructs a coordinate system where the top edge has y=1, the bottom edge y=-1 and the left and right sides have x=-ratio and x=ratio, respectively.

OpenGL circle drawing getting an ellipse

I'm trying to draw a circle in opengl, but i can't seem to get the right coordinates, so i always get an ellipsis no matter what method i use. The current code is as follows:
void Ball::Render() {
float center_position_x = _body->GetWorldCenter().x;
float center_position_y = _body->GetWorldCenter().y;
float radius = static_cast<b2CircleShape*>(_body->GetFixtureList()->GetShape())->m_radius;
glBegin(GL_LINE_STRIP);
for(float angle = 0; angle <= 360; ++angle) {
float angleInRadians = glm::radians(angle);
float x = glm::cos(angleInRadians);
float y = glm::sin(angleInRadians);
glVertex3f(x,y,0);
}
glEnd();
}
( I know that code should draw the circle at the origin, but even then it's not a perfect circle, if i understand correctly that should draw a circle at the origin with radius=1 )
The other methods i used were:
http://slabode.exofire.net/circle_draw.shtml
http://www.opengl.org/discussion_boards/showthread.php/167955-drawing-a-smooth-circle
This is my OpenGL window setup code (It's a stub program so i'm starting with hardcoded values):
gluOrtho2D(-10, 15, -10, 15);
Use gluOrtho2D(-WIDOWS_WIDTH, WIDOWS_WIDTH, -WINDOWS_HEIGHT, WINDOWS_HEIGHT);
By the way your are using fixed pipeline in 2013. With a vertex shader this would be much easy to understand.
The aspect ratio of your 2D projection matrix defined by gluOrtho2d must be same as the viewport/window on which you are rendering otherwise you'll notice distortions in the figures you are rendering. You can use the above gluOrtho2d statement or other way of writing it is -
float ar = (float)WindowWidth/WindowHeight;
gluOrtho2D(-1*ar, ar, -1, 1)

how to draw a spiral using opengl

I want to know how to draw a spiral.
I wrote this code:
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
GLfloat x,y,z = -50,angle;
glBegin(GL_POINTS);
for(angle = 0; angle < 360; angle += 1)
{
x = 50 * cos(angle);
y = 50 * sin(angle);
glVertex3f(x,y,z);
z+=1;
}
glEnd();
glutSwapBuffers();
}
If I don't include the z terms I get a perfect circle but when I include z, then I get 3 dots that's it. What might have happened?
I set the viewport using glviewport(0,0,w,h)
To include z should i do anything to set viewport in z direction?
You see points because you are drawing points with glBegin(GL_POINTS).
Try replacing it by glBegin(GL_LINE_STRIP).
NOTE: when you saw the circle you also drew only points, but drawn close enough to appear as a connected circle.
Also, you may have not setup the depth buffer to accept values in the range z = [-50, 310] that you use. These arguments should be provided as zNear and zFar clipping planes in your gluPerspective, glOrtho() or glFrustum() call.
NOTE: this would explain why with z value you only see a few points: the other points are clipped because they are outside the z-buffer range.
UPDATE AFTER YOU HAVE SHOWN YOUR CODE:
glOrtho(-100*aspectratio,100*aspectratio,-100,100,1,-1); would only allow z-values in the [-1, 1] range, which is why only the three points with z = -1, z = 0 and z = 1 will be drawn (thus 3 points).
Finally, you're probably viewing the spiral from the top, looking directly in the direction of the rotation axis. If you are not using a perspective projection (but an isometric one), the spiral will still show up as a circle. You might want to change your view with gluLookAt().
EXAMPLE OF SETTING UP PERSPECTIVE
The following code is taken from the excellent OpenGL tutorials by NeHe:
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
Then, in your draw loop would look something like this:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity();
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd();
Of course, you should alter this example code your needs.
catchmeifyoutry provides a perfectly capable method, but will not draw a spatially accurate 3D spiral, as any render call using a GL_LINE primitive type will rasterize to fixed pixel width. This means that as you change your perspective / view, the lines will not change width. In order to accomplish this, use a geometry shader in combination with GL_LINE_STRIP_ADJACENCY to create 3D geometry that can be rasterized like any other 3D geometry. (This does require that you use the post fixed-function pipeline however)
I recommended you to try catchmeifyoutry's method first as it will be much simpler. If you are not satisfied, try the method I described. You can use the following post as guidance:
http://prideout.net/blog/?tag=opengl-tron
Here is my Spiral function in C. The points are saved into a list which can be easily drawn by OpenGL (e.g. connect adjacent points in list with GL_LINES).
cx,cy ... spiral centre x and y coordinates
r ... max spiral radius
num_segments ... number of segments the spiral will have
SOME_LIST* UniformSpiralPoints(float cx, float cy, float r, int num_segments)
{
SOME_LIST *sl = newSomeList();
int i;
for(i = 0; i < num_segments; i++)
{
float theta = 2.0f * 3.1415926f * i / num_segments; //the current angle
float x = (r/num_segments)*i * cosf(theta); //the x component
float y = (r/num_segments)*i * sinf(theta); //the y component
//add (x + cx, y + cy) to list sl
}
return sl;
}
An example image with r = 1, num_segments = 1024:
P.S. There is difference in using cos(double) and cosf(float).
You use a float variable for a double function cos.