f3e15b8c8d
- aggiunti file della libreria e progetto visual studio.
429 lines
18 KiB
C++
429 lines
18 KiB
C++
/*****************************************************************************/
|
|
/* */
|
|
/* Copyright (C) 2002--2023 M. Held */
|
|
/* */
|
|
/* This code is not in the public domain. All rights reserved! Please make */
|
|
/* sure to read the full copyright statement contained in "README.txt" or in */
|
|
/* the "main" file of this code, such as "main.cc". */
|
|
/* */
|
|
/*****************************************************************************/
|
|
/* */
|
|
/* Written by: Martin Held */
|
|
/* */
|
|
/* E-Mail: held@cs.sbg.ac.at */
|
|
/* Fax Mail: (+43 662) 8044-611 */
|
|
/* Voice Mail: (+43 662) 8044-6304 */
|
|
/* Snail Mail: Martin Held */
|
|
/* FB Informatik */
|
|
/* Universitaet Salzburg */
|
|
/* A-5020 Salzburg, Austria */
|
|
/* */
|
|
/*****************************************************************************/
|
|
/* */
|
|
/* output routines for VD and DT. */
|
|
/* */
|
|
/*****************************************************************************/
|
|
/* */
|
|
/* get standard libraries */
|
|
/* */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
/* */
|
|
/* get my header files */
|
|
/* */
|
|
#include "fpkernel.h"
|
|
#include "vronivector.h"
|
|
#include "vroni_object.h"
|
|
#include "defs.h"
|
|
|
|
|
|
/* #define GEOMVIEW */
|
|
/* #define OBJ */
|
|
|
|
|
|
|
|
|
|
void vroniObject::WriteVoronoiRegion(int i, FILE *output)
|
|
{
|
|
int i1, number, e, e0, e1, n, n1;
|
|
coord p;
|
|
t_site t1;
|
|
|
|
p = GetPntCoords(i);
|
|
|
|
fprintf(output, "\nVoronoi polygon of pnt %d (%23.16f %23.16f):\n", i - 2,
|
|
FP_PRNTARG(UnscaleX(p.x)),
|
|
FP_PRNTARG(UnscaleY(p.y)));
|
|
|
|
number = num_pnts - 2;
|
|
e0 = GetVDPtr(i, PNT); /* get VD edge that belongs to this region */
|
|
assert(InEdgesList(e0));
|
|
e = e0;
|
|
#ifndef NDEBUG
|
|
if (IsLftSite(e, i, PNT)) n1 = GetStartNode(e);
|
|
else n1 = GetEndNode(e);
|
|
#endif
|
|
|
|
/* */
|
|
/* CCW traversal of the boundary of the Voronoi region of pnt i. */
|
|
/* */
|
|
do {
|
|
/* */
|
|
/* process VD edge e */
|
|
/* */
|
|
if (IsLftSite(e, i, PNT)) {
|
|
n = GetStartNode(e);
|
|
assert(n1 == n);
|
|
n1 = GetEndNode(e);
|
|
e1 = GetCWEdge(e, n1);
|
|
GetRgtSiteData(e, &i1, &t1); /* other defining site of edge e */
|
|
}
|
|
else {
|
|
assert(IsRgtSite(e, i, PNT));
|
|
n = GetEndNode(e);
|
|
assert(n1 == n);
|
|
n1 = GetStartNode(e);
|
|
e1 = GetCWEdge(e, n1);
|
|
GetLftSiteData(e, &i1, &t1); /* other defining site of edge e */
|
|
}
|
|
assert(t1 == PNT);
|
|
if (!IsDeg2Node(n)) {
|
|
/* */
|
|
/* degree-two nodes are artifacts of my algorithm; since they */
|
|
/* do not really belong to the VD, we'll skip them. */
|
|
/* */
|
|
p = GetNodeCoord(n);
|
|
if ((i1 <= 1) || (i1 >= number)) i1 = NIL;
|
|
if (i1 != NIL)
|
|
FP_fprintf(output, "%23.16f %23.16f %d\n",
|
|
FP_PRNTARG(UnscaleX(p.x)),
|
|
FP_PRNTARG(UnscaleY(p.y)),
|
|
i1 - 2);
|
|
else
|
|
FP_fprintf(output, "%23.16f %23.16f %d\n",
|
|
FP_PRNTARG(UnscaleX(p.x)), FP_PRNTARG(UnscaleY(p.y)),
|
|
NIL);
|
|
}
|
|
e = e1;
|
|
} while (e != e0);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
void vroniObject::WriteVDDT(char output_file[])
|
|
#ifdef GEOMVIEW /******************* OFF output for Geomview *****************/
|
|
{
|
|
FILE *output;
|
|
int i, i1, i2, i3, number, e0, e1, n, num_nodes;
|
|
int pnt_cntr = 0, tri_cntr = 0;
|
|
t_site t1, t2, t3;
|
|
#ifdef EXT_APPL_PNTS
|
|
eap_type eap_data;
|
|
#endif
|
|
|
|
output = OpenFileVD(output_file, "w");
|
|
assert(gt(scale_factor, ZERO));
|
|
|
|
/* */
|
|
/* count the number of points and triangles, and write to Geomview file */
|
|
/* */
|
|
number = num_pnts - 2;
|
|
for (i = 2; i < number; ++i) {
|
|
if (!IsDeletedPnt(i)) ++pnt_cntr;
|
|
}
|
|
num_nodes = GetNumberOfNodes();
|
|
for (n = 0; n < num_nodes; ++n) {
|
|
if ((GetNodeStatus(n) != MISC) && (GetNodeStatus(n) != DELETED)) {
|
|
if (!IsDeg2Node(n)) {
|
|
assert(IsNodeUnchecked(n));
|
|
e0 = GetIncidentEdge(n);
|
|
assert(InEdgesList(e0));
|
|
e1 = GetCCWEdge(e0, n);
|
|
if (IsEndNode(e0, n)) {
|
|
GetLftSiteData(e0, &i1, &t1);
|
|
GetRgtSiteData(e0, &i2, &t2);
|
|
}
|
|
else {
|
|
GetLftSiteData(e0, &i2, &t2);
|
|
GetRgtSiteData(e0, &i1, &t1);
|
|
}
|
|
if (IsEndNode(e1, n)) {
|
|
GetRgtSiteData(e1, &i3, &t3);
|
|
}
|
|
else {
|
|
GetLftSiteData(e1, &i3, &t3);
|
|
}
|
|
if ((i1 <= 1) || (i1 >= number)) i1 = NIL;
|
|
if ((i2 <= 1) || (i2 >= number)) i2 = NIL;
|
|
if ((i3 <= 1) || (i3 >= number)) i3 = NIL;
|
|
if ((i1 != NIL) && (i2 != NIL) && (i3 != NIL)) {
|
|
/* */
|
|
/* all three points are original input points */
|
|
/* */
|
|
++tri_cntr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fprintf(output, "OFF\n");
|
|
fprintf(output, "%d %d %d\n", pnt_cntr, tri_cntr, 3 * tri_cntr);
|
|
|
|
/* */
|
|
/* write the point sites in sorted order. (the first two and the last two */
|
|
/* points are not output since they do not belong to the original input.) */
|
|
/* */
|
|
for (i = 2; i < number; ++i) {
|
|
if (!IsDeletedPnt(i)) {
|
|
#ifdef EXT_APPL_PNTS /* write coords plus site ID */
|
|
eap_data = GetExtApplPnt(i);
|
|
WritePntData(output, UnscaleX(GetPntCoords(i).x), UnscaleY(GetPntCoords(i).y),
|
|
&eap_data);
|
|
#else /* write coords only */
|
|
WritePntData(output, UnscaleX(GetPntCoords(i).x), UnscaleY(GetPntCoords(i).y));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* */
|
|
/* output all triangles of the DT; the vertices of all triangles are */
|
|
/* arranged in CCW order. */
|
|
/* */
|
|
for (n = 0; n < num_nodes; ++n) {
|
|
/* */
|
|
/* loop through all nodes and check whether they are part of the final */
|
|
/* VD. */
|
|
/* */
|
|
if ((GetNodeStatus(n) != MISC) && (GetNodeStatus(n) != DELETED)) {
|
|
if (!IsDeg2Node(n)) {
|
|
/* */
|
|
/* this is a genuine degree-three node of the VD that */
|
|
/* corresponds to a triangle of the DT */
|
|
/* */
|
|
assert(IsNodeUnchecked(n));
|
|
e0 = GetIncidentEdge(n);
|
|
assert(InEdgesList(e0));
|
|
e1 = GetCCWEdge(e0, n);
|
|
if (IsEndNode(e0, n)) {
|
|
GetLftSiteData(e0, &i1, &t1);
|
|
GetRgtSiteData(e0, &i2, &t2);
|
|
}
|
|
else {
|
|
GetLftSiteData(e0, &i2, &t2);
|
|
GetRgtSiteData(e0, &i1, &t1);
|
|
}
|
|
if (IsEndNode(e1, n)) {
|
|
GetRgtSiteData(e1, &i3, &t3);
|
|
}
|
|
else {
|
|
GetLftSiteData(e1, &i3, &t3);
|
|
}
|
|
if ((i1 <= 1) || (i1 >= number)) i1 = NIL;
|
|
if ((i2 <= 1) || (i2 >= number)) i2 = NIL;
|
|
if ((i3 <= 1) || (i3 >= number)) i3 = NIL;
|
|
if ((i1 != NIL) && (i2 != NIL) && (i3 != NIL)) {
|
|
/* */
|
|
/* all three points are original input points */
|
|
/* */
|
|
assert(t1 == PNT);
|
|
assert(t2 == PNT);
|
|
assert(t3 == PNT);
|
|
fprintf(output, "3 %d %d %d 0 255 0\n",
|
|
i1 - 2 , i2 - 2, i3 - 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(output);
|
|
|
|
return;
|
|
}
|
|
#else
|
|
#ifdef OBJ /********************** output in OBJ format **********************/
|
|
{
|
|
FILE *output;
|
|
int i, i1, i2, i3, number, e0, e1, n, num_nodes;
|
|
t_site t1, t2, t3;
|
|
#ifdef EXT_APPL_PNTS
|
|
eap_type eap_data;
|
|
#endif
|
|
|
|
output = OpenFileVD(output_file, "w");
|
|
assert(gt(scale_factor, ZERO));
|
|
|
|
/* */
|
|
/* write the point sites in sorted order. (the first two and the last two */
|
|
/* points are not output since they do not belong to the original input.) */
|
|
/* */
|
|
number = num_pnts - 2;
|
|
for (i = 2; i < number; ++i) {
|
|
if (!IsDeletedPnt(i)) {
|
|
#ifdef EXT_APPL_PNTS /* write coords plus site ID */
|
|
eap_data = GetExtApplPnt(i);
|
|
WritePntData(output, UnscaleX(GetPntCoords(i).x), UnscaleY(GetPntCoords(i).y),
|
|
&eap_data);
|
|
#else /* write coords only */
|
|
WritePntData(output, UnscaleX(GetPntCoords(i).x), UnscaleY(GetPntCoords(i).y));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* */
|
|
/* output all triangles of the DT; the vertices of all triangles are */
|
|
/* arranged in CCW order. */
|
|
/* */
|
|
num_nodes = GetNumberOfNodes();
|
|
for (n = 0; n < num_nodes; ++n) {
|
|
/* */
|
|
/* loop through all nodes and check whether they are part of the final */
|
|
/* VD. */
|
|
/* */
|
|
if ((GetNodeStatus(n) != MISC) && (GetNodeStatus(n) != DELETED)) {
|
|
if (!IsDeg2Node(n)) {
|
|
/* */
|
|
/* this is a genuine degree-three node of the VD that */
|
|
/* corresponds to a triangle of the DT */
|
|
/* */
|
|
assert(IsNodeUnchecked(n));
|
|
e0 = GetIncidentEdge(n);
|
|
assert(InEdgesList(e0));
|
|
e1 = GetCCWEdge(e0, n);
|
|
if (IsEndNode(e0, n)) {
|
|
GetLftSiteData(e0, &i1, &t1);
|
|
GetRgtSiteData(e0, &i2, &t2);
|
|
}
|
|
else {
|
|
GetLftSiteData(e0, &i2, &t2);
|
|
GetRgtSiteData(e0, &i1, &t1);
|
|
}
|
|
if (IsEndNode(e1, n)) {
|
|
GetRgtSiteData(e1, &i3, &t3);
|
|
}
|
|
else {
|
|
GetLftSiteData(e1, &i3, &t3);
|
|
}
|
|
if ((i1 <= 1) || (i1 >= number)) i1 = NIL;
|
|
if ((i2 <= 1) || (i2 >= number)) i2 = NIL;
|
|
if ((i3 <= 1) || (i3 >= number)) i3 = NIL;
|
|
if ((i1 != NIL) && (i2 != NIL) && (i3 != NIL)) {
|
|
/* */
|
|
/* all three points are original input points */
|
|
/* */
|
|
assert(t1 == PNT);
|
|
assert(t2 == PNT);
|
|
assert(t3 == PNT);
|
|
fprintf(output, "f %d %d %d\n", i1 - 1 , i2 - 1, i3 - 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(output);
|
|
|
|
return;
|
|
}
|
|
#else /******************** standard output **********************************/
|
|
{
|
|
FILE *output;
|
|
int i, i1, i2, i3, number, e0, e1, n, num_nodes;
|
|
coord p;
|
|
t_site t1, t2, t3;
|
|
#ifdef EXT_APPL_PNTS
|
|
eap_type eap_data;
|
|
#endif
|
|
|
|
output = OpenFileVD(output_file, "w");
|
|
assert(gt(scale_factor, ZERO));
|
|
|
|
/* */
|
|
/* write the point sites in sorted order. (the first two and the last two */
|
|
/* points are not output since they do not belong to the original input.) */
|
|
/* */
|
|
number = num_pnts - 2;
|
|
fprintf(output, "%d\n", number - 2);
|
|
for (i = 2; i < number; ++i) {
|
|
if (!IsDeletedPnt(i)) {
|
|
#ifdef EXT_APPL_PNTS /* write coords plus site ID */
|
|
eap_data = GetExtApplPnt(i);
|
|
WritePntData(output, UnscaleX(GetPntCoords(i).x), UnscaleY(GetPntCoords(i).y),
|
|
&eap_data);
|
|
#else /* write coords only */
|
|
WritePntData(output, UnscaleX(GetPntCoords(i).x), UnscaleY(GetPntCoords(i).y));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* */
|
|
/* traverse all Voronoi regions and write their boundaries in CCW order */
|
|
/* */
|
|
for (i = 2; i < number; ++i) {
|
|
if (!IsDeletedPnt(i)) {
|
|
WriteVoronoiRegion(i, output);
|
|
}
|
|
}
|
|
|
|
/* */
|
|
/* output all triangles of the DT; the vertices of all triangles are */
|
|
/* arranged in CCW order. */
|
|
/* */
|
|
fprintf(output, "\nDelaunay triangles:\n");
|
|
|
|
num_nodes = GetNumberOfNodes();
|
|
for (n = 0; n < num_nodes; ++n) {
|
|
/* */
|
|
/* loop through all nodes and check whether they are part of the final */
|
|
/* VD. */
|
|
/* */
|
|
if ((GetNodeStatus(n) != MISC) && (GetNodeStatus(n) != DELETED)) {
|
|
if (!IsDeg2Node(n)) {
|
|
/* */
|
|
/* this is a genuine degree-three node of the VD that */
|
|
/* corresponds to a triangle of the DT */
|
|
/* */
|
|
assert(IsNodeUnchecked(n));
|
|
e0 = GetIncidentEdge(n);
|
|
assert(InEdgesList(e0));
|
|
e1 = GetCCWEdge(e0, n);
|
|
if (IsEndNode(e0, n)) {
|
|
GetLftSiteData(e0, &i1, &t1);
|
|
GetRgtSiteData(e0, &i2, &t2);
|
|
}
|
|
else {
|
|
GetLftSiteData(e0, &i2, &t2);
|
|
GetRgtSiteData(e0, &i1, &t1);
|
|
}
|
|
if (IsEndNode(e1, n)) {
|
|
GetRgtSiteData(e1, &i3, &t3);
|
|
}
|
|
else {
|
|
GetLftSiteData(e1, &i3, &t3);
|
|
}
|
|
if ((i1 <= 1) || (i1 >= number)) i1 = NIL;
|
|
if ((i2 <= 1) || (i2 >= number)) i2 = NIL;
|
|
if ((i3 <= 1) || (i3 >= number)) i3 = NIL;
|
|
if ((i1 != NIL) && (i2 != NIL) && (i3 != NIL)) {
|
|
/* */
|
|
/* all three points are original input points */
|
|
/* */
|
|
assert(t1 == PNT);
|
|
assert(t2 == PNT);
|
|
assert(t3 == PNT);
|
|
fprintf(output, "%d %d %d\n", i1 - 2 , i2 - 2, i3 - 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(output);
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
#endif
|