Bezier Curve Algorithm in C | OpenGL
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<GL/freeglut.h>
#include<GL/gl.h>
#define STEP 0.0001
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
int numpoints=0,q=0;
typedef struct{
float x,y;
}POINT;
POINT *ctrlPoint,*auxPoint;
int i,j,f;
float t;
long double factorial(int x){
long double fact=1;
int p=1;
if(x==0 || x==1)
return 1;
else{
while(p<=x){
fact*=p;
p++;}
}
return fact;
}
long double binomial( int f, int n){
double com=factorial(n)/(factorial(f)*factorial(n-f));
return com;
}
POINT bernstein(POINT *ctrlPoint,float t,int n){
POINT N;N.x=N.y=0;
for(i=0;i<=n;i++){
N.x+=ctrlPoint[i].x*binomial(i,n)*pow(t,i)*pow((1-t),(n-i));
N.y+=ctrlPoint[i].y*binomial(i,n)*pow(t,i)*pow((1-t),(n-i));
}
return N;
}
void init(){
glClearColor(0.0,0.0,0.0,0.0);
glPointSize(10.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(float)SCREEN_WIDTH,0.0,(float)SCREEN_HEIGHT);
}
void drawPoint(int x,int y){
glColor3f(0.0,0.0,1.0);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glFlush();
}
void drawLine(POINT p1,POINT p2){
glColor3f(1.0,0.0,0.0);
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex2f(p1.x,p1.y);
glVertex2f(p2.x,p2.y);
glEnd();
glFlush();
}
void drawCurve(POINT p1,POINT p2,float color){
glColor3f(1,0.0,0.0);
glLineWidth(1);
glBegin(GL_LINES);
glVertex2f(p1.x,p1.y);
glVertex2f(p2.x,p2.y);
glEnd();
glFlush();
}
void MouseEvent(int button,int state,int x,int y){
POINT M,P=ctrlPoint[0];
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN){
ctrlPoint[numpoints].x=(float)x;
ctrlPoint[numpoints].y=(float)SCREEN_HEIGHT-y;
numpoints++;
drawPoint(x,SCREEN_HEIGHT-y);
}
else
if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN){
for(t = 0;t <= 1.0; t += STEP) {
M=bernstein(ctrlPoint,t,numpoints-1);
drawCurve(P,M,t);
P=M;
}
}
else
if(button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN){
for(i=0;i<numpoints-1;i++)
drawLine(ctrlPoint[i],ctrlPoint[i+1]);
}
}
void keyboardEvent(unsigned char key,int x, int y){
if(key==27)
exit(0);
else
if(key=='C'){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
numpoints=0;
}
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("Bezier Curve Application in OpenGL | Developed BY Shaharyar Shaukat");
ctrlPoint=(POINT *)malloc(q*sizeof(POINT));
if(!ctrlPoint){
exit(EXIT_FAILURE);
}
else{
q++;
auxPoint=(POINT *)realloc(ctrlPoint,q*sizeof(POINT));
if(!auxPoint){
exit(EXIT_FAILURE);
}
else{
ctrlPoint=auxPoint;
glutMouseFunc(MouseEvent);
}
}
glutDisplayFunc(display);
glutKeyboardFunc(keyboardEvent);
init();
glutMainLoop();
free(ctrlPoint);
free(auxPoint);
return 0;
}
#include<math.h>
#include<stdlib.h>
#include<GL/freeglut.h>
#include<GL/gl.h>
#define STEP 0.0001
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
int numpoints=0,q=0;
typedef struct{
float x,y;
}POINT;
POINT *ctrlPoint,*auxPoint;
int i,j,f;
float t;
long double factorial(int x){
long double fact=1;
int p=1;
if(x==0 || x==1)
return 1;
else{
while(p<=x){
fact*=p;
p++;}
}
return fact;
}
long double binomial( int f, int n){
double com=factorial(n)/(factorial(f)*factorial(n-f));
return com;
}
POINT bernstein(POINT *ctrlPoint,float t,int n){
POINT N;N.x=N.y=0;
for(i=0;i<=n;i++){
N.x+=ctrlPoint[i].x*binomial(i,n)*pow(t,i)*pow((1-t),(n-i));
N.y+=ctrlPoint[i].y*binomial(i,n)*pow(t,i)*pow((1-t),(n-i));
}
return N;
}
void init(){
glClearColor(0.0,0.0,0.0,0.0);
glPointSize(10.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(float)SCREEN_WIDTH,0.0,(float)SCREEN_HEIGHT);
}
void drawPoint(int x,int y){
glColor3f(0.0,0.0,1.0);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glFlush();
}
void drawLine(POINT p1,POINT p2){
glColor3f(1.0,0.0,0.0);
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex2f(p1.x,p1.y);
glVertex2f(p2.x,p2.y);
glEnd();
glFlush();
}
void drawCurve(POINT p1,POINT p2,float color){
glColor3f(1,0.0,0.0);
glLineWidth(1);
glBegin(GL_LINES);
glVertex2f(p1.x,p1.y);
glVertex2f(p2.x,p2.y);
glEnd();
glFlush();
}
void MouseEvent(int button,int state,int x,int y){
POINT M,P=ctrlPoint[0];
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN){
ctrlPoint[numpoints].x=(float)x;
ctrlPoint[numpoints].y=(float)SCREEN_HEIGHT-y;
numpoints++;
drawPoint(x,SCREEN_HEIGHT-y);
}
else
if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN){
for(t = 0;t <= 1.0; t += STEP) {
M=bernstein(ctrlPoint,t,numpoints-1);
drawCurve(P,M,t);
P=M;
}
}
else
if(button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN){
for(i=0;i<numpoints-1;i++)
drawLine(ctrlPoint[i],ctrlPoint[i+1]);
}
}
void keyboardEvent(unsigned char key,int x, int y){
if(key==27)
exit(0);
else
if(key=='C'){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
numpoints=0;
}
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("Bezier Curve Application in OpenGL | Developed BY Shaharyar Shaukat");
ctrlPoint=(POINT *)malloc(q*sizeof(POINT));
if(!ctrlPoint){
exit(EXIT_FAILURE);
}
else{
q++;
auxPoint=(POINT *)realloc(ctrlPoint,q*sizeof(POINT));
if(!auxPoint){
exit(EXIT_FAILURE);
}
else{
ctrlPoint=auxPoint;
glutMouseFunc(MouseEvent);
}
}
glutDisplayFunc(display);
glutKeyboardFunc(keyboardEvent);
init();
glutMainLoop();
free(ctrlPoint);
free(auxPoint);
return 0;
}
0 comments:
Post a Comment