Files
fist/orientation.cpp
SaraP cbec90699f FIST 6.8 :
- creato il progetto in Visual Studio per compilare come libreria statica
- modifiche al codice originale per integrarlo nelle nostre librerie.
2025-03-04 16:19:35 +01:00

191 lines
7.1 KiB
C++

/*****************************************************************************/
/* */
/* F I S T : Fast, Industrial-Strength Triangulation */
/* */
/*****************************************************************************/
/* */
/* (C) Martin Held */
/* (C) Universitaet Salzburg, Salzburg, Austria */
/* */
/* This code is not in the public domain. All rights reserved! Please make */
/* sure to read the full copyright statement contained in api_functions.cpp. */
/* */
/*****************************************************************************/
/* */
/* get standard libraries */
/* */
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "martin.h"
#include "defs.h"
#include "list.h"
#include "header.h"
#include "basic.h"
#include "numerics.h"
/* */
/* prototypes of functions provided in this file */
/* */
void AdjustOrientation(global_struct *all, int i1, int i2);
double PolygonArea(global_struct *all, list_ind ind);
void DetermineOrientation(global_struct *all, list_ind ind);
void FreeOrientation(global_struct *all);
/* */
/* determine the outer polygon and the orientation of the polygons; the */
/* default orientation is CCW for the outer-most polygon, and CW for the */
/* inner polygons. the polygonal loops are referenced by loops[i1,..,i2-1]. */
/* */
void AdjustOrientation(global_struct *all, int i1, int i2)
{
listdef *list = &all->c_list;
double area;
int i, outer;
list_ind ind;
assert(i1 < i2);
if (list->num_loops > all->max_num_poly_area) {
all->poly_area = CORE_ReallocateArray(list->memptr, all->poly_area, all->max_num_poly_area,
list->num_loops, double, "orientation:poly_area");
all->max_num_poly_area = list->num_loops;
}
/* */
/* for each contour, compute its signed area, i.e., its orientation. the */
/* contour with largest area is assumed to be the outer-most contour. */
/* */
#ifdef PARTITION_FIST
#pragma omp parallel for
#endif
for (i = i1; i < i2; ++i) {
ind = list->loops[i];
all->poly_area[i] = PolygonArea(all, ind);
}
/* */
/* determine the outer-most contour */
/* */
area = Abs(all->poly_area[i1]);
outer = i1;
#ifdef PARTITION_FIST
#pragma omp parallel for
#endif
for (i = i1 + 1; i < i2; ++i) {
if (area < Abs(all->poly_area[i])) {
area = Abs(all->poly_area[i]);
outer = i;
}
}
/* */
/* default: the outer contour is referenced by loops[i1] */
/* */
if (outer != i1) {
Swap(list->loops[i1], list->loops[outer], ind);
Swap(all->poly_area[i1], all->poly_area[outer], area);
}
/* */
/* adjust the orientation */
/* */
if (all->poly_area[i1] < C_0_0) {
SwapLinks(list, list->loops[i1]);
// MODIF : nel nostro caso è l'orientamento del loop esterno a determinare l'orientamento dei triangoli, quindi
// salvo il suo orientamento come viene fatto nel caso di un singolo loop in DetermineOrientation
all->ccw_loop = false ;
}
#ifdef PARTITION_FIST
#pragma omp parallel for
#endif
for (i = i1 + 1; i < i2; ++i) {
if (all->poly_area[i] > C_0_0) SwapLinks(list, list->loops[i]);
}
return;
}
void FreeOrientation(global_struct *all)
{
all->max_num_poly_area = 0;
CORE_FreeMemory((debug_memdef*)(&all->c_mem), &all->poly_area, "orientation:poly_area");
return;
}
/* */
/* this function computes twice the signed area of a simple closed polygon */
/* */
double PolygonArea(global_struct *all, list_ind ind)
{
listdef *list = &all->c_list;
datadef *data = &all->c_data;
tmp_data_def tmp_data;
int hook = 0;
list_ind ind1, ind2;
int i1, i2;
double area = C_0_0, area1 = C_0_0;
ind1 = ind;
i1 = GetIndex(list, ind1);
ind2 = GetNextNode(list, ind1);
i2 = GetIndex(list, ind2);
StableDet2D(data, tmp_data, hook, i1, i2, area);
ind1 = ind2;
i1 = i2;
while (ind1 != ind) {
ind2 = GetNextNode(list, ind1);
i2 = GetIndex(list, ind2);
StableDet2D(data, tmp_data, hook, i1, i2, area1);
area += area1;
ind1 = ind2;
i1 = i2;
}
return area;
}
/* */
/* determine the orientation of the polygon; the default orientation is CCW */
/* */
void DetermineOrientation(global_struct *all, list_ind ind)
{
double area;
/* */
/* compute the polygon's signed area, i.e., its orientation. */
/* */
area = PolygonArea(all, ind);
/* */
/* adjust the orientation (i.e., make it CCW) */
/* */
if (area < C_0_0) {
SwapLinks(&all->c_list, ind);
all->ccw_loop = false;
}
return;
}