Draw bezier curve
This commit is contained in:
parent
99863ddcdd
commit
cabc8e8c09
111
src/gl_draw.c
111
src/gl_draw.c
@ -28,6 +28,7 @@
|
|||||||
#include "filereader.h"
|
#include "filereader.h"
|
||||||
#include "gl_draw.h"
|
#include "gl_draw.h"
|
||||||
#include "half_edge.h"
|
#include "half_edge.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
#include <GL/glut.h>
|
#include <GL/glut.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
@ -66,10 +67,11 @@ bool shademodel = true;
|
|||||||
/*
|
/*
|
||||||
* static function declaration
|
* static function declaration
|
||||||
*/
|
*/
|
||||||
static void draw_bez(HE_obj const * const obj);
|
static void draw_bez(HE_obj const * const obj, float step_factor_inc);
|
||||||
static void draw_obj(int32_t const myxrot,
|
static void draw_obj(int32_t const myxrot,
|
||||||
int32_t const myyrot,
|
int32_t const myyrot,
|
||||||
int32_t const myzrot);
|
int32_t const myzrot,
|
||||||
|
float bez_inc);
|
||||||
static void draw_Planet_1(void);
|
static void draw_Planet_1(void);
|
||||||
static void draw_Planet_2(void);
|
static void draw_Planet_2(void);
|
||||||
static void gl_destroy(void);
|
static void gl_destroy(void);
|
||||||
@ -189,11 +191,16 @@ static void draw_vertices(HE_obj const * const obj,
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_bez(HE_obj const * const obj)
|
static void draw_bez(HE_obj const * const obj, float step_factor_inc)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
static float line_width = 2;
|
static float line_width = 2;
|
||||||
static float point_size = 10;
|
static float point_size = 10;
|
||||||
|
static float step_factor = 0.1;
|
||||||
|
|
||||||
|
if (step_factor + step_factor_inc > 0.002 &
|
||||||
|
step_factor + step_factor_inc < 0.50)
|
||||||
|
step_factor += step_factor_inc;
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
@ -201,7 +208,13 @@ static void draw_bez(HE_obj const * const obj)
|
|||||||
glPointSize(point_size);
|
glPointSize(point_size);
|
||||||
glColor3f(1.0, 0.0, 0.0);
|
glColor3f(1.0, 0.0, 0.0);
|
||||||
|
|
||||||
while (i < obj->bzc) {
|
while (i < obj->bzc) { /* for all bezier curves */
|
||||||
|
vector *v1 = NULL,
|
||||||
|
*v2 = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* draw frame
|
||||||
|
*/
|
||||||
glBegin(GL_LINE_STRIP);
|
glBegin(GL_LINE_STRIP);
|
||||||
for (uint32_t j = 0; j <= obj->bez_curves[i].deg; j++) {
|
for (uint32_t j = 0; j <= obj->bez_curves[i].deg; j++) {
|
||||||
glVertex3f(obj->bez_curves[i].vec[j].x,
|
glVertex3f(obj->bez_curves[i].vec[j].x,
|
||||||
@ -209,21 +222,69 @@ static void draw_bez(HE_obj const * const obj)
|
|||||||
obj->bez_curves[i].vec[j].z);
|
obj->bez_curves[i].vec[j].z);
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
/*
|
||||||
while (i < obj->bzc) {
|
* draw control points
|
||||||
|
*/
|
||||||
glBegin(GL_POINTS);
|
glBegin(GL_POINTS);
|
||||||
for (uint32_t j = 0; j <= obj->bez_curves[i].deg; j++) {
|
for (uint32_t j = 0; j <= obj->bez_curves[i].deg; j++) {
|
||||||
glVertex3f(obj->bez_curves[i].vec[j].x,
|
glVertex3f(obj->bez_curves[i].vec[j].x,
|
||||||
obj->bez_curves[i].vec[j].y,
|
obj->bez_curves[i].vec[j].y,
|
||||||
obj->bez_curves[i].vec[j].z);
|
obj->bez_curves[i].vec[j].z);
|
||||||
}
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* line segments: first line
|
||||||
|
*/
|
||||||
|
v1 = calculate_bezier_point(&(obj->bez_curves[i]), step_factor);
|
||||||
|
glVertex3f(obj->bez_curves[i].vec[0].x,
|
||||||
|
obj->bez_curves[i].vec[0].y,
|
||||||
|
obj->bez_curves[i].vec[0].z);
|
||||||
|
glVertex3f(v1->x,
|
||||||
|
v1->y,
|
||||||
|
v1->z);
|
||||||
|
|
||||||
|
for (float k = step_factor; k < 1 - step_factor; k += step_factor) {
|
||||||
|
free(v1);
|
||||||
|
free(v2);
|
||||||
|
|
||||||
|
v1 = calculate_bezier_point(&(obj->bez_curves[i]), k);
|
||||||
|
v2 = calculate_bezier_point(&(obj->bez_curves[i]), k +
|
||||||
|
step_factor);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* line segments: middle lines
|
||||||
|
*/
|
||||||
|
glVertex3f(v1->x,
|
||||||
|
v1->y,
|
||||||
|
v1->z);
|
||||||
|
glVertex3f(v2->x,
|
||||||
|
v2->y,
|
||||||
|
v2->z);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* line segments: last line
|
||||||
|
*/
|
||||||
|
glVertex3f(v2->x,
|
||||||
|
v2->y,
|
||||||
|
v2->z);
|
||||||
|
glVertex3f(obj->bez_curves[i].vec[obj->bez_curves[i].deg].x,
|
||||||
|
obj->bez_curves[i].vec[obj->bez_curves[i].deg].y,
|
||||||
|
obj->bez_curves[i].vec[obj->bez_curves[i].deg].z);
|
||||||
|
|
||||||
|
free(v1);
|
||||||
|
free(v2);
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +298,8 @@ static void draw_bez(HE_obj const * const obj)
|
|||||||
*/
|
*/
|
||||||
static void draw_obj(int32_t const myxrot,
|
static void draw_obj(int32_t const myxrot,
|
||||||
int32_t const myyrot,
|
int32_t const myyrot,
|
||||||
int32_t const myzrot)
|
int32_t const myzrot,
|
||||||
|
float bez_inc)
|
||||||
{
|
{
|
||||||
/* rotation */
|
/* rotation */
|
||||||
static int32_t xrot = 0,
|
static int32_t xrot = 0,
|
||||||
@ -279,7 +341,7 @@ static void draw_obj(int32_t const myxrot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj->bzc != 0)
|
if (obj->bzc != 0)
|
||||||
draw_bez(obj);
|
draw_bez(obj, bez_inc);
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
@ -451,7 +513,7 @@ void display(void)
|
|||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
draw_obj(0, 0, 0);
|
draw_obj(0, 0, 0, 0);
|
||||||
draw_Planet_1();
|
draw_Planet_1();
|
||||||
draw_Planet_2();
|
draw_Planet_2();
|
||||||
|
|
||||||
@ -616,27 +678,27 @@ void keyboard(unsigned char key, int x, int y)
|
|||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
draw_obj(2, 0, 0);
|
draw_obj(2, 0, 0, 0);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
draw_obj(-2, 0, 0);
|
draw_obj(-2, 0, 0, 0);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
draw_obj(0, 2, 0);
|
draw_obj(0, 2, 0, 0);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'Y':
|
case 'Y':
|
||||||
draw_obj(0, -2, 0);
|
draw_obj(0, -2, 0, 0);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
draw_obj(0, 0, 2);
|
draw_obj(0, 0, 2, 0);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
draw_obj(0, 0, -2);
|
draw_obj(0, 0, -2, 0);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
@ -654,13 +716,22 @@ void keyboard(unsigned char key, int x, int y)
|
|||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
draw_normals(obj, 0.01f);
|
draw_obj(0, 0, 0, 0.02);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'K':
|
||||||
draw_normals(obj, -0.01f);
|
draw_obj(0, 0, 0, -0.02);
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* case 'k': */
|
||||||
|
/* draw_normals(obj, 0.01f); */
|
||||||
|
/* glutPostRedisplay(); */
|
||||||
|
/* break; */
|
||||||
|
/* case 'l': */
|
||||||
|
/* draw_normals(obj, -0.01f); */
|
||||||
|
/* glutPostRedisplay(); */
|
||||||
|
/* break; */
|
||||||
case 'w':
|
case 'w':
|
||||||
glTranslatef(0.0f, 1.0f, 0.0f);
|
glTranslatef(0.0f, 1.0f, 0.0f);
|
||||||
break;
|
break;
|
||||||
|
@ -285,6 +285,43 @@ bool normalize_object(HE_obj *obj)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate a point on the bezier curve according to the
|
||||||
|
* bezier vertices. If section is set to 0.5 then it will
|
||||||
|
* return the vector to the point in the middle of the curve.
|
||||||
|
*
|
||||||
|
* @param obj the object holding the bezier vertices information
|
||||||
|
* @param section the section which will be applied to all
|
||||||
|
* lines between the bezier vertices
|
||||||
|
* @return the vector to the calculated point
|
||||||
|
*/
|
||||||
|
vector *calculate_bezier_point(bez_curv *bez, float section)
|
||||||
|
{
|
||||||
|
vector vec_arr[bez->deg];
|
||||||
|
bez_curv new_bez;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < bez->deg; i++) {
|
||||||
|
vector new_vec;
|
||||||
|
|
||||||
|
SUB_VECTORS(&(bez->vec[i + 1]), &(bez->vec[i]), &new_vec);
|
||||||
|
VECTOR_LEN_SCAL_MUL(&new_vec, section, &new_vec);
|
||||||
|
ADD_VECTORS(&new_vec, &(bez->vec[i]), &new_vec);
|
||||||
|
|
||||||
|
vec_arr[i] = new_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_bez.vec = vec_arr;
|
||||||
|
new_bez.deg = bez->deg - 1;
|
||||||
|
|
||||||
|
if (new_bez.deg > 0) {
|
||||||
|
return calculate_bezier_point(&new_bez, section);
|
||||||
|
} else {
|
||||||
|
vector *result_vector = malloc(sizeof(*result_vector));
|
||||||
|
*result_vector = vec_arr[0];
|
||||||
|
return result_vector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free the inner structures of an object.
|
* Free the inner structures of an object.
|
||||||
*
|
*
|
||||||
|
@ -324,6 +324,7 @@ bool vec_normal(HE_vert const * const vert, vector *vec);
|
|||||||
bool find_center(HE_obj const * const obj, vector *vec);
|
bool find_center(HE_obj const * const obj, vector *vec);
|
||||||
float get_normalized_scale_factor(HE_obj const * const obj);
|
float get_normalized_scale_factor(HE_obj const * const obj);
|
||||||
bool normalize_object(HE_obj *obj);
|
bool normalize_object(HE_obj *obj);
|
||||||
|
vector *calculate_bezier_point(bez_curv *bez, float section);
|
||||||
HE_obj *parse_obj(char const * const filename);
|
HE_obj *parse_obj(char const * const filename);
|
||||||
void delete_object(HE_obj *obj);
|
void delete_object(HE_obj *obj);
|
||||||
|
|
||||||
|
37
src/vector.c
37
src/vector.c
@ -33,6 +33,43 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the vector which lengths is reduced by the
|
||||||
|
* factor scal and store it in c.
|
||||||
|
* This function is aliasing safe.
|
||||||
|
*
|
||||||
|
* @param a vector
|
||||||
|
* @param scal scalar to multiply the vector with
|
||||||
|
* @param c vector [out]
|
||||||
|
* @return true/false for success/failure
|
||||||
|
*/
|
||||||
|
bool vector_len_scal_mul(vector *a, float scal, vector *c)
|
||||||
|
{
|
||||||
|
vector a_tmp;
|
||||||
|
float vector_length;
|
||||||
|
float factor;
|
||||||
|
|
||||||
|
if (!a || !scal || !c)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
copy_vector(a, &a_tmp);
|
||||||
|
|
||||||
|
vector_length = sqrt((a_tmp.x * a_tmp.x) +
|
||||||
|
(a_tmp.y * a_tmp.y) + (a_tmp.z * a_tmp.z));
|
||||||
|
|
||||||
|
factor = vector_length * scal;
|
||||||
|
|
||||||
|
c->x = a_tmp.x / vector_length;
|
||||||
|
c->y = a_tmp.y / vector_length;
|
||||||
|
c->z = a_tmp.z / vector_length;
|
||||||
|
|
||||||
|
c->x = c->x * factor;
|
||||||
|
c->y = c->y * factor;
|
||||||
|
c->z = c->z * factor;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the vector product of a and b
|
* Calculate the vector product of a and b
|
||||||
* and store it in c. This function is aliasing safe.
|
* and store it in c. This function is aliasing safe.
|
||||||
|
13
src/vector.h
13
src/vector.h
@ -31,6 +31,18 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fault intolerant macro. Will abort the program if the called
|
||||||
|
* function failed.
|
||||||
|
*/
|
||||||
|
#define VECTOR_LEN_SCAL_MUL(...) \
|
||||||
|
{ \
|
||||||
|
if (!vector_len_scal_mul(__VA_ARGS__)) { \
|
||||||
|
fprintf(stderr, "Failure in vector_product()!\n"); \
|
||||||
|
abort(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fault intolerant macro. Will abort the program if the called
|
* Fault intolerant macro. Will abort the program if the called
|
||||||
* function failed.
|
* function failed.
|
||||||
@ -117,6 +129,7 @@ struct vector {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool vector_len_scal_mul(vector *a, float scal, vector *c);
|
||||||
bool vector_product(vector *a, vector *b, vector *c);
|
bool vector_product(vector *a, vector *b, vector *c);
|
||||||
bool add_vectors(vector *a, vector *b, vector *c);
|
bool add_vectors(vector *a, vector *b, vector *c);
|
||||||
bool sub_vectors(vector *a, vector *b, vector *c);
|
bool sub_vectors(vector *a, vector *b, vector *c);
|
||||||
|
Loading…
Reference in New Issue
Block a user