here is my display method:
void display()
{
GLfloat sphere_vertices[3]={0.0,0.0,0.0};
int theta,phi;
float x,y,z;
int off_set;
off_set=5;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
for (theta=-90; theta<=90-off_set; theta+=off_set) {
for (phi=0; phi<=360-off_set; phi+=off_set)
{
//calculate X of sphere
x= cos(theta + off_set) * sin(phi + off_set);
//calculate Y of sphere
y = cos(theta + off_set) * cos(theta + off_set);
//calculate Z of sphere
z = sin(theta + off_set);
//store vertices
sphere_vertices[0]=x;
sphere_vertices[1]=y;
sphere_vertices[2]=z;
//plot new point
glVertex3fv(sphere_vertices);
printf("X is %f, Y is %f, Z is %f", x,y,z);
}
}
glEnd();
glFlush();
}
I am calculating the points on the surface of a sphere and then plotting each point. But the only thing I get are some pixel at the bottom-left corner of the screen
It seems like you are trying to render a sphere with radius of 1.0 consisting of about 180 / off_set slices of circles with 360 / off_set points. How did you come up with your x, y and z?
For each point, you could construct a unit length vector on, for example, the xy-plane from theta and then rotate it about the z-axis by phi and scale the resulting vector by the radius of the sphere.
After reviewing your math, make sure you have specified the model-view and projection matrices and note if you are using the standard cos/sin functions, they take radians, not degrees.
Related
The device I am using generates vectors like this;
How do I translate polar (angle and magnitude) from a left handed cordinate to a cartesian line, drawn on a screen where the origin point is the middle of a screen?
I am displaying the line on a wt32-sc01 screen using c++. There is a tft.drawline function but its references are normal pixel locations. In which case 0,0 is the upper left corner of the screen.
This is what I have so far (abbreviated)
....
int screen_height = tft.height();
int screen_width = tft.width();
// Device can read to 12m and reports in mm
float zoom_factor = (screen_width / 2.0) / 12000.0;
int originY = (int)(screen_height / 2);
int originX = (int)(screen_width / 2);
// Offset is for screen scrolling. No screen offset to start
int offsetX = 0;
int offsetY = 0;
...
// ld06 holds the reported angles and distances.
Coord coord = polarToCartesian(ld06.angles[i], ld06.distances[i]);
drawVector(coord, WHITE);
Coord polarToCartesian(float theta, float r) {
// cos() and sin() take radians
float rad = theta * 0.017453292519;
Coord converted = {
(int)(r * cos(rad)),
(int)(r * sin(rad))
};
return converted;
}
void drawVector(Coord coord, int color) {
// Cartesian relative the center of the screen factoring zoom and pan
int destX = (int)(zoom_factor * coord.x) + originX + offsetX;
int destY = originY - (int)(zoom_factor * coord.y) + offsetY;
// From the middle of the screen (origin X, origin Y) to destination x,y
tft.drawLine( originX, originY, destX, destY, color);
}
I have something drawing on the screen, but now I have to translate between a left handed coordinate system and the whole plane is rotated 90 degrees. How do I do that?
If I understood correctly, your coordinate system is with x pointing to the right and the y to the bottom and you used the formula for the standard math coordinate system where y is pointing up so multiplying your sin by -1 should do the trick (if it doesn't, try multiplying random things by -1, it often works for this kind of problems).
I assuming (from your image) your coordinate system has x going right y going up angle going from y axis clockwise and (0,0) is also center of your polar coordinates and your goniometrics accept radians then:
#include <math.h>
float x,y,ang,r;
const float deg = M_PI/180.0;
// ang = <0,360> // your angle
// r >= 0 // your radius (magnitude)
x = r*sin(ang*deg);
y = r*cos(ang*deg);
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.
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.
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.
I was just wondering how would I go about clipping a circle in a rectangular boundary box? I am currently using the Cohen–Sutherland algorithm for line clipping in my program and so far I've managed to get rectangles and polygons to clip. However, for circle clipping, I have no idea how I would accomplish this. I'm using the following to construct my circle:
glBegin(GL_POLYGON);
double radius = 50;
for(int angle = 0; angle <= 360; angle++ ){
float const curve = 2 * PI * (float)angle / (float)360;
glVertex2f(point.x + sin(curve) * radius, point.y + cos(curve) * radius);
}
glEnd();
My clipping algorithm is the same as the one here: http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm. However, it returns 2 points representing a new line to later be used to draw the clipped shape. So basically I've tried to do this:
line Lines[360] // an array with size 360 with data type line, which is a struct holding two points (x1, y1, x2, y2) of the new line returned by my clipping function.
double radius = 50;
for(int angle = 0; angle < 360; angle++){
float const currentCurve = 2 * PI * (float)angle / (float)360;
float const nextCurve = 2 * PI * (float)(angle+1) / (float)360;
int x1 = (int)(point[i].x + sin(currentCurve) * radius); // point is another struct holding only a single point.
y1 = (int)(point[i].y + cos(currentCurve) * radius);
x2 = (int)(point[i+1].x+ sin(nextCurve) * radius);
y2 = (int)(point[i+1].y + cos(nextCurve) * radius);=
// Clip the points with the clipping algorithm:
Lines[i] = Clipper(x1, y1, x2, y2);
}
// Once all lines have been clipped or not, draw:
glBegin(GL_POLYGON);
for(int i = 0; i < 360; i++){
glVertex2f(Lines[i].x1, Lines[i].y1);
glVertex2f(Lines[i].x2, Lines[i].y2);
}
glEnd();
Note that, I've drawn a circle on the screen with a mouse and and stored each 360 points into a struct array called point, which is apart of a linked list. So I have like 1 node representing one circle on the screen.
Anyway, with the above, my circle is not drawing clipped (or drawing at all for that matter) and my application crashes after a few mouse clicks.
Use the scissor test - read up on glScissor(): http://www.opengl.org/sdk/docs/man/xhtml/glScissor.xml