Using modulo operator to alternate between even and odd numbered objects - c++

Example Screenshot
I am new to programming in c++ and I am stuck on this homework problem. I need to draw a grid of trees. The dimensions of this grid must be the parameters of the function. So, if you call forest(2,2) it will make 4 trees, forest (3,5) will render 15. Additionally, the trees need to alternate between pine and tree. I just can't seem to get my forest to match the example screenshot and would love any help to steer me in the right direction.
#include "cgt215.h"
#include "demo.h"
#include <time.h>
using namespace std;
using namespace cgt215;
// Place global variables here
int mode = 1;
int framesDrawn = 0;
float secondsPassed = 0;
static int counter;
int x = 0;
int y = 0;
int parameterX = 5;
int parameterY = 4;
// Declare new functions here
void drawPine(double x, double z);
void drawTree(double x, double z);
void trunk(void);
void modeSwitch(char keyToPress, int modeToSwitchTo);
void forest(int, int);
void renderFrame(float lastFrameDuration) {
// Place interactive/animated drawing code here
enable3d();
//Frames Drawn
framesDrawn++;
secondsPassed += lastFrameDuration;
modeSwitch('w', 2);
if (mode == 2) {
forest(parameterX,parameterY);
}
void drawPine(double x, double z) {
glPushMatrix();
glTranslated(x, 0.0, z);
trunk();
glPushMatrix();
glTranslated(0.0, 15.0, 0.0);
glScaled(1.0, 0.75, 1.0);
drawCone();
glPopMatrix();
glPopMatrix();
return;
}
void drawTree(double x, double z) {
glPushMatrix();
glTranslated(x, 0.0, z);
trunk();
glPushMatrix();
glTranslated(0.0, 40.0, 0.0);
drawSphere(25.0);
glPopMatrix();
glPopMatrix();
return;
}
void trunk(void) {
glPushMatrix();
glScaled(1.0, 4.0, 1.0);
glRotated(90.0, 1.0, 0.0, 0.0);
drawTorus(5.0, 6.0);
glPopMatrix();
}
void modeSwitch(char keyToPress, int modeToSwitchTo) {
if (keyPressed(keyToPress)) {
mode = modeToSwitchTo;
}
}
void forest(int, int) {
for (x = 0; x < parameterX; x++)
for (y = 0; y < parameterY; y++)
if (x % 2 == 0) {
drawTree(-(9 * 100 / 2) + x * 100, -(9 * 100 / 2) + y * 100);
else {
drawPine(-(9 * 100 / 2) + x * 100, -(9 * 100 / 2) + y * 100);
}
}
}

Let's take a look at 2D arrangement in ASCII of the trees and pines you want to see.
T P T P T
P T P T P
T P T P T
The places where T are found, (x+y) is even.
The places where P are found, (x+y) is odd.
The code must reflect that.
void forest(int parameterX, int parameterY) {
for (x = 0; x < parameterX; x++) {
for (y = 0; y < parameterY; y++) {
// Check whether x+y is even. not just x
if ( (x+y) % 2 == 0) {
drawTree(-(9 * 100 / 2) + x * 100, -(9 * 100 / 2) + y * 100);
}
else {
drawPine( ... );
}
}
}
}

Related

Bezier curve by control points is not working

I'm trying to make Bezier curve by control point.
I have some examples and followed it. But it did not work.
It shows the line is going to (0, 0) points during working.
I still don't get it why.
Here's the code in the C++ language, using OpenGL.
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <gl/glut.h>
#include <gl/GLU.h>
#include <gl/GL.h>
#include <math.h>
#define CTRL_COUNT 100
void display();
void init();
float getNextBezierPointX(float t);
float getNextBezierPointY(float t);
void drawline();
int ctrlPointsCount;
int ctrlPointsX[CTRL_COUNT], ctrlPointsY[CTRL_COUNT];
int X1[20] = { 10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105 };
int Y1[20] = { 50,60,40,70,40,60,35,80,45,55,30,60,40,60,40,55,35,70,40,50 };
void main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(500, 300);
glutCreateWindow("Bezier");
glutDisplayFunc(display);
init();
glutMainLoop();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
ctrlPointsCount = 20;
for (int i = 0; i < 20; i++) {
ctrlPointsX[i] = X1[i];
ctrlPointsY[i] = Y1[i];
}
drawline();
glFlush();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glPointSize(8.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 128.0, 0.0, 96.0);
}
float getNextBezierPointX(float t) {
float x = 0.0;
int c;
for (int i = 0; i < ctrlPointsCount; i ++) {
if (i == 0 || i == ctrlPointsCount - 1)
c = 1;
else
c = ctrlPointsCount - 1;
x = x + c * pow(t, i) * pow(1 - t, ctrlPointsCount - 1 - i) * ctrlPointsX[i];
}
return x;
}
float getNextBezierPointY(float t) {
float y = 0.0;
int c;
for (int i = 0; i < ctrlPointsCount; i ++) {
if (i == 0 || i == ctrlPointsCount - 1)
c = 1;
else
c = ctrlPointsCount - 1;
y = y + c * pow(t, i) * pow(1 - t, ctrlPointsCount - 1 - i) * ctrlPointsY[i];
}
return y;
}
void drawline() {
float x, y;
for (int i = 0; i < 20; i++) {
glBegin(GL_POINTS);
glVertex2i(ctrlPointsX[i], ctrlPointsY[i]);
glEnd();
glFlush();
}
float oldX = ctrlPointsX[0], oldY = ctrlPointsY[0];
for (double t = 0.0; t <= 1.0; t += 0.01) {
x = getNextBezierPointX(t);
y = getNextBezierPointY(t);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex2f(oldX, oldY);
glVertex2f(x, y);
glEnd();
glFlush();
oldX = x;
oldY = y;
}
}
For a bezier curve like this you have to calculate Bernstein polynomials:
double factorial(int n)
{
double x = 1.0;
for (int i = 1; i <= n; i++)
x *= (double)i;
return x;
}
double Ni(int n, int i)
{
double a1 = factorial(n);
double a2 = factorial(i);
double a3 = factorial(n - i);
double ni = a1/ (a2 * a3);
return ni;
}
double Bernstein(int n, int i, double t)
{
double ti = (t == 0.0 && i == 0) ? 1.0 : pow(t, i); /* t^i */
double tni = (n == i && t == 1.0) ? 1.0 : pow((1 - t), (n - i)); /* (1 - t)^i */
double basis = Ni(n, i) * ti * tni; //Bernstein basis
return basis;
}
The code to create the curve may look like this:
struct vec2
{
double x, y;
};
vec2 getBezierPoint(float t, int n, int x[], int y[] )
{
vec2 pt{ 0.0, 0.0 };
for (int i = 0; i < n; i ++) {
double b = Bernstein( n - 1, i, t );
pt.x += b * x[i];
pt.y += b * y[i];
}
return pt;
}
float oldX = ctrlPointsX[0], oldY = ctrlPointsY[0];
for (double t = 0.0; t <= 1.0; t += 0.01)
{
vec2 pt = getBezierPoint( t, ctrlPointsCount, ctrlPointsX, ctrlPointsY );
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex2f(oldX, oldY);
glVertex2f((float)pt.x, (float)pt.y);
glEnd();
glFlush();
oldX = (float)pt.x; oldY = (float)pt.y;
}
An other solution is provided in the answer to the Stack Overflow question How do I implement a Bézier curve in C++?:
#include <vector>
vec2 getBezierPoint2( float t, int n, int x[], int y[] )
{
std::vector<double> tmpx( n ), tmpy( n );
for ( int i=0; i<n; ++ i )
{
tmpx[i] = x[i];
tmpy[i] = y[i];
}
int i = n - 1;
while (i > 0)
{
for (int k = 0; k < i; k++)
{
tmpx[k] = tmpx[k] + t * ( tmpx[k+1] - tmpx[k] );
tmpy[k] = tmpy[k] + t * ( tmpy[k+1] - tmpy[k] );
}
i--;
}
return { tmpx[0], tmpy[0] };
}
But may be the result is not what you expect it to be, because you create a Higher-order Bézier curve which results in a very flat curve:
Maybe you want to connect any number of points with square bezier curves: Quadratic Bézier Curve: Calculate Points

How to draw a Bezier curve with C++ in OpenGL using floating point values

I am trying to draw a Bezier curve in OpenGL using floating point values. I have tried using many different code examples. My current code below, runs ,but does not show the curve on screen. The usual way to draw Bezier curves are with integer values, which means using the GLUORTHO2D() function for drawing the curve. But I want to draw a curve using floating point values. Such as x range(-1,1) and y range(-1,1).
like if x=(500) then consider it (-1 to 1) and if y=(800) then consider it (-1,1).
I have already tried using integer values and it worked for me. my code using integer values is below:
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#define CTRL_COUNT 100
int ctrlPointsCount;
int ctrlPointsX[CTRL_COUNT], ctrlPointsY[CTRL_COUNT];
int X1[3]={20,25,20}, Y1[3]={5,24,38}; //first point(x1[0],y1[0]) second(x1[1],y1[1]) third(x1[2],y1[2])
void myInit()
{
glClearColor(0.0,0.0,0.0,0.0);
glColor3f(1.0,0.0,0.0);
glPointSize(8.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,128.0,0.0,96.0);
}
//p(t)=(1-t)^3*p0+3t(1-t)^2*p1+3t^2(1-t)p2+t^3p3
float getNextBezierPointX(float t)
{
float x=0.0;
for(int i=0; i<ctrlPointsCount; i++)
{
int c;
if(i==0 || i==ctrlPointsCount-1)
c = 1;
else
{
c = ctrlPointsCount-1;
}
x += c * pow(t, i) * pow(1-t, ctrlPointsCount-1-i) * ctrlPointsX[i];
}
return x;
}
float getNextBezierPointY(float t)
{
float y=0.0;
for(int i=0; i<ctrlPointsCount; i++)
{
int c;
if(i==0 || i==ctrlPointsCount-1)
c = 1;
else
{
c = ctrlPointsCount-1;
}
y += c * pow(t, i) * pow(1-t, ctrlPointsCount-1-i) * ctrlPointsY[i];
}
return y;
}
void drawline()
{
// draw control points using red color
for(int i=0; i < 3; i++)
{
glBegin(GL_POINTS);
glVertex2i(ctrlPointsX[i], ctrlPointsY[i]);
glEnd();
glFlush();
}
// draw bezier curve using control poitns by calculating next points using cubic bezier curve formula
float oldX=ctrlPointsX[0], oldY=ctrlPointsY[0];
for(double t = 0.0;t <= 1.0; t += 0.01) {
float x = getNextBezierPointX(t);
float y = getNextBezierPointY(t);
//glColor3f(1.0,t,1.0);
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINES);
glVertex2f(oldX, oldY);
glVertex2f(x, y);
glEnd();
glFlush();
oldX = x;
oldY = y;
}
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
ctrlPointsCount=3;
for(int i=0;i<3;i++)
{
ctrlPointsX[i] = X1[i];
ctrlPointsY[i] = Y1[i];
}
drawline();
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,150);
glutCreateWindow("Bezier Curve");
glutDisplayFunc(myDisplay);
myInit();
glutMainLoop();
return 0;
}
But when i tried using floating point values , it does not work for me. It does not show the curved line on screen. My code using floating point values is below:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
using namespace std;
#define CTRL_COUNT 100
int ctrlPointsCount;
int ctrlPointsX[CTRL_COUNT], ctrlPointsY[CTRL_COUNT];
double X1[3] = { 0.26015037593985, 0.43609022556391, 0.6 }, Y1[3] = { 0.946875, 0.884375, 0.946875 };
//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
}
float getNextBezierPointX(float t)
{
float x = 0.0;
for (int i = 0; i<ctrlPointsCount; i++)
{
int c;
if (i == 0 || i == ctrlPointsCount - 1)
c = 1;
else
{
c = ctrlPointsCount - 1;
}
x += c * pow(t, i) * pow(1 - t, ctrlPointsCount - 1 - i) * ctrlPointsX[i];
}
return x;
}
float getNextBezierPointY(float t)
{
float y = 0.0;
for (int i = 0; i<ctrlPointsCount; i++)
{
int c;
if (i == 0 || i == ctrlPointsCount - 1)
c = 1;
else
{
c = ctrlPointsCount - 1;
}
y += c * pow(t, i) * pow(1 - t, ctrlPointsCount - 1 - i) * ctrlPointsY[i];
}
return y;
}
void drawline()
{
// draw control points using red color
for (int i = 0; i < 3; i++)
{
glBegin(GL_POINTS);
glVertex2i(ctrlPointsX[i], ctrlPointsY[i]);
glEnd();
glFlush();
}
// draw bezier curve using control poitns by calculating next points using cubic bezier curve formula
float oldX = ctrlPointsX[0], oldY = ctrlPointsY[0];
for (double t = 0.0; t <= 1.0; t += 0.01)
{
float x = getNextBezierPointX(t);
float y = getNextBezierPointY(t);
//glColor3f(1.0,t,1.0);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex2f(oldX, oldY);
glVertex2f(x, y);
glEnd();
glFlush();
oldX = x;
oldY = y;
}
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
float _angle = 0.0;
float _cameraAngle = 0.0;
float _ang_tri = 0.0;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); //Reset the drawing perspective
ctrlPointsCount = 3;
for (int i = 0; i<3; i++)
{
ctrlPointsX[i] = X1[i];
ctrlPointsY[i] = Y1[i];
}
drawline();
glutSwapBuffers();
}
void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}
_ang_tri += 2.0f;
if (_ang_tri > 360) {
_ang_tri -= 360;
}
glutPostRedisplay(); //Tell GLUT that the display has changed
//Tell GLUT to call update again in 25 milliseconds
glutTimerFunc(25, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1331, 641);
glutInitWindowPosition(0, 0);
//Create the window
glutCreateWindow("Our cg project");
initRendering();
//Set handler functions
glutDisplayFunc(drawScene);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0); //Add a timer
glClearColor(0.0, 0.7, 1.5,0.0);
glutMainLoop();
return 0;
}
The problem is this here:
int ctrlPointsX[CTRL_COUNT], ctrlPointsY[CTRL_COUNT];
double X1[3] = { 0.26015037593985, 0.43609022556391, 0.6 }, Y1[3] = {0.946875, 0.884375, 0.946875 };
for (int i = 0; i<3; i++)
{
ctrlPointsX[i] = X1[i];
ctrlPointsY[i] = Y1[i];
}
ctrlPointsX and ctrlPointsYcan only hold integer values. So when you do ctrlPointsX[i] = X1[i] and ctrlPointsY[i] = Y1[i] you are converting the floats to integers, which will round them down. So all your controlPoints will be 0.
You have to declare the controlPoints arrays as type double too:
double ctrlPointsX[CTRL_COUNT], ctrlPointsY[CTRL_COUNT];
double X1[3] = { 0.26015037593985, 0.43609022556391, 0.6 }, Y1[3] = {0.946875, 0.884375, 0.946875 };
This should fix your problem.

Drawing N-Pointed Star in OpenGL - C++

I've written a code that inputs n and draws N-pointed star,
just like this one:
when n=5 and filed
the problem that is whenever n=7 or 8 or 16 or 25...
I get a problem in the star drawing it becomes like this :
when n=7 and filled
Here's my code:
#include <iostream>
#include <ctime>
#include <vector>
#include <glut.h>
using namespace std;
float starCenterX, starCenterY, starRadius;
int numPoints;
bool bDrawFill = false;
void DrawStar (float cx, float cy, float radius, int numPoints);
void DrawStarFilled (float cx, float cy, float radius, int numPoints);
float width, height; // global variables to store window width and height
// render text
void renderBitmapString (float x, float y, float z, void* font, const char* string)
{
const char *c;
glRasterPos3f (x, y,z);
for (c = string; *c != '\0'; c++)
glutBitmapCharacter (font, *c);
}
void init ()
{
glClearColor (1.0, 1.0, 1.0, 0.0); // set display-window color to white
}
void reshape (int width, int height)
{
::width = width;
::height = height;
glViewport (0, 0, width, height);
glMatrixMode (GL_PROJECTION); // set projection parameters
glLoadIdentity ();
gluOrtho2D (0.0, width, 0.0, height);
glMatrixMode (GL_MODELVIEW); // set projection parameters
glLoadIdentity ();
}
void display ()
{
glClear (GL_COLOR_BUFFER_BIT); // clear display window
glColor3f (0, 0, 1);
renderBitmapString (10, height - 20, 0, GLUT_BITMAP_TIMES_ROMAN_24, "Name : Saif Badran");
renderBitmapString (10, height - 50, 0, GLUT_BITMAP_TIMES_ROMAN_24, "ID : 0142852");
renderBitmapString (10, height - 80, 0, GLUT_BITMAP_TIMES_ROMAN_24, "Section : 2");
DrawStar(starCenterX,starCenterY,starRadius,numPoints);
if(bDrawFill)
DrawStarFilled(starCenterX,starCenterY,starRadius,numPoints);
glFlush (); // process all openGl routines as quickly as possible
}
void processNormalKeys (unsigned char key, int x, int y)
{
if(key=='w' || key=='W')
starCenterY+=4;
else if(key=='z' || key=='Z')
starCenterY-=4;
else if(key=='a' || key=='A')
starCenterX-=4;
else if(key=='d' || key=='D')
starCenterX+=4;
else if(key=='f' || key=='F')
bDrawFill = (bDrawFill==1?0:1);
}
void mouseClick (int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
starCenterX = x;
starCenterY = height - y;
}
}
void activeMouseMotion (int x, int y)
{
starRadius = abs(starCenterX-x);
}
void main (int argc, char** argv)
{
cout<<"Enter number of points : ";
cin>>numPoints;
numPoints = (numPoints < 2) ? 2 : numPoints;
glutInit (&argc, argv); // initialize GLUT
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowPosition (20, 20); // set top left display window position
glutInitWindowSize (600, 600); // set display window width and height
glutCreateWindow ("Homework#2 : Star Drawing"); // create display window
init (); // execute initialization function
glutKeyboardFunc (processNormalKeys);
glutMouseFunc (mouseClick);
glutMotionFunc (activeMouseMotion);
glutReshapeFunc (reshape);
glutDisplayFunc (display); // send graphics to display window
glutIdleFunc (display);
glutMainLoop (); // dispaly everthing and wait
}
void DrawStar (float cx, float cy, float radius, int numPoints)
{
const float DegToRad = 3.14159 / 180;
glColor3f(1.0,0.0,0.0);
glBegin (GL_POINTS);
int count = 1;
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;
if(count%2!=0)
glVertex2d (cx + cos (DegInRad) * radius, cy + sin (DegInRad) * radius);
else
glVertex2d ((cx + cos (DegInRad) * radius/2), (cy + sin (DegInRad) * radius/2));
count++;
}
glEnd();
glBegin (GL_LINE_LOOP);
count = 1;
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;
if(count%2!=0)
glVertex2d (cx + cos (DegInRad) * radius, cy + sin (DegInRad) * radius);
else
glVertex2d ((cx + cos (DegInRad) * radius/2), (cy + sin (DegInRad) * radius/2));
count++;
}
glEnd();
}
void DrawStarFilled (float cx, float cy, float radius, int numPoints)
{
const float DegToRad = 3.14159 / 180;
glBegin (GL_TRIANGLE_FAN);
int count = 1;
glVertex2f(starCenterX, starCenterY);
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;
if(count%2!=0)
glVertex2d (cx + cos (DegInRad) * radius, cy + sin (DegInRad) * radius);
else
glVertex2d ((cx + cos (DegInRad) * radius/2), (cy + sin (DegInRad) * radius/2));
count++;
}
glEnd();
}
The issue is in this line:
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
For numPoints = 5, for each step i will be incremented with 360/(2*5) = 36.
For numPoints = 7, for each step i will be incremented with 360/(2*7) = 25 (integer division, truncating 25.714... to 25). So, at each step there is a 0.714.. degrees loss. Cummulated, this is: 360 - 14 * 25 = 10 degrees. This can be seen on the output picture.
To solve this we can use a floating point variable for the step counter, and to increment it with a floating point value obtained from a floating point division, using for example 360.0 as the numerator. (Actually 360.0 is stored as a double, to store it as a single precision float it should be 360.0f).
for (float i = 0; i <= 360; i+=360.0/(numPoints*2)) {
But doing so, we may have trouble at the i <= 360 comparison, there are quantization errors resulting from floating point operations (i could be slightly smaller or bigger than the "mathematical" value). So it would be better to keep the integer counter for the loop, and do the floating point operations afterwards. This code part:
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;
would then be changed to:
for (int i = 0; i <= numPoints*2; i++) {
float DegInRad = i * 360.0/(numPoints*2) * DegToRad;

Internal nested while loop wont execute

I'm trying to create a nested while-loop structure, which will create a 3 * 3 grid of cubes. It only appears to run the internal loop one time, creating an "L" shape out of cubes. So, my guess is that the internal while loop is not resetting after it runs the first time, but I do appear to be explicitly resetting it.
I'd rather not post the entire code, as some is code given by my TA, and it feels wrong to post that without their permission.
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
UpdateTransform();
int x = 0;
int y = 0;
float Xres = 0;
float Yres = 0;
while(x < 3)
{
glPushMatrix();
glTranslatef(Xres,0,0);
drawOneCube();
glPopMatrix();
Xres += 0.3;
while(y < 3)
{
glPushMatrix();
glTranslatef(0,Yres,0);
drawOneCube();
glPopMatrix();
Yres += 0.3;
y++;
}
y = 0;
Yres = 0;
x++;
}
glutSwapBuffers();//this prevents that problem where the window copies the contents behind the window, possibly with glClear at the top of this function
}
It looks like your logic is incorrect. You should only be calling the cube drawing function at one point, something like this:
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
UpdateTransform();
int x = 0;
int y = 0;
float Xres = 0;
float Yres = 0;
for (x = 0; x < 3; ++x)
{
Yres = 0;
for (y = 0; y < 3; ++y)
{
glPushMatrix();
glTranslatef(Xres,Yres,0);
drawOneCube();
glPopMatrix();
Yres += 0.3;
}
Xres += 0.3;
}
glutSwapBuffers();
}

Bezier curve using c++ opengl

I'm using this code to draw a Bézier curve by clicking a point. It works if I use the static formula that is written in drawBezier function, and it makes the right curve. But if I use the generalized formula written in drawBezierGeneralized, there's a problem with the last point.
What am I doing wrong?
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
using namespace std;
//Point class for taking the points
class Point {
public:
float x, y;
void setxy(float x2, float y2)
{
x = x2; y = y2;
}
//operator overloading for '=' sign
const Point & operator=(const Point &rPoint)
{
x = rPoint.x;
y = rPoint.y;
return *this;
}
};
int factorial(int n)
{
if (n<=1)
return(1);
else
n=n*factorial(n-1);
return n;
}
float binomial_coff(float n,float k)
{
float ans;
ans = factorial(n) / (factorial(k)*factorial(n-k));
return ans;
}
Point abc[20];
int SCREEN_HEIGHT = 500;
int points = 0;
int clicks = 4;
void myInit() {
glClearColor(1.0,1.0,1.0,0.0);
glColor3f(0.0,0.0,0.0);
glPointSize(3);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,640.0,0.0,500.0);
}
void drawDot(int x, int y) {
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glFlush();
}
void drawLine(Point p1, Point p2) {
glBegin(GL_LINES);
glVertex2f(p1.x, p1.y);
glVertex2f(p2.x, p2.y);
glEnd();
glFlush();
}
//Calculate the bezier point
Point drawBezier(Point PT[], double t) {
Point P;
P.x = pow((1 - t), 3) * PT[0].x + 3 * t * pow((1 -t), 2) * PT[1].x + 3 * (1-t) * pow(t, 2)* PT[2].x + pow (t, 3)* PT[3].x;
P.y = pow((1 - t), 3) * PT[0].y + 3 * t * pow((1 -t), 2) * PT[1].y + 3 * (1-t) * pow(t, 2)* PT[2].y + pow (t, 3)* PT[3].y;
return P;
}
//Calculate the bezier point [generalized]
Point drawBezierGeneralized(Point PT[], double t) {
Point P;
P.x = 0;P.y=0;
for(int i=0;i<clicks;i++)
{
P.x = P.x + binomial_coff((float)clicks,(float)i) * pow(t,(double)i) * pow((1-t),(clicks-i)) * PT[i].x;
P.y = P.y + binomial_coff((float)clicks,(float)i) * pow(t,(double)i) * pow((1-t),(clicks-i)) * PT[i].y;
}
//cout<<P.x<<endl<<P.y;
//cout<<endl<<endl;
return P;
}
void myMouse(int button, int state, int x, int y) {
// If left button was clicked
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
// Store where mouse was clicked, Y is backwards.
abc[points].setxy((float)x,(float)(SCREEN_HEIGHT - y));
points++;
// Draw the red dot.
drawDot(x, SCREEN_HEIGHT - y);
// If (click-amout) points are drawn do the curve.
if(points == clicks)
{
glColor3f(0.2,1.0,0.0);
// Drawing the control lines
for(int k=0;k<clicks-1;k++)
drawLine(abc[k], abc[k+1]);
Point p1 = abc[0];
/* Draw each segment of the curve.Make t increment in smaller amounts for a more detailed curve.*/
for(double t = 0.0;t <= 1.0; t += 0.02)
{
Point p2 = drawBezierGeneralized(abc,t);
cout<<p1.x<<" , "<<p1.y<<endl;
cout<<p2.x<<" , "<<p2.y<<endl;
cout<<endl;
drawLine(p1, p2);
p1 = p2;
}
glColor3f(0.0,0.0,0.0);
points = 0;
}
}
}
void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(640,500);
glutInitWindowPosition(100,150);
glutCreateWindow("Bezier Curve");
glutMouseFunc(myMouse);
glutDisplayFunc(myDisplay);
myInit();
glutMainLoop();
return 0;
}
I found what the problem was. Hope this is not too late.
Also, thanks for your code.
Point drawBezierGeneralized(Point PT[], double t) {
Point P;
P.x = 0; P.y = 0;
for (int i = 0; i<clicks; i++)
{
P.x = P.x + binomial_coff((float)(clicks - 1), (float)i) * pow(t, (double)i) * pow((1 - t), (clicks - 1 - i)) * PT[i].x;
P.y = P.y + binomial_coff((float)(clicks - 1), (float)i) * pow(t, (double)i) * pow((1 - t), (clicks - 1 - i)) * PT[i].y;
}
//cout<<P.x<<endl<<P.y;
//cout<<endl<<endl;
return P;
}
I think the problem is in the call to the primitive.
for(double t = 0.0;t <= 1.0; t += 0.02)
{
//Point p2 = drawBezierGeneralized(abc,t); -> here is the problem, you call the generalized
Point p2 = drawBezier(abc,t);
cout<<p1.x<<" , "<<p1.y<<endl;
cout<<p2.x<<" , "<<p2.y<<endl;
cout<<endl;
drawLine(p1, p2);
p1 = p2;
}