diff --git a/delaunay.c b/delaunay.c deleted file mode 100644 index 02c1df9d0c99369ed4b01b49490e41080cafcd0e..0000000000000000000000000000000000000000 --- a/delaunay.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "delaunay.h" -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> - -coordinates_t coordinates_create(int row_, int column_) -{ - coordinates_t c = {.row = row_, .column = column_}; - return c; -} - -// Transform a position in the univers [x0,y0]x[x1,y1] to a screen position -coordinates_t position_to_coordinates(int width, int height, double x0, double x1, double y0, double y1, vec2 pos) -{ - double dx = x1 - x0; - double dy = y1 - y0; - return coordinates_create((int)round(height * (pos.y - y0) / dy), (int)round(width * (pos.x - x0) / dx)); -} - -double distance_2(vec2 p1, vec2 p2) { return vec2_norm(vec2_sub(p2, p1)); } - -// Returns false if P is not a valid position -bool in_univers(vec2 P_actual, double limitX, double limitY) -{ - // check if P_actual is in the window - return P_actual.x <= limitX && P_actual.y <= limitY && P_actual.x >= 0.0 && P_actual.y >= 0.0; -} - -vec2 circle_middle(vec2 p1, vec2 p2, vec2 p3) -{ - /* - A=point2.x-point1.x - B=point2.y-point1.y - C=point3.x-point1.x - D=point3.y-point1.y - E = A*(point1.x+point2.x) + B*(point1.y+point2.y) - F = C*(point1.x+point3.x) + D*( point1.y+point3.y) - G = 2*(A*(pont3.y-point2.y) - B*(point3.x-point2.x)) - Si G==0 : return //Les trois points sont debout - x = (D*E-B*F)/G ; - y = (A*F-C*E)/G - Return x,y - */ - double A = p2.x - p1.x; - double B = p2.y - p1.y; - double C = p3.x - p1.x; - double D = p3.x - p1.y; - double E = A * (p1.x + p2.x) + B * (p1.y + p2.y); - double F = C * (p1.x + p3.x) + D * (p1.y + p3.y); - double G = 2 * (A * (p3.y - p2.y) - B * (p3.x - p2.x)); - // Les trois points sont debouts(return) - if (G == 0) - { - return vec2_create_zero(); - } - return (vec2){ - .x = (D * E - B * F) / G, - .y = (A * F - C * E) / G}; -} - -// void showSweepLine(struct gfx_context_t *ctxt) -// { -// vec2 sweepLine = (vec2) -// { -// .x = 0, -// .y = 1 -// } -// while (in_univers(sweepLine, 0.0, 1.0, 0.0, 1.0)) -// { -// } -// } - -// void initialize() - -// double parabolaY(site_t *site, uint32_t sweepY, uint32_t x) -// { - -// return (1 / (2 * (site->row - sweepY))) * (pow(x, 2.0) - 2 * site->column * x + pow(site->column, 2.0) + pow(site->row, 2.0) - pow(sweepY, 2.0)); -// } - -// void Shift(int taille, event_t file[taille]) -// { -// event_t event_min = file[0]; -// if (event_min.y) -// } - -// void insererEvenement(file E, event_t *site) -// { -// } - -// bool isEmpty(file_t Q) -// { - -// } - -// void intersect(site_t *site1, site_t *site2, uint32_t sweepY) -// { -// for (uint32_t i = 0; i < SCREEN_WIDTH; i++) -// { -// if (parabolaY(site1, sweepY, i) == parabolaY(site2, sweepY, i)) -// { -// uint32_t y=(uint32_t)parabolaY(site1, sweepY, i); -// // printf("intersect site1: %zu %zu // site2: %zu %zu at x=%zu y=%zu\n", site1->column, site1->row, site2->column, site2->row, i, y); -// } -// } - -// } -/* -void fortune(struct gfx_context_t *ctxt, int nbPoints, file_t Q, uint32_t sweepLine) -{ - // while(!) - // coordinates_t p1=position_to_coordinates(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 0, 1, *(Q[0].coord)); - // coordinates_t p2=position_to_coordinates(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, 0, 1, *(Q[1].coord)); - // printf("q1 x=%zu // q1 y=%zu\n", p1.column, p1.row); - // printf("q2 x=%zu // q2 y=%zu\n", p2.column, p2.row); - // site_t site1=(site_t){ - // .column=p1.column, - // .row=p1.row - // }; - // site_t site2=(site_t){ - // .column=p2.column, - // .row=p2.row - // }; - // intersect(&site1, &site2, sweepLine); - // exit(EXIT_SUCCESS); - - - - - // avl_tree T = NULL; - // insererEvenement(E, event_t * site); - // while (!isEmpty(E)) - // { - // event_t p = extraireEvenement(E); - // if (evenementSite(p)) - // { - // creerArc(); - // creerArrete(); - // desactiverEvenObs(); - // insererEvenCercle(); - // } - // else if (evenementCercle(p)) - // { - // supprimerArc(); - // creerSommetVor(); - // desactiverEvenObs(); - // insererEvenCercle(); - // } - // } -} -*/ \ No newline at end of file diff --git a/delaunay.h b/delaunay.h deleted file mode 100644 index f83c9a816435b2be3f79b00179879ae699557c0a..0000000000000000000000000000000000000000 --- a/delaunay.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _DELAUNAY_H_ -#define _DELAUNAY_H_ -#define SCREEN_WIDTH 1000 -#define SCREEN_HEIGHT 1000 -#include "vec2/vec2.h" -#include "gfx/gfx.h" - - -// enum event -// { -// CIRCLE, SITE -// }; - - -// typedef struct _site_t -// { -// uint32_t row; -// uint32_t column; -// } site_t; - - -// typedef struct _areteV_t -// { -// uint32_t p1; -// uint32_t p2; -// } areteV_t; - -// typedef struct _event_t -// { -// vec2 *coord; -// double instantT; -// enum event type; -// struct _event_t *cercleEv; -// } event_t; - -// typedef event_t *file_t; - - -// Transform a position in the univers [x0,y0]x[x1,y1] to a screen position - -// void showSweepLine(struct gfx_context_t *ctxt); - -// void fortune(struct gfx_context_t *ctxt, int nbPoints, file_t Q, uint32_t sweepLine); - - -#endif \ No newline at end of file diff --git a/exemple/pyramid.stl b/exemple/pyramid.stl index ce226ba278b911bf338468b81cef9c082a06e8d5..c850b82f654ef691f364c14293439ca7e236d487 100644 --- a/exemple/pyramid.stl +++ b/exemple/pyramid.stl @@ -1,4 +1,4 @@ -solid pyramid +solid exemple/pyramid facet normal 0.000000 -2.285714 -1.142857 outer loop vertex 0.200000 0.800000 0.300000 @@ -27,4 +27,4 @@ solid pyramid vertex 0.200000 0.800000 0.300000 endloop endfacet -endsolid pyramid +endsolid exemple/pyramid diff --git a/exemple/test.ply b/exemple/test.ply index e624d6c6a72eca44935c361f0fb95b27613e6000..bf3ffd872cc26819886ef1950de0f9e86ad88969 100644 --- a/exemple/test.ply +++ b/exemple/test.ply @@ -2,7 +2,7 @@ ex1: 0.200000 0.300000 0.300000 0.900000 0.300000 0.300000 0.200000 0.800000 0.300000 -0.90000000 0.800000 0.300000 +0.900000 0.800000 0.300000 0.550000 0.550000 0.800000 diff --git a/fortune/fortune.c b/fortune/fortune.c index fce4a4e8d1add35a7d84fd2f48ab40b9b06f438d..8031676946fd9fd535afb3101c86558c93fa89ff 100644 --- a/fortune/fortune.c +++ b/fortune/fortune.c @@ -12,10 +12,9 @@ int countTriangle = 0; void construct(int nbPoints, struct gfx_context_t *ctxt, char *filename) { printf("Début de la triangulation\n"); - allocateTriangle(nbSites); + allocateTriangle(getNbSites()); stack mEvents; beachline_t *mBeachLine = calloc(1, sizeof(beachline_t)); - qSommets = queue_creer(); mBeachLine->beginArc = initbeginArc(); mBeachLine->rootArc = mBeachLine->beginArc; stack_init(&mEvents, nbPoints); @@ -25,7 +24,7 @@ void construct(int nbPoints, struct gfx_context_t *ctxt, char *filename) stack_push(&mEvents, initEvents(getSite(i))); } - printf("nombre de points=%d\n", nbSites); + printf("nombre de points=%d\n", getNbSites()); while (!stack_is_empty(mEvents)) { @@ -43,9 +42,11 @@ void construct(int nbPoints, struct gfx_context_t *ctxt, char *filename) } printf("triangulation finished\n"); printf("Génération fichier STL\n"); - createSTL(filename, nbSommets, allTriangles); + createSTL(filename, getNbSommets()); // print all vertices - for (int i = 0; i < nbSommets; i++) + + vec2* mSommets=getMSommets(); + for (int i = 0; i < getNbSommets(); i++) { coordinates_t p = position_to_coordinates(SCREEN_WIDTH, SCREEN_HEIGHT, 0.0, 1.0, 0.0, 1.0, mSommets[i]); draw_full_circle(ctxt, p.column, p.row, 2, COLOR_GREEN); // gfx_draw_line(ctxt, p, p1, COLOR_BLUE); @@ -75,6 +76,7 @@ void handleSiteEvent(stack *mEvents, event_t *event, beachline_t *beachL, double arc_t *middleArc = breakArc(beachL, arcToBreak, site); arc_t *leftArc = middleArc->prev; arc_t *rightArc = middleArc->next; + // Add an edge in the diagram addEdge(leftArc, middleArc); middleArc->rightHalfEdge = middleArc->leftHalfEdge; @@ -105,7 +107,7 @@ void handleCircleEvent(stack *mEvents, event_t *event, beachline_t *beachL, doub deleteEvent(mEvents, leftArc); deleteEvent(mEvents, rightArc); - removeArc(beachL, arc, queue_tete(qSommets)); + removeArc(beachL, arc, queue_tete(getQSommet())); if (!isBeginArc(beachL, leftArc->prev)) { @@ -128,7 +130,7 @@ void printArc(beachline_t *beachL, arc_t *arc, int n) { printf(" "); } - printf("x=%lf // y=%lf //arc= %p //arcNext=%p//arcPrev=%p//arcLeft=%p//arcRight=%p\n", arc->site->point.x, arc->site->point.y, (void*)arc, (void*)arc->next, (void*)arc->prev, (void*)arc->left, (void*)arc->right); + printf("x=%lf // y=%lf //arc= %p //arcNext=%p//arcPrev=%p//arcLeft=%p//arcRight=%p\n", arc->site->point.x, arc->site->point.y, (void *)arc, (void *)arc->next, (void *)arc->prev, (void *)arc->left, (void *)arc->right); if (!isBeginArc(beachL, arc->left)) { @@ -298,94 +300,8 @@ event_t *createEvent(double y, vec2 point, arc_t *arc) return event; } -/** - * It creates a stl file, then it writes the - * STL file format in it - * - * @param filename the name of the file to be created - * @param nbTriangle the number of triangles in the STL file - * @param tr an array of triangles data - */ -void createSTL(char *filename, int nbTriangle, triangle_t *tr) -{ - char fileComplet[256]; - assert(strcpy(fileComplet, filename) != NULL); - assert(strcat(fileComplet, ".stl") != NULL); - FILE *stl_file = fopen(fileComplet, "w+"); - if (!stl_file) - { - fprintf(stderr, "Error open file: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - fprintf(stl_file, "solid %s\n", filename); - for (int i = 0; i < nbTriangle; i++) - { - fprintf(stl_file, " facet normal %lf %lf %lf\n", tr[i].facetNormal.x, tr[i].facetNormal.y, tr[i].facetNormal.z); - fprintf(stl_file, " outer loop\n"); - fprintf(stl_file, " vertex %lf %lf %lf\n", tr[i].p1.x, tr[i].p1.y, tr[i].p1.z); - fprintf(stl_file, " vertex %lf %lf %lf\n", tr[i].p2.x, tr[i].p2.y, tr[i].p2.z); - fprintf(stl_file, " vertex %lf %lf %lf\n", tr[i].p3.x, tr[i].p3.y, tr[i].p3.z); - fprintf(stl_file, " endloop\n"); - fprintf(stl_file, " endfacet\n"); - } - fprintf(stl_file, "endsolid %s\n", filename); - fclose(stl_file); -} -void allocateTriangle(int nbTriangle) -{ - allTriangles = malloc(nbTriangle * sizeof(triangle_t)); -} -//calculate and assign all triangles data -void calculateTriangleData(vec2 p1, vec2 p2, vec2 p3, triangle_t *tr) -{ - double p1Z, p2Z, p3Z; - - for (int i = 0; i < nbSites; i++) - { - if (point3Dim[i].x == p1.x && point3Dim[i].y == p1.y) - { - p1Z = point3Dim[i].z; - } - if (point3Dim[i].x == p2.x && point3Dim[i].y == p2.y) - { - p2Z = point3Dim[i].z; - } - if (point3Dim[i].x == p3.x && point3Dim[i].y == p3.y) - { - p3Z = point3Dim[i].z; - } - } - - vec2 V2 = vec2_sub(p2, p1); - vec2 W2 = vec2_sub(p3, p1); - vec2_z V = (vec2_z){ - .x = V2.x, - .y = V2.y, - .z = p2Z - p1Z}; - vec2_z W = (vec2_z){ - .x = W2.x, - .y = W2.y, - .z = p3Z - p1Z}; - double Nx = (V.y * W.z) - (V.z * W.y); - double Ny = (V.z * W.x) - (V.x * W.z); - double Nz = (V.x * W.y) - (V.y * W.y); - - tr->facetNormal.x = Nx / (pow(Nx, 2.0) + pow(Ny, 2.0) + pow(Nz, 2.0)); - tr->facetNormal.y = Ny / (pow(Nx, 2.0) + pow(Ny, 2.0) + pow(Nz, 2.0)); - tr->facetNormal.z = Nz / (pow(Nx, 2.0) + pow(Ny, 2.0) + pow(Nz, 2.0)); - - tr->p1.x = p1.x; - tr->p1.y = p1.y; - tr->p1.z = p1Z; - tr->p2.x = p2.x; - tr->p2.y = p2.y; - tr->p2.z = p2Z; - tr->p3.x = p3.x; - tr->p3.y = p3.y; - tr->p3.z = p3Z; -} // draw the voronoi diagramm(draw center of 3 points to the middle of different face) void draw_line_middle(vec2 point1, vec2 point2, vec2 point3, vec2 center, struct gfx_context_t *ctxt) @@ -425,12 +341,12 @@ void draw_line_middle(vec2 point1, vec2 point2, vec2 point3, vec2 center, struct gfx_draw_line(ctxt, site1, site3, COLOR_YELLOW); // resize the number of triangle if it's over the actual number - if (nbSommets > nbSites) + if (getNbSommets() > getNbSites()) { - allTriangles = realloc(allTriangles, countTriangle); + reallocTriangle(countTriangle); } // calculate and assign all data of every triangles - calculateTriangleData(point1, point2, point3, &allTriangles[countTriangle]); + calculateTriangleData(point1, point2, point3, countTriangle); // increment the number of triangles countTriangle++; } @@ -443,7 +359,8 @@ void addEvent(stack *mEvents, double beachY, arc_t *left, arc_t *middle, arc_t * bool present = false; bool isUnderBL = (y <= beachY); - + vec2* mSommets=getMSommets(); + int nbSommets=getNbSommets(); bool leftUnder = isUnderThan(left, middle); bool rightUnder = isUnderThan(middle, right); double leftInitialX = getInitialX(left, middle, leftUnder); @@ -455,10 +372,10 @@ void addEvent(stack *mEvents, double beachY, arc_t *left, arc_t *middle, arc_t * if (nbSommets == 0) { // draw all part of voronoi diagram if the data is valid - if (!present && (leftValid || rightValid) && (nbSommets + 1) < nbSites && (convergencePoint.x >= 0.0 && convergencePoint.x <= 1.0 && convergencePoint.y >= 0.0 && convergencePoint.y <= 1.0) && !isnan(convergencePoint.x)) + if ((leftValid || rightValid) && (nbSommets + 1) < getNbSites() && (convergencePoint.x >= 0.0 && convergencePoint.x <= 1.0 && convergencePoint.y >= 0.0 && convergencePoint.y <= 1.0) && !isnan(convergencePoint.x)) { - nbSommets++; - mSommets[0] = convergencePoint; + incrementSommet(); + assignMSommet(0, convergencePoint); draw_line_middle(left->site->point, middle->site->point, right->site->point, convergencePoint, ctxt); } } @@ -474,9 +391,9 @@ void addEvent(stack *mEvents, double beachY, arc_t *left, arc_t *middle, arc_t * } // draw all part of voronoi diagram if the data is valid - if (!present && (leftValid || rightValid) && (nbSommets + 1) < nbSites && (convergencePoint.x >= 0.0 && convergencePoint.x <= 1.0 && convergencePoint.y >= 0.0 && convergencePoint.y <= 1.0) && !isnan(convergencePoint.x)) + if (!present && (leftValid || rightValid) && (nbSommets + 1) < getNbSites() && (convergencePoint.x >= 0.0 && convergencePoint.x <= 1.0 && convergencePoint.y >= 0.0 && convergencePoint.y <= 1.0) && !isnan(convergencePoint.x)) { - nbSommets++; + incrementSommet(); mSommets[nbSommets - 1] = convergencePoint; draw_line_middle(left->site->point, middle->site->point, right->site->point, convergencePoint, ctxt); } @@ -485,13 +402,13 @@ void addEvent(stack *mEvents, double beachY, arc_t *left, arc_t *middle, arc_t * { event_t *event = createEvent(y, convergencePoint, middle); middle->event = event; - //add event in the begin of the stack(queue) + // add event in the begin of the stack(queue) mEvents = addEventQueue(mEvents, *event); } } } -//delete event with the index of the site +// delete event with the index of the site void deleteEvent(stack *mEvents, arc_t *arc) { if (arc->site != NULL) @@ -529,7 +446,7 @@ void removeA(beachline_t *beachL, arc_t *z) yOriginalColor = y->color; x = y->right; if (y->parent == z) - x->parent = y; + x->parent = y; else { changeParent(beachL, y, y->right); @@ -568,10 +485,10 @@ void setPrevHalfEdge(halfEdge_t *prev, halfEdge_t *next) next->prev = prev; } -//print half edge if exist +// print half edge if exist void printHalfEdge(arc_t *arc, struct gfx_context_t *ctxt) { - for (int i = 0; i < nbSommets; i++) + for (int i = 0; i < getNbSommets(); i++) { if (arc->rightHalfEdge != NULL && arc->rightHalfEdge->origin != NULL) { @@ -598,7 +515,7 @@ void printHalfEdge(arc_t *arc, struct gfx_context_t *ctxt) } void removeArc(beachline_t *beachL, arc_t *arc, vec2 *sommet) { - //set origin, destination and twin of the arc prev and arc next + // set origin, destination and twin of the arc prev and arc next setDestination(arc->prev, arc, sommet); setDestination(arc, arc->next, sommet); @@ -617,14 +534,15 @@ void removeArc(beachline_t *beachL, arc_t *arc, vec2 *sommet) arc = NULL; } -void freeArc(beachline_t* beachL, arc_t* arc){ - if (arc->left!=NULL && !isBeginArc(beachL, arc->left)) +void freeArc(beachline_t *beachL, arc_t *arc) +{ + if (arc->left != NULL && !isBeginArc(beachL, arc->left)) { freeArc(beachL, arc->left); } free(arc); - arc=NULL; - if (arc->right!=NULL && !isBeginArc(beachL, arc->right)) + arc = NULL; + if (arc->right != NULL && !isBeginArc(beachL, arc->right)) { freeArc(beachL, arc->right); } diff --git a/fortune/fortune.h b/fortune/fortune.h index 19d2b1898044c18c5af808cb7cc5f8e127f396e0..1bfbd4758304de56dfd8dc8fa4ba1353912a802e 100644 --- a/fortune/fortune.h +++ b/fortune/fortune.h @@ -5,19 +5,6 @@ #include "../pile/pile.h" #define SCREEN_WIDTH 1000 #define SCREEN_HEIGHT 1000 -#define PI 3.14159 - - - - -typedef struct _triangle_t{ - vec2_z facetNormal; - vec2_z p1; - vec2_z p2; - vec2_z p3; -}triangle_t; - - typedef struct _arc_t{ struct _arc_t* parent; @@ -37,7 +24,6 @@ typedef struct _beachline_t{ arc_t* rootArc; }beachline_t; -triangle_t *allTriangles; void construct(int nbPoints, struct gfx_context_t* ctxt, char* filename); void handleSiteEvent(stack *mEvents, event_t *event, beachline_t *beachL, double beachY, struct gfx_context_t* ctxt); @@ -59,7 +45,6 @@ void addEdge(arc_t *left, arc_t *right); vec2 convPoint(vec2 point1, vec2 point2, vec2 point3, double *y); bool isUnderThan(arc_t *left, arc_t *right); double getInitialX(arc_t *left, arc_t *right, bool isUnderThan); -void createSTL(char *filename, int nbTriangle, triangle_t* tr); void removeArc(beachline_t *beachL, arc_t *arc, vec2 *sommet); void freeArc(beachline_t* beachL, arc_t* arc); diff --git a/main.c b/main.c index d01ab0f6188578a575bc3e9b57edbdbdf39eab3b..52d680833f9015ab4c4792171ed6b28057e65bb2 100644 --- a/main.c +++ b/main.c @@ -165,10 +165,10 @@ int main(int argc, char **argv) { parseargs(argc, argv); int nbPoints; - point3Dim = getPoints(argv[1], &nbPoints); + initializePoint3Dim(getPoints(argv[1], &nbPoints)); srand(time(NULL)); - initVoronoiDiagramm(point3Dim, nbPoints); + initVoronoiDiagramm(getPoint3Dim(), nbPoints); struct gfx_context_t *ctxt = gfx_create("Delaunay", SCREEN_WIDTH, SCREEN_HEIGHT); if (!ctxt) @@ -176,12 +176,8 @@ int main(int argc, char **argv) fprintf(stderr, "Graphics initialization failed!\n"); return EXIT_FAILURE; } - vec2 *p2dim = printPoints(ctxt, nbPoints, point3Dim); + vec2 *p2dim = printPoints(ctxt, nbPoints, getPoint3Dim()); - for (int i = 0; i < nbSommets; i++) - { - vec2_print(mSommets[i]); - } char filen[100]; strcpy(filen, argv[1]); // delete ply extension @@ -205,7 +201,6 @@ int main(int argc, char **argv) gfx_destroy(ctxt); free(p2dim); freeAllV(); - free(allTriangles); return EXIT_SUCCESS; diff --git a/voronoi/voronoi.c b/voronoi/voronoi.c index 55a1637289dcb44ec9cfbc562f610cb3c60e9be4..1df6ce6797faafd10df4b8aebff377f4654979af 100644 --- a/voronoi/voronoi.c +++ b/voronoi/voronoi.c @@ -1,13 +1,27 @@ #include "voronoi.h" #include <stdlib.h> #include <stdio.h> +#include <errno.h> +#include <math.h> +#include <string.h> +#include <assert.h> + +triangle_t *allTriangles; +vec2_z *point3Dim; +vec2 *mSommets; +int nbSommets; +queue *qSommets; +site_t *mSites; +int nbSites; +halfEdge_t *mDemiBord; + // init all variables void initVoronoiDiagramm(vec2_z *points, int nbPoints) { mSites = calloc(nbPoints, sizeof(site_t)); - mFaces = calloc(nbPoints, sizeof(face_t)); mSommets = malloc((nbPoints * 2) * sizeof(vec2)); + qSommets = queue_creer(); for (int i = 0; i < (nbPoints * 2); i++) { mSommets[i] = vec2_create_zero(); @@ -21,7 +35,6 @@ void initVoronoiDiagramm(vec2_z *points, int nbPoints) mSites[i].point.x = points[i].x; mSites[i].point.y = points[i].y; - mFaces[i].site = &mSites[i]; } } @@ -35,11 +48,6 @@ int getNbSites() return nbSites; } -face_t *getFace(int index) -{ - return mFaces + index; -} - halfEdge_t *getDemiBord() { return mDemiBord; @@ -60,6 +68,133 @@ void creerSommet(vec2 point) queue_inserer(qSommets, sommet); } +void allocateTriangle(int nbTriangle) +{ + allTriangles = malloc(nbTriangle * sizeof(triangle_t)); +} + +void reallocTriangle(int countTriangle) +{ + allTriangles = realloc(allTriangles, countTriangle); +} + +// calculate and assign all triangles data +void calculateTriangleData(vec2 p1, vec2 p2, vec2 p3, int countTriangle) +{ + double p1Z, p2Z, p3Z; + triangle_t *tr = allTriangles + countTriangle; + + for (int i = 0; i < nbSites; i++) + { + if (point3Dim[i].x == p1.x && point3Dim[i].y == p1.y) + { + p1Z = point3Dim[i].z; + } + if (point3Dim[i].x == p2.x && point3Dim[i].y == p2.y) + { + p2Z = point3Dim[i].z; + } + if (point3Dim[i].x == p3.x && point3Dim[i].y == p3.y) + { + p3Z = point3Dim[i].z; + } + } + + vec2 V2 = vec2_sub(p2, p1); + vec2 W2 = vec2_sub(p3, p1); + vec2_z V = (vec2_z){ + .x = V2.x, + .y = V2.y, + .z = p2Z - p1Z}; + vec2_z W = (vec2_z){ + .x = W2.x, + .y = W2.y, + .z = p3Z - p1Z}; + double Nx = (V.y * W.z) - (V.z * W.y); + double Ny = (V.z * W.x) - (V.x * W.z); + double Nz = (V.x * W.y) - (V.y * W.y); + + tr->facetNormal.x = Nx / (pow(Nx, 2.0) + pow(Ny, 2.0) + pow(Nz, 2.0)); + tr->facetNormal.y = Ny / (pow(Nx, 2.0) + pow(Ny, 2.0) + pow(Nz, 2.0)); + tr->facetNormal.z = Nz / (pow(Nx, 2.0) + pow(Ny, 2.0) + pow(Nz, 2.0)); + + tr->p1.x = p1.x; + tr->p1.y = p1.y; + tr->p1.z = p1Z; + tr->p2.x = p2.x; + tr->p2.y = p2.y; + tr->p2.z = p2Z; + tr->p3.x = p3.x; + tr->p3.y = p3.y; + tr->p3.z = p3Z; +} + + +/** + * It creates a stl file, then it writes the + * STL file format in it + * + * @param filename the name of the file to be created + * @param nbTriangle the number of triangles in the STL file + * @param tr an array of triangles data + */ +void createSTL(char *filename, int nbTriangle) +{ + triangle_t* tr=allTriangles; + char fileComplet[256]; + assert(strcpy(fileComplet, filename) != NULL); + assert(strcat(fileComplet, ".stl") != NULL); + FILE *stl_file = fopen(fileComplet, "w+"); + if (!stl_file) + { + fprintf(stderr, "Error open file: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stl_file, "solid %s\n", filename); + for (int i = 0; i < nbTriangle; i++) + { + fprintf(stl_file, " facet normal %lf %lf %lf\n", tr[i].facetNormal.x, tr[i].facetNormal.y, tr[i].facetNormal.z); + fprintf(stl_file, " outer loop\n"); + fprintf(stl_file, " vertex %lf %lf %lf\n", tr[i].p1.x, tr[i].p1.y, tr[i].p1.z); + fprintf(stl_file, " vertex %lf %lf %lf\n", tr[i].p2.x, tr[i].p2.y, tr[i].p2.z); + fprintf(stl_file, " vertex %lf %lf %lf\n", tr[i].p3.x, tr[i].p3.y, tr[i].p3.z); + fprintf(stl_file, " endloop\n"); + fprintf(stl_file, " endfacet\n"); + } + fprintf(stl_file, "endsolid %s\n", filename); + fclose(stl_file); +} + +void initializePoint3Dim(vec2_z* points){ + point3Dim=points; +} + +vec2_z* getPoint3Dim(){ + return point3Dim; +} + +vec2* getMSommets(){ + return mSommets; +} + +int getNbSommets(){ + return nbSommets; +} + +void incrementSommet(){ + nbSommets++; +} + +void assignMSommet(int indice, vec2 point){ + mSommets[indice]=point; +} + + +queue* getQSommet(){ + return qSommets; +} + + void freeAllV() @@ -69,10 +204,10 @@ void freeAllV() if (mSites->face != NULL) free(mSites->face); free(mSites); - free(mFaces); if (mDemiBord != NULL) { free(mDemiBord); } + free(allTriangles); } diff --git a/voronoi/voronoi.h b/voronoi/voronoi.h index ed077f09b2f2d945fe451a17da5fb27a570c23b4..ed3c896534724e099e8869a5eabfd57a8236b57e 100644 --- a/voronoi/voronoi.h +++ b/voronoi/voronoi.h @@ -16,6 +16,13 @@ typedef struct _vec2_z{ double z; }vec2_z; +typedef struct _triangle_t{ + vec2_z facetNormal; + vec2_z p1; + vec2_z p2; + vec2_z p3; +}triangle_t; + typedef struct _site_t { int index; @@ -47,22 +54,23 @@ typedef struct _intersection_t{ enum side side; }intersection_t; - // printf("arc origin=%lf %lf // arc destination=%lf %lf\n", arc->leftHalfEdge->origin->x, arc->leftHalfEdge->origin->y, arc->leftHalfEdge->destination->x, arc->leftHalfEdge->destination->y); - -site_t *mSites; -int nbSites; -face_t *mFaces; -vec2 *mSommets; -vec2_z* point3Dim; -queue *qSommets; -int nbSommets; -halfEdge_t *mDemiBord; void initVoronoiDiagramm(vec2_z* points, int nbPoints); site_t *getSite(int index); +void allocateTriangle(int nbTriangle); +void calculateTriangleData(vec2 p1, vec2 p2, vec2 p3, int countTriangle); +void reallocTriangle(int countTriangle); +void createSTL(char *filename, int nbTriangle); +void initializePoint3Dim(vec2_z* points); +vec2_z* getPoint3Dim(); int getNbSites(); face_t *getFace(int index); void creerSommet(vec2 point); +vec2* getMSommets(); +int getNbSommets(); +queue* getQSommet(); +void incrementSommet(); +void assignMSommet(int indice, vec2 point); halfEdge_t *getDemiBord(); halfEdge_t* createHalfEdge(face_t* face); void freeAllV();