Attachment 1032
Hello every body, I have a polygon consisting of 26 points as shown in the figure. i would just like to smoothen the edges. Could you suggest me some simple way to do it? Thanks in advance.
Printable View
Attachment 1032
Hello every body, I have a polygon consisting of 26 points as shown in the figure. i would just like to smoothen the edges. Could you suggest me some simple way to do it? Thanks in advance.
Something like this http://www.opengl.org/discussion_boa...control-points ?
Sounds like a Google question to me. Just divide the edges at their midpoints and connect them.
I didn't say 'push out the edges', I said push out the midpoints of each divided segment as below ...
Attachment 1037
Thank you all for the suggestion.
With only one midpoints step, this give something like this :
Code :
#include <stdio.h> #include <stdlib.h> #include <GL/glut.h> //====================================================== // GLOBAL VARIABLES //====================================================== typedef struct { GLfloat x, y, z; }position_t; // modify the closed curve here position_t vertices[] = { {2.75,0.56,0}, {3.86, 1.56, 0}, {4.06, 2.79,0}, {3.69,3.51, 0}, {2.75, 4.11, 0}, {1.43, 4.15, 0}, {0.42, 3.38, 0}, {0.43, 1.79, 0}, {0.79, 1.00, 0}, {1.54, 0.47, 0} }; position_t *middlePoints = NULL; int numPoints = 0; //==================================================================== // Allocate middlePoints array (with the same size as vertices) //==================================================================== void AllocMiddlePoints() { middlePoints = (position_t *) malloc( sizeof(vertices)); numPoints = sizeof(vertices) / sizeof(position_t); } //==================================================================== // Draw controls points //==================================================================== void DrawControlPoints(position_t *pos, int num, int pointSize, GLfloat red, GLfloat green, GLfloat blue) { int i; glPointSize(pointSize); glColor3f(red, green, blue); glBegin(GL_POINTS); for( i = 0; i < num; i++) { glVertex3fv( (GLfloat *) &pos[i] ); } glEnd(); } //==================================================================== // Draw multiples connected segments (with a loop) //==================================================================== void DrawSegments(position_t *pos, int num, int lineSize, GLfloat red, GLfloat green, GLfloat blue) { int i; glLineWidth(lineSize); glColor3f(red, green, blue); glBegin(GL_LINE_LOOP); for( i = 0; i < num ; i++) { glVertex3fv((GLfloat *) &pos[i] ); } glEnd(); } //============================================================================ // draw multiples connected segments from "interleaved' src and dst vertices //============================================================================ void DrawSegments2(position_t *src, position_t *dst, int num, int lineSize, GLfloat red, GLfloat green, GLfloat blue) { int i; glLineWidth(lineSize); glColor3f(red, green, blue); glBegin(GL_LINE_LOOP); for( i = 0; i < num ; i++) { glVertex3fv((GLfloat *) &src[i] ); glVertex3fv((GLfloat *) &dst[i] ); } glEnd(); } //==================================================================== // compute middles positions from initials segments //==================================================================== void ComputeMiddlePositions(position_t *src, position_t *dst, int num) { int i; for( i = 0 ; i < num; i++) { dst[i].x = src[i].x + (src[ (i+1) % num].x - src[i].x) / 2.0f; dst[i].y = src[i].y + (src[ (i+1) % num].y - src[i].y) / 2.0f ; dst[i].z = src[i].z + (src[ (i+1) % num].z - src[i].z) / 2.0f; } } //==================================================================== // rescale middle positions for to give the "more smooth" impression //==================================================================== void ScaleMiddlePositions(position_t *pos, int num, GLfloat scale) { int i; float cx = 0, cy = 0, cz = 0; for( i = 0 ; i < num; i++) { cx += pos[i].x; cy += pos[i].y; cz += pos[i].z; } cx /= num; cy /= num; cz /= num; for( i = 0 ; i < num; i++) { pos[i].x = (pos[i].x - cx) * scale + cx; pos[i].y = (pos[i].y - cy) * scale + cy; pos[i].z = (pos[i].z - cz) * scale + cz; } } //====================================================== // WINDOW RESHAPE ROUTINE //====================================================== void displayReshape(int w, int h) { // If the display is re-sized in any way, the curve is redrawn // so that it fits the display properly. Try it! glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-4.0, 4.0, -3.0 * (GLfloat) h / (GLfloat) w, 5.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-4.0 * (GLfloat) w / (GLfloat) h, 4.0 * (GLfloat) w / (GLfloat) h, -3.0, 5.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); } //====================================================== // DISPLAY CALL BACK ROUTINE //====================================================== void displayCallBack() { int num = sizeof(vertices) / sizeof(position_t); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0); glTranslatef(0.0, 1.0, 0.0); DrawSegments(vertices, num, 1, 1,1,1); DrawControlPoints(vertices, num, 3, 1,1,1); ComputeMiddlePositions(vertices, middlePoints, num); ScaleMiddlePositions(middlePoints, num, 1.1f); DrawSegments2(vertices, middlePoints, num, 1, 1,0,0); DrawControlPoints(middlePoints, num, 3, 1,0,0); glutSwapBuffers(); } //====================================================== // MAIN PROGRAM //====================================================== int main(int argc, char** argv) { // Allow cmd line arguments to be passed to the glut glutInit(&argc, argv); // Create and name window glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Need both double buffering and z buffer glutInitWindowSize(500, 500); glutCreateWindow("Smooth segments"); // Add Display CallBacks glutReshapeFunc(displayReshape); glutDisplayFunc(displayCallBack); glClearColor(0.0,0.0,0.0,1.0); glColor3f(0.0,0.0,0.0); AllocMiddlePoints(); //Enter infinite loop calling 'displayCallBack' glutMainLoop(); return 0; }
You have only to modify values into the vertices[] array for to see another closed curve that mine
The centroïd (cx, cy, cz) is computed in the first part of the ScaleMiddlePositions()
[this is only the sum of all coordinates divided by the number of them]
Code :
float cx = 0, cy = 0, cz = 0; for( i = 0 ; i < num; i++) { cx += pos[i].x; cy += pos[i].y; cy += pos[i].z; } cx /= num; cy /= num; cz /= num;
The pushing of midpoints is make at the second part of the same ScaleMiddlePositions()
[the "push out the midpoints of each divided segment" factor is the last parameter of this funtion, I have set it to 1.1 )
(this translate the middlepoint to the centroïd origine, scale it for make the push, and retranslate it to his original origine)Code :
for( i = 0 ; i < num; i++) { pos[i].x = (pos[i].x - cx) * scale + cx; pos[i].y = (pos[i].y - cy) * scale + cy; pos[i].z = (pos[i].z - cz) * scale + cz; }
I was thinking you could have used some kind of corner cutting technique and discard the old point,
but you can just keep it and average the old point instead:
http://img515.imageshack.us/img515/6642/subdivide.png
Chaikin's Algorithm - interesting - looks easy to code.
Final product is totally inside the original.
Area of polygon decreases with each step.
OP has to decide if that's acceptable.