Cutting the bottom side of a circle - c++

// #include loads up library files, the order can matter
// generally load glut.h last
#include <stdio.h> // this library is for standard input and output
#include "glut.h"// this library is for glut the OpenGL Utility Toolkit
#include <math.h>
// this is the initialisation function, called once only
void init() {
glClearColor(0.0, 0.0, 1.0, 0.0); // set what colour you want the background to be
glMatrixMode(GL_PROJECTION); // set the matrix mode, we will look at this later
// set the projection window size in x an y.
gluOrtho2D(0.0, 500, 0.0, 500.0);
}
// this is the display function it is called when ever you want to draw something
// all drawing should be called form here
void circle() {
// draw circle
float theta;
glClear(GL_COLOR_BUFFER_BIT); // clear the screen using the background colour
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0); // set colour to red
for (int i = 0; i < 320; i++) {
theta = i * 3.142 / 180;
glVertex2f(190 + 50 * cos(theta), 250 + 70 * sin(theta));
}
glEnd();
glFlush(); // force all drawing to finish
}
// this has the effect of repeatedly calling the display function
void display() {
circle();
}
// as with many programming languages the main() function is the entry point for execution of the program
int main(int argc, char** argv) {
glutInit(&argc, argv); //perform the GLUT initialization
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // more initialisation
glutInitWindowSize(800, 600); // set window position
glutInitWindowPosition(0, 0); // set window size
glutCreateWindow("Circle"); // create a display with a given caption for the title bar
init(); // call init function defined above
glutDisplayFunc(display); // define what function to call to draw
// the last function in the program puts the program into infinite loop
glutMainLoop();
// this line exits the program
return 0;
}
I've added comments so you can understand my code. The code creates a big red circle, and cuts the bottom right side of the circle, but I want to the cut only the bottom side. How can I achieve this? I would really appreciate the help.
Like this:

If you want to cut a circle by a Secant line, then you have to define an start angle and an end angle and to specify the vertex coordinates form the point on the circle with the start angle to the point with the end angle.
A Full angle has 360 degrees (2*PI radians). The bottom (south) has an angle of -90 degrees.
If you want to cut a part at the bottom of the circle, then the start and the end angle can be calculated like this:
int cutsegment = 45;
int start = -90 + cutsegment / 2;
int end = 270 - cutsegment / 2;
for (int i = start; i <= end; i++) {
theta = i * 3.142 / 180;
glVertex2f(190 + 50 * cos(theta), 250 + 70 * sin(theta));
}

Related

how do i calculate glFrustum parameters?

I have this code:
/*
* This is a simple program that computes FPS
* by means of a circular buffer
*/
#include <GL/glut.h>
//#include <numeric>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
// Number of elements in the circular buffer
#define NELS 10
// Number of lines
#define NLINES 10000
// circular buffer used to compute frame rate
float circularBuffer[NELS];
int firstInd = 0, nEls = 0;
// function to get the number of elapsed ticks
uint32_t getTick()
{
struct timespec ts;
unsigned theTick = 0U;
clock_gettime( CLOCK_REALTIME, &ts );
theTick = ts.tv_nsec / 1000000;
theTick += ts.tv_sec * 1000;
return theTick;
}
// Function to compute real modulus and NOT remained as % does
inline int modulo(int a, int b) {
const int result = a % b;
return result >= 0 ? result : result + b;
}
// Compute sum of the elements in the circular buffer
float sumCircularBuffer()
{
int ind;
float sum = 0;
if (nEls > 0) {
for (ind=1; ind<=nEls; ind++) {
sum = sum + circularBuffer[modulo(firstInd-ind, NELS)];
}
}
return sum;
}
// accumulate buffer and update window title
void computeAndShowFrameRate(void)
{
static float lastTime = 0.0f;
static unsigned int frameCount = 0;
char windowTitle[100];
float sumFPS;
float currentTime = (float)getTick() * 0.001f;
// Initialize lastTime to the current time
if (lastTime == 0) {
lastTime = currentTime;
}
// increase frame count
frameCount++;
if (currentTime - lastTime > 1.0f) {
// insert the current fps in the circular buffer
circularBuffer[firstInd] = ((float)frameCount) / (currentTime - lastTime);
// update variable lastTime
lastTime = currentTime;
//circularBuffer[firstInd] = (float)frameCount;
firstInd = ((firstInd+1)%NELS);
if (nEls < NELS) {
nEls++;
}
frameCount = 0;
// sum elements in circular buffer
sumFPS = sumCircularBuffer();
snprintf(windowTitle, 100, "FPS = %6.2f", sumFPS/nEls);
// update window title
glutSetWindowTitle(windowTitle);
}
}
// display function
void display(void)
{
int currLineInd;
// get current frame rate
computeAndShowFrameRate();
// clear buffer
glClear (GL_COLOR_BUFFER_BIT);
for (currLineInd = 0; currLineInd<NLINES; currLineInd++) {
// draw line
glBegin(GL_LINES);
// random color
glColor3f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
// random first point
glVertex2f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
// random color
glColor3f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
// random second point
glVertex2f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
glEnd();
}
glFinish();
glutPostRedisplay();
}
// initialization function
void init (void)
{
// Use current time as seed for random generator
srand(time(0));
// select clearing color
glClearColor (0.0, 0.0, 0.0, 0.0);
// Orthographic projection
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
// Window size and mode
int main(int argc, char** argv)
{
// pass potential input arguments to glutInit
glutInit(&argc, argv);
// set display mode
// GLUT_SINGLE = single buffer window
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (400, 400);
glutInitWindowPosition (100, 100);
glutCreateWindow ("OpenGL Window");
// Call initialization routinesx
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
I have to replace the glOrtho function with glFrustum and get the same result.
I read the opengl guide on khronos and understood the differences between glOrtho and glFrustum but i can't figure out how to calculate the parameters.
How do I calculate the parameters to pass to the glFrustum function?
glFrustum() require 6 parameters to specify 6 clipping planes: left, right, bottom, top, near and far planes. A visual representation would be like this:
The values that will come up with depend on your implementation and the scale of the models you are working with. As mentioned above, if the projected geometry is in front of the near plane or behind the far plane it will be clipped thus it won't be visible.
To solve this you either have to recompute the parameters for the glFrustum() function(bad idea) or move the camera/scene along the z-axis.
References:
http://www.songho.ca/opengl/gl_transform.html
https://learnopengl.com/Getting-started/Coordinate-Systems
With Perspective projection the distnace to the near and far plane have to be grater than 0,
0 < near < far
because you want to define a Viewing frustum:
If the distance to the near plane is less than 0, the result is undefined (Usually the instruction has no effect at all).
See glFrustum:
void glFrustum( GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top,
GLdouble nearVal,
GLdouble farVal);
The distances left, right, bottom and top, are the distances from the center of the view to the side faces of the frustum, on the near plane. near and far specify the distances to the near and far plane of the frustum.
The geometry has to be between the near and the far plane, else it is clipped. Therefore, you have to move the shift along the z-axis in the negative direction (in negativ direction, because the view space z-axis points out of the view):
// initialization function
void init (void)
{
// [...]
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.1, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
}

Getting points equidstant from each other in openGL on a circle

I'm trying to write code for a weaving pattern in OpenGL.
Weaving Pattern
Pic
Now, I am trying to write code for a similar pattern using a circle.
I draw a circle using points, each point is drawn using cos and sin functions.
I understand this is not as efiicient as SeigeLord's method as it makes higher use of resources.
I am able to get the circle, I want to get points on it's circumference.
My code :
#include<GL/glut.h>
#include<stdio.h>
#include<math.h>
int n, r;
void display()
{
int i, j;
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-50, 50, -50, 50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
for (i = 0;i <= 360;i += 1)
{
glBegin(GL_POINTS);
glVertex2f(r*cos(i), r*sin(i));
glEnd();
}
/*for (i = 0;i < 360;i += 10)
{
glBegin(GL_LINES);
glVertex2f(r*cos(i), r*sin(i));
glVertex2f(r*cos(i + 300), r*sin(i + 300));
glEnd();
}*/
glFlush();
}
int main(int argc, char **argv)
{
r = 30;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(300, 50);
glutInitWindowSize(800, 800);
glutCreateWindow("Cylinder");
glutDisplayFunc(display);
glutMainLoop();
}
I tried using the commented code for getting lines between points 300 degrees apart, do this every at point 10 degrees apart.(It looks good at 3 degrees apart).
Now, this obviously doesn't work as we use trigonometric functions, which won't space out the points equally.
I hope you understand my question, how can I get points on the circle equally apart?
One solution, I think might work is, while plotting the points itself, if I use an array to save every nth point, I may get equidistant points. Am I right? Is there any other way of getting the points?
Please do correct me if I am wrong anywhere above, I am just newbie here.
Note that sin and cos take their input in radians(i.e. 0 to 2* pi), not degrees(0 to 360). So your code should probably be
for (i = 0;i <= 360;i += 1)
{
glBegin(GL_POINTS);
glVertex2f(r*cos(i * (M_PI / 180.)), r*sin(i* (M_PI / 180.)));
glEnd();
}
edit:
To get N equidistant point we have to put them (1/N) part of the circle away from each other:
for (i = 0;i < N;i += 1)
{
double angle = i * (2.0 * M_PI / N);
glBegin(GL_POINTS);
glVertex2f(r*cos(angle), r*sin(angle));
glEnd();
}

Need help understanding why nothing is drawing to screen in OpenGL, glut

Can anyone explain what's going on or not going on so that I can correct it. Here's the code so far from a .cpp file. Running in Visual Studio Community 2015.
#include <windows.h>
#include <gl/GL.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <math.h>
#define M_PI 3.14159265358979323846
const int screenWidth = 640;
const int screenHeight = 480;
Here aa, bb, cc, & dd are used to map the world coordinates to screen coordinates. I printed them out to make sure it was working correctly and the coordinates are being calculated correctly. In this case 0 < radius <= 5.
void drawHex(GLdouble radius, GLdouble aa, GLdouble bb, GLdouble cc, GLdouble dd) {
glBegin(GL_POLYGON);
for (int i = 0; i < 6; i++) {
glVertex2d(((cos(i / 6.0 * 2 * M_PI) * radius) * aa) + cc,
((sin(i / 6.0 * 2 * M_PI) * radius) * bb) + dd);
}
glEnd();
glFlush();
}
Here I calculate A, B, C, and D to map the world to the view and pass them to the drawHex function.
void myDisplay(void) {
glClear(GL_COLOR_BUFFER_BIT);
GLdouble winWidth = glutGet(GLUT_WINDOW_WIDTH);
GLdouble winHeight = glutGet(GLUT_WINDOW_HEIGHT);
GLdouble A, B, C, D;
glViewport((GLint)0, (GLint)0, (GLint)winWidth, (GLint)winHeight);
A = winWidth / 10.0;
B = winHeight / 10.0;
C = 0 - (A * -5.0);
D = 0 - (B * -5.0);
drawHex(0.5, A, B, C, D);
}
Program inits and main loop.
void myInit() {
glClearColor(0.93, 0.93, 0.93, 0.0);
glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-5.0, 5.0, -5.0, 5.0);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(screenWidth, screenHeight);
glutInitWindowPosition(100, 150);
glutCreateWindow("Window");
myInit();
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
All I get is a blank window with the background color. I'm expecting a hexagon in the middle of the view (not yet resized to maintain a proper aspect ratio).
In your call to gluOrtho2D you pass [-5, 5] as bounds on both dimensions. In your calculation, anything going beyond this would be clipped out and will not be visible. Lets see if this is the case.
The aa, bb, cc and dd you pass are constants; they always remain: 64, 48, 320 and 240. The value you'd get after correcting the above issue will always be within [-1, 1] since that's the codomain of cos and sin functions. This gets multiplied with radius * aa and added to cc. So worst case would be (1 * 0.5 * 64) + 320 = 352, which is clearly outside the -5 boundary you'd set via gluOrtho2D.
The same observations apply to y too. Do your math on paper first and then code this up. Make sure all the boundary conditions are within limits.
It's recommended that you pass GLUT_DOUBLE to avoid flickers and as the other answer mentions, you need swap buffers at the end of the display function for double buffering to work. Read the answer to Difference between single buffered(GLUT_SINGLE) and double buffered drawing(GLUT_DOUBLE) for details. Also, you don't need to call glViewport on every rendering call, instead put it in your init function.
I'm unfamiliar with glut but try adding glutSwapBuffers(); to the end of your drawing function. In OpenGL, there is always one frame being displayed to the user and one frame that is being rendered. Swapbuffers swaps these two frames: it sends the rendered frame to the user and pulls back the previous frame for further rendering.

How do you rotate an object in OpenGL a certain number of degrees? Is there a built-in command or do I have to use a formula?

How do you rotate an object in OpenGL a certain number of degrees? Is there a built-in command or do I have to use a formula? I've been stuck on this issue for days. Its a program that draws a shape under my mouse as it moves.
Say I have a drawing function:
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glColor3f ( 1, 1, 1 );
glBegin (toggle_type );
//Where cur_x and cur_y is the current mouse location that gets auto-updated
//ratiox is 0.7 and ratioy is 0.6
if (toggle_type==GL_QUADS) //rectangle from (-length, -length) to (length,length)
{
glVertex2f ( cur_x- length*ratiox, cur_y + length*ratioy );
glVertex2f ( cur_x+ length*ratiox, cur_y + length*ratioy );
glVertex2f ( cur_x+ length*ratiox, cur_y- length*ratioy );
glVertex2f ( cur_x- length*ratiox, cur_y- length*ratioy );
}
else if (toggle_type==GL_TRIANGLES)//triangle with vertices (-length, -length), (length, -length), (0, length).
{
glVertex2f ( cur_x- length, cur_y - length );
glVertex2f ( cur_x+length, cur_y - length );
glVertex2f ( cur_x, cur_y + length );
}
else if (toggle_type==GL_LINES) //line brush with vertices (0,-length), (0,length)
{
glVertex2f ( cur_x, cur_y - length );
glVertex2f ( cur_x, cur_y + length );
}
I can't just use glRotatef() before I use glBegin can I? I want to rotate the way it's drawn around my mouse a certain number of degrees. Is there not a built in function? What formula should I look into using if not?
You need to learn how to use OpenGL transforms: glTranslate, glRotate, and glScale.
Translate means "move stuff." Scale means "make stuff bigger or smaller." Rotate means what it sounds like it means.
With OpenGL transforms, it helps to think in terms of changing the coordinate system every time you issue a transform.
So to do this, let's saying you're drawing a box around the cursor. First translate to the position of the mouse cursor. That's where you want to do your drawing. Then rotate the coordinate system around the cursor, so you can draw a box easily without having to do funny stuff with sines and cosines and angles. Then, scale the object to whatever size you want it to be -- this shrinks or expands the coordinate system. Finally, just draw a one-unit-across box around the origin (0,0), and it will appear on screen in the location, rotation, and size you want.
If you try to rotate before you translate, you'll get incorrect results. The technical reason for this is that OpenGL post-multiplies transform matrices by vertex vectors.
And, yes, you should do all transforms outside of your begin/end block. Your begin/end block is just for specifying vertices, normals, etc.
I was just playing with freeglut to see if multi windows can work (seem it does!), and i was using rotations to see some change in display:
#include <cstdio>
#include <cassert>
#include <GL/freeglut.h>
#define DEGREES_X_SEC 10.0
int w_dc, w_ds;
float yRotationAngle;
void DrawSphere()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(yRotationAngle, .3f, .3f, .3f);
glutWireSphere(.3, 20, 20);
glFlush();
glutSwapBuffers();
}
void DrawCube()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(yRotationAngle, .2f, .2f, .2f);
glutWireCube(.5);
glFlush();
glutSwapBuffers();
}
void Idle()
{
static int previousTime = 0;
int currentTime = glutGet(GLUT_ELAPSED_TIME);
if (currentTime - previousTime > 10)
{
float x_frame = (DEGREES_X_SEC / 1000.0) * (currentTime - previousTime);
yRotationAngle += x_frame;
glutPostWindowRedisplay(w_dc);
glutPostWindowRedisplay(w_ds);
previousTime = currentTime;
}
}
// other code here....
int main(int argc, char *argv[])
{
// let glut eat any command line args that it owns
glutInit(&argc, argv);
// full color, double buffered
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(800, 600);
w_dc = make_window("cube", DrawCube);
glutPositionWindow(100, 100);
w_ds = make_window("sphere", DrawSphere);
glutPositionWindow(200, 200);
// not bound to any window
glutIdleFunc(Idle);
glutMainLoop();
return 0;
}
HTH, of course requires freeglut...
you need to focus an allegraic material like c 5 and m2, this is automatic rotation and will be instantly rewarded by the government because it shows abnormal behaviour, let me know if this helps.
Rog.

shooting bullets opengl

I have the following code which draws me a "spacecraft" which I'm able to ctrol with my arrow keys to spin clockwise and anti-clockwise. I'm trying to get the spacecraft shoot bullets when another key is pressed (it can be any key). I am so new to OpenGL that I'm confused on how to do it. I have tried so many methods but none of them work. Below is the code where I draw my spaceship and how I control it. Can someone help me with the bullets please?
struct
{
float rotateSpaceCraft;
} scene;
void SpaceCraft (){
glBegin(GL_TRIANGLE_FAN);
//specify the vertices to draw Ship in 2d space
glColor3f(1.0, 0.0, 1.0);
glVertex2f( X_CENTRE + LENGTH * 0, Y_CENTRE + LENGTH * 12);
glColor3f(1.0, 1.0, 0.0);
glVertex2f( X_CENTRE - LENGTH * 8, Y_CENTRE - LENGTH * 8);
glColor3f(0.0, 1.0, 1.0);
glVertex2f( X_CENTRE - LENGTH * 0, Y_CENTRE - LENGTH * 0);
glColor3f(1.0, 0.0, 0.0);
glVertex2f( X_CENTRE + LENGTH * 8, Y_CENTRE - LENGTH * 8);
glEnd();
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT); /* clear window */
glColor3f(1.0, 1.0, 1.0); /* white drawing objects */
/* define object to be drawn as a square polygon */
glPushMatrix();
glRotatef(scene.rotateSpaceCraft, 0.0, 0.0, 1.0);
SpaceCraft();
glPopMatrix();
glutSwapBuffers();
glFlush(); /* execute drawing commands in buffer */
}
static void specialKey(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_LEFT:
scene.rotateSpaceCraft = fmod(scene.rotateSpaceCraft + 7, 360);
break;
case GLUT_KEY_RIGHT:
scene.rotateSpaceCraft = fmod(scene.rotateSpaceCraft - 7, 360);
break;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use single-buffered window and RGBA colour model */
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize (600, 600);
/* window upper left corner at (100, 100) */
glutInitWindowPosition (250, 50);
/* creates an OpenGL window with command argument in its title bar */
glutCreateWindow ("Asteroids");
glutKeyboardFunc(key);
glutSpecialFunc(specialKey);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
Step by Step you could do it this way:
Create a spaceship object which holds rotation of the spaceship
Create a bullet object ( struct or class ), which holds the vector of the bullet, the start position ( and the time at which the bullet has been fired, you will need it later )
Create a scene object which holds a list of all bullets fired and the spaceship
Catch Key Events from Windows or any other platform you are using
When the bullet is fired, use the rotation and position of your spaceship to determine the position of the new bullet and the vector of it.
Some pseudo code for the structure:
struct Bullet {
Vector3 Position;
Vector3 Rotation;
}
struct {
struct {
Vector3 Position;
Vector3 Rotation;
} Ship;
Vector<Bullet*> Bullets;
} Scene;
....:
void Update(void) {
if (Key.IsPressed(Space)) {
CreateNewBullet();
}
}
void UpdateBullets(void) {
for (Bullet bullet in Scene.Bullets)
{
// Delete bullets here if not longer used
// and move all others
}
}
void Draw(void) {
// Draw spaceship here
....
// Draw bullets
for (Bullet bullet in Scene.Bullets) {
DrawBullet(bullet);
}
}
I also recommend using VBO but if you want to do it with the deprecated set then what you are looking for is to render a bullet similar to your SpaceCraft() function. A bullet will need to travel so you will need to translate its position every frame.
glTranslatef(x, 0.0f, 0.0f);
This will translate the bullet x amount in the x axis. Therefore you will need a variable that increments certain amount per frame and passes it to your new Bullet() function. You can store the translation X amount just like you did with struct
{
float rotateSpaceCraft;
} scene;