diff --git a/vroni/Include/api_functions.h b/vroni/Include/api_functions.h new file mode 100644 index 0000000..4147b06 --- /dev/null +++ b/vroni/Include/api_functions.h @@ -0,0 +1,130 @@ +// recupero le definizioni dal file api_functions.cc + +#pragma once + +/* */ +/* get standard libraries */ +/* */ +#include +#include +#include +#include +#include +#include +#include + + +/* */ +/* get my header files */ +/* */ +#include "fpkernel.h" +#include "coord.h" +#include "vroni_object.h" + + +/* */ +/* function prototypes of functions provided in this file; see arg_eval.cc */ +/* for the default values of most of those parameters. */ +/* */ + +// get access to underlying VD +vroniObject& API_VD(); + +void API_ParseCommandLineArgs(int argc, char *argv[], vr_bool *graphics, vr_bool *color_graphics, vr_bool *full_screen); + +// call this routine once prior calling any other routine of VRONI +void API_InitializeProgram(void); + +void API_GetInputData(vr_bool *input_received); + +void API_ProceedWithoutGraphics(vr_bool new_input); + +// call this routine whenever new data is to be input and VRONI's data structures are to be reset; +// note that this function won't free memory allocated +void API_ResetAll(void); + +// call this routine to release all memory allocated by VRONI +void API_TerminateProgram(void); + + +void API_HandleInput(char input_file[], // name of the input file + vr_bool *new_input, // true if new data has been read + vr_bool read_polygon, // read ".dat" format + vr_bool read_poly, // read ".poly" format + vr_bool read_sites, // read ".site" format + vr_bool read_xdr, // read ".xdr" format + vr_bool read_e00, // read ".e00" format + vr_bool read_polylines, // read ".polylines" format + vr_bool read_usgs, // read ".usgs" format + vr_bool read_dxf, // read ".dxf" format + vr_bool read_pnts, // read ".pnt" format + vr_bool read_graphml); // read ".graphml" format + +// this function requires the user to stick to my naming convention for the extension of the input file relative to the data format used +void API_FileInput(char input_file[], // name of the input file + vr_bool *new_input); // true if new data has been read + +void API_ArrayInput( int number_of_points, // data in point_data[0,..,k] for k := number_of_points-1 + in_pnts *point_data, // see ext_appl_inout.h + int number_of_segments, + in_segs *segment_data, // see ext_appl_inout.h + int number_of_arcs, + in_arcs *arc_data, // see ext_appl_inout.h + vr_bool *new_input); + +void API_ComputeVD( vr_bool save_data, // save input data to file? + vr_bool new_data, // first call for this data? + vr_bool time, // do you want to time the computation? + int bound, // scale factor for bounding box; default value: 3 + int sample, // sampling factor for sampling segs/arcs; default: 0; see SampleData() in approx.cc + int approx, // approximation factor for circular arcs; default: 0; see ApproxArcsHeuristic() in approx.cc. obsolet by now! + char output_file[], // name of the output file; irrelevant if save_data is false + vr_bool discard_duplicate_sites, //d shall the code check prior to the computation whether duplicate segs/arcs have been input? default: false. + vr_bool pnts_only, // compute VD/DT of points only + vr_bool write_vd_dt, // output point VD/DT + char vd_dt_file[], // output file for point VD/DT + vr_bool clean_up); // shall we clean up the data prior to the VD computation? + +void API_ComputeOff( vr_bool time, // do you want to time the computation? + char off_file[], // name of the file that will contain the offsets computed + vr_bool write_off, // shall we output the offsets to off_file[]? + vr_bool dxf_format, // if offsets are to be output: shall we use DXF format? + double t_offset, // compute offset curve(s) for offset distance t_offset + double d_offset, // incremental step-over distance for further offset curves + vr_bool auto_offset, // shall we use my heuristic for finding offset distances that create a family of offsets? + vr_bool left_offset, // true if offsets are to be computed only on the left side of input segments + vr_bool right_offset); // true if offsets are to be computed only on the right side of input segments + + +void API_ComputeWMAT( vr_bool auto_wmat, // shall we use my heuristic for finding nice WMAT thresholds? + double wmat_angle, // angle threshold for WMAT computation;in radians, out of the interval [0, pi] + double wmat_dist, // distance threshold for WMAT computation + vr_bool time, // do you want to time the computation? + vr_bool left_wmat, // true if WMAT is to be computed only on the left side of input segments + vr_bool right_wmat); // true if WMAT is to be computed only on the right side of input segments + + +#ifdef WRITE_VD +void API_Output_VD( char vd_file[], // name of the file that will contain the VD polygons + double vd_apx_dist, // sampling distance used for approximating conic VD edges + vr_bool left_vd, // true if VD is to be output only on the left side of input segments + vr_bool right_vd); // true if VD is to be output on the right side of input segments +#endif + +void API_ComputeOutputMIC( vr_bool time, // do you want to time the computation? + vr_bool left_mic, // true if MIC is to be computed only on the left side of input segments + vr_bool right_mic, // true if MIC is to be computed only on the right side of input segments + coord *center, // x,y-coordinates of a MIC center + double *radius); // radius of a MIC circle + +void API_OutputMA(char vdma_file[]) ; + +// discard all offsets computed so far +void API_ResetOffsetData(void); + +// VRONI exception handling +void API_HandleError(void); + +const char* API_GetProgName(); +const char* API_GetProgVersion(); +const char* API_GetProgYear(); diff --git a/vroni/Include/approx.h b/vroni/Include/approx.h new file mode 100644 index 0000000..2032daa --- /dev/null +++ b/vroni/Include/approx.h @@ -0,0 +1,101 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2003--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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_APPROX_H +#define VRONI_APPROX_H + +inline void ApproxArc(const coord & p1, const coord & p2, + double_arg xc3, double_arg yc3, double_arg radius, + vr_bool ccw_orientation, double_arg apx_absolute, + vronivector & apx_vtx, int & max_num_apx_vtx, + double_arg max_incr, int & number) +{ + double incr; + /* */ + /* determine the start angle and end angle of the arc */ + /* */ + double angle_s = atan2(p1.y - yc3, p1.x - xc3); + double angle_e = atan2(p2.y - yc3, p2.x - xc3); + + if (angle_s < 0.0) angle_s += M_2PI; + if (angle_e < 0.0) angle_e += M_2PI; + if (angle_e < angle_s) angle_e += M_2PI; + + /* */ + /* determine the angular increment incr: we will insert points at */ + /* the angles angle_s + 0.5 * incr, angle_s + 1.5 * incr, ..., */ + /* angle_e - 0.5 * incr (for a CCW arc). */ + /* */ + + if (apx_absolute > 0.0) { + incr = acos(radius / (radius + apx_absolute)); + incr = Min(incr, max_incr); + } + else { + incr = max_incr; + } + incr *= 10.0; + assert(gt(incr, ZERO)); + double diff = (angle_e - angle_s); + incr = diff / (2.0 * incr); + number = REAL_TO_INT(Ceiling(incr)); + if (number <= 0) number = 1; + incr = diff / ((double) (number)); + + /* */ + /* the new pnts will lie at a distance lgth from the arc's center */ + /* */ + // double lgth = radius / cos(incr / 2.0); + double lgth = radius; + double alpha; + if (ccw_orientation) { + alpha = angle_s + incr / 2.0; + } + else { + alpha = angle_e - incr / 2.0; + incr = - incr; + } + + /* */ + /* allocate memory for the new vertices to be computed */ + /* */ + if (number > max_num_apx_vtx) { + max_num_apx_vtx = number; + gentlyResizeSTLVector(apx_vtx, max_num_apx_vtx, "approx:apx_vtx"); + } + + /* */ + /* compute and store the new pnts and segs */ + /* */ + //printf("p1.x = %20.16f, p1.y = %20.16f\n", p1.x, p1.y); + //printf("p2.x = %20.16f, p2.y = %20.16f\n", p2.x, p2.y); + for (int k = 0; k < number; ++k) { + assert(k <= max_num_apx_vtx); + apx_vtx[k].x = xc3 + lgth * cos(alpha); + apx_vtx[k].y = yc3 + lgth * sin(alpha); + //printf("alpha = %20.16f\n", alpha); + alpha += incr; + } +} + + +#endif diff --git a/vroni/Include/arc_common.h b/vroni/Include/arc_common.h new file mode 100644 index 0000000..57b5546 --- /dev/null +++ b/vroni/Include/arc_common.h @@ -0,0 +1,46 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2007-2023 M. Held, S. Huber */ +/* */ +/* 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: Stefan Huber, 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 */ +/* */ +/*****************************************************************************/ + + +#ifndef VRONI_ARC_COMMON_H +#define VRONI_ARC_COMMON_H + + + //Uncomment this line to print quality messages + //#define ARC_QUALITY_MSG + + + /** Test if pnt is in arc-cone. */ +inline vr_bool vroniObject::IsPntInArcCone(int arc, coord pnt) +{ + return IsPntInArcConeEps(arc, pnt, ZERO); +} + +/** Test if pnt is in arc-cone. */ +inline vr_bool vroniObject::IsPntInArcConeStrict(int arc, coord pnt) +{ + return IsPntInArcConeEps(arc, pnt, -ZERO); +} + +#endif + + diff --git a/vroni/Include/basic.h b/vroni/Include/basic.h new file mode 100644 index 0000000..a1c2b7d --- /dev/null +++ b/vroni/Include/basic.h @@ -0,0 +1,117 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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.c". */ +/* */ +/*****************************************************************************/ +/* */ +/* 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 */ +/* */ +/*****************************************************************************/ + + + +#ifndef VRONI_BASIC_H +#define VRONI_BASIC_H + + +#include "consts.h" +#include "util.h" +#include "types.h" + + + +#define BASIC_MINI 1.0e-20 + +#ifndef RAND + +#define RND_MAX 2147483647 + +#define UniformRandom(x) \ +{\ + x = ((double) random()) / RND_MAX; } + +#define RandomInteger(N) \ + (\ + assert(N > 0), \ + basic_i_local = random(), \ + basic_i_local - (basic_i_local / (N)) * (N)) + +#define InitRandom(seed) \ +{\ + srandom(seed); } + +#else + +#ifdef RAND_MAX +#define RND_MAX RAND_MAX +#else +#define RND_MAX 32767 +#endif + +#define UniformRandom(x) \ +{\ + x = ((double) rand()) / RND_MAX; \ +} + +#define RandomInteger(N) \ + (\ + assert(N > 0), \ + basic_i_local = rand(), \ + basic_i_local - (basic_i_local / (N)) * (N)) + + +#define InitRandom(seed) \ +{\ + srand(seed); } + +#endif + + + + + + +/* +#define ScaleX(xc) (scale_factor * (xc - shift.x)) + +#define ScaleY(yc) (scale_factor * (yc - shift.y)) + +#define ScaleV(value) (value * scale_factor) + +#define UnscaleX(xc) (assert(scale_factor > 0.0), xc / scale_factor + shift.x) + +#define UnscaleY(yc) (assert(scale_factor > 0.0), yc / scale_factor + shift.y) + +#define UnscaleV(value) (assert(scale_factor > 0.0), value / scale_factor) +*/ + + + + +#define CirBBox(p, r, bb_min, bb_max) {\ + (bb_min).x = (p).x - r; \ + (bb_min).y = (p).y - r; \ + (bb_max).x = (p).x + r; \ + (bb_max).y = (p).y + r; } + + +#define TriBBox(a, b, c, bb_min, bb_max) {\ + MinMax3((a).x, (b).x, (c).x, (bb_min).x, (bb_max).x); \ + MinMax3((a).y, (b).y, (c).y, (bb_min).y, (bb_max).y); } + + + + +#endif diff --git a/vroni/Include/consts.h b/vroni/Include/consts.h new file mode 100644 index 0000000..26e2a22 --- /dev/null +++ b/vroni/Include/consts.h @@ -0,0 +1,189 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2010-2023 M. Held, S. Huber */ +/* */ +/* 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: Stefan Huber, 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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_CONSTS_H +#define VRONI_CONSTS_H + +#ifndef DOUBLE_OVERRIDE +/* */ +/* please do not change the following tolerance thresholds */ +/* */ +#define TINY 1.0e-14 /* about the size of the machine precision */ +#define SMALL 0.0078125 /* 0.01 >= SMALL = 1/128 >> ZERO */ +#define INVERSE_SMALL 128.0 /* INVERSE_SMALL = 1/SMALL */ +/* */ +/* the following tolerance thresholds may be changed if you know what you do */ +/* */ +#define ZERO 1.0e-13 /* small number with ZERO >= TINY */ +#define ZERO_MAX 1.0e-5 /* SMALL >> ZERO_MAX >= ZERO */ +#define ZERO_IO 1.0e-5 /* SMALL >> ZERO_IO >= ZERO_MAX */ +#define DECENT 1.0e-10 /* = ZERO_MAX / 1000 */ +#define GRAZE 1.0e-4 /* = ZERO_MAX * 10 */ +/* */ +/* the following thresholds depend on thresholds defined in previous lines */ +/* */ +#define THRESHOLD 1.0e-6 /* THRESHOLD = ZERO_MAX / 10.0 */ +#define ZERO2 1.0e-26 /* ZERO2 = ZERO * ZERO */ + + +#endif + +#define NIL -1 +#define APPROX 10 +#define MAX_RESTART 50 /* max. number of retries if computation fails */ + +#ifdef WITH_MPFRBACKEND + +extern double SMALL; +extern double INVERSE_SMALL; +extern double ZERO_IO; +extern double ZERO_MAX; +extern double ZERO; +extern double ZERO2; +extern double THRESHOLD; +extern double TINY; + +#elif defined(WITH_COREBACKEND) + +const double SMALL = 0; +/* INVERSE_SMALL is not used anyway of SMALL == 0, so keep value from + plain value. */ +const double INVERSE_SMALL = 128; +const double ZERO_IO = 1.0e-6; +const double ZERO_MAX = 0; +const double ZERO = 0; +const double ZERO2 = 0; +const double THRESHOLD = 0; +const double TINY = 0; + +#endif + + + +#ifndef DOUBLE_OVERRIDE + + + #ifndef M_E + #define M_E 2.71828182845904553488 + #endif + #ifndef M_1_E + #define M_1_E 0.36787944117144227851 + #endif + #ifndef M_LOG2E + #define M_LOG2E 1.44269504088896360904 + #endif + #ifndef M_LOG10E + #define M_LOG10E 0.43429448190325182765 + #endif + #ifndef M_LN2 + #define M_LN2 0.69314718055994530942 + #endif + #ifndef M_LN10 + #define M_LN10 2.30258509299404568402 + #endif + #ifndef M_PI + #define M_PI 3.14159265358979323846 + #endif + #ifndef M_PI_2 + #define M_PI_2 1.57079632679489661923 + #endif + #ifndef M_PI_4 + #define M_PI_4 0.78539816339744830962 + #endif + #ifndef M_PI_8 + #define M_PI_8 0.39269908169872415481 + #endif + #ifndef M_1_PI + #define M_1_PI 0.31830988618379067154 + #endif + #ifndef M_2_PI + #define M_2_PI 0.63661977236758134308 + #endif + #ifndef M_2PI + #define M_2PI 6.28318530717958623199 + #endif + #ifndef M_180_PI + #define M_180_PI 57.2957795130823208767 + #endif + #ifndef M_PI_180 + #define M_PI_180 0.01745329251994329576 + #endif + #ifndef M_2_SQRTPI + #define M_2_SQRTPI 1.12837916709551257390 + #endif + #ifndef M_SQRT2 + #define M_SQRT2 1.41421356237309504880 + #endif + #ifndef M_SQRT1_2 + #define M_SQRT1_2 0.70710678118654752440 + #endif + #ifndef M_SQRT3 + #define M_SQRT3 1.73205080756887719317 + #endif + #ifndef M_SQRT1_3 + #define M_SQRT1_3 0.57735026918962584208 + #endif + #ifndef M_1_3 + #define M_1_3 0.33333333333333333333 + #endif + +#elif defined(WITH_MPFRBACKEND) + +extern double M_1_3; +extern double M_180_PI; +extern double M_PI_180; +#undef M_SQRT2 +extern double M_SQRT2; +#undef M_PI_4 +extern double M_PI_4; +#undef M_PI_2 +extern double M_PI_2; +#undef M_PI +extern double M_PI; +#undef M_2PI +extern double M_2PI; + +#else +//defined(WITH_COREBACKEND) + +const double M_1_3 = double(1) / 3; +#undef M_SQRT2 +const double M_SQRT2 = sqrt(double(2)); +#undef M_PI +const double M_PI = pi(); +#undef M_PI_4 +const double M_PI_4 = M_PI / 4; +#undef M_PI_2 +const double M_PI_2 = M_PI / 2;; +#undef M_2PI +const double M_2PI = M_PI * 2; +const double M_180_PI = 180 / M_PI; +const double M_PI_180 = M_PI * 180; + +#endif + + + + + + +#endif diff --git a/vroni/Include/coord.h b/vroni/Include/coord.h new file mode 100644 index 0000000..6927d76 --- /dev/null +++ b/vroni/Include/coord.h @@ -0,0 +1,171 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2010-2023 M. Held, S. Huber */ +/* */ +/* 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: Stefan Huber */ +/* Modified: 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 */ +/* */ +/*****************************************************************************/ + + +#ifndef VRONI_COORD_H +#define VRONI_COORD_H + + +#ifndef DOUBLE_OVERRIDE +#include +#endif + +#include "fpkernel.h" + +/** Defines a vector in the plane */ +struct coord { + double x; + double y; + inline coord(double_arg x, double_arg y) : x(x), y(y) {} + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline coord() {} +}; + +struct coord3D { + double x; + double y; + double z; + inline coord3D(double_arg x, double_arg y, double_arg z) : x(x), y(y), z(z) {} + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline coord3D() {} +}; + + + +/** Computes determinant of 3x3 matrix given by homogeneous coordinates + * of the three column vectors u, v and w. */ +inline static double VecDet(coord u, coord v, coord w) +{ + return (((u).x - (v).x) * ((v).y - (w).y) + ((v).y - (u).y) * ((v).x - (w).x)); +} + + +/** Computes standard inner-product of vectors u and v */ +inline static double VecDotProd(coord u, coord v) +{ + return (((u).x * (v).x) + ((u).y * (v).y)); +} + + +/** Adds two vectors */ +inline static coord VecAdd(coord p, coord q) +{ + coord r; + r.x = p.x + q.x; + r.y = p.y + q.y; + return r; +} + +/** Subtracs two vectors */ +inline static coord VecSub(coord p, coord q) +{ + coord r; + r.x = p.x - q.x; + r.y = p.y - q.y; + return r; +} + + +/** Multiply vector with scalar */ +inline static coord VecMult(double_arg scalar, const coord & u) +{ + coord r; + r.x = scalar * u.x; + r.y = scalar * u.y; + return r; +} + + +/** Divide vector by scalar */ +inline static coord VecDiv(double_arg scalar, const coord & u) +{ + return VecMult(1.0/scalar, u); +} + + +/** Get vector -p of p */ +inline static coord VecInv(coord p) +{ + coord q; + q.x = -p.x; + q.y = -p.y; + return q; +} + + +/** Squared vector length */ +inline static double VecLenSq(coord p) +{ + return (p.x*p.x + p.y*p.y); +} + + +/** Vector length */ +inline static double VecLen(coord p) +{ + return sqrt(VecLenSq(p)); +} + +/** Normalize vector */ +inline static coord VecNorm(coord p) +{ + return VecDiv(VecLen(p), p); +} + + +/** Get counter clock-wise 90 degree rotation */ +inline static coord VecCCW(coord p) +{ + coord q; + q.x = -p.y; + q.y = p.x; + return q; +} + + +/** Get clock-wise 90 degree rotation */ +inline static coord VecCW(coord p) +{ + coord q; + q.x = p.y; + q.y = -p.x; + return q; +} + + + +/** Make vector by its coordinates */ +inline static coord MakeVec(double_arg x, double_arg y) +{ + coord p; + p.x = x; + p.y = y; + return p; +} + + + + + +#endif + diff --git a/vroni/Include/coreatan2.h b/vroni/Include/coreatan2.h new file mode 100644 index 0000000..b24b68c --- /dev/null +++ b/vroni/Include/coreatan2.h @@ -0,0 +1,81 @@ +/* */ +/* Copyright (C) 1999-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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_CORE_ATAN2_H +#define VRONI_CPRE_ATAN2_H + + +inline double atan2local(const double &y, const double &x) +{ + if( fabs(x) >= fabs(y) ) + { + // Sector to the right + if( x > 0 ) + { + const double phi = y/x; + return atan(phi); + } + // Sector to the left + else if( x < 0 ) + { + const double phi = y/x; + if( y >= 0) { + return atan(phi) + M_PI; + } else { + return atan(phi) - M_PI; + } + } + // Hence, x and y are zero + else + { + return 0.0; + } + } + else if( fabs(y) >= fabs(x) ) + { + // Sector to the top + if( y > 0 ) + { + const double phi = x/y; + return M_PI_2 - atan(phi); + } + // Sector to the bottom + if( y < 0 ) + { + const double phi = x/y; + return - M_PI_2 - atan(phi); + } + // Actually, the impossible case, x=y=0. Should be catched above. + else + { + assert(false); + return 0.0; + } + + } + // This can only happen, if x or y is NaN. + else + { + return 0.0; + } +} + +#endif diff --git a/vroni/Include/defs.h b/vroni/Include/defs.h new file mode 100644 index 0000000..49575be --- /dev/null +++ b/vroni/Include/defs.h @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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-172 */ +/* Voice Mail: (+43 662) 8044-6304 */ +/* Snail Mail: Martin Held */ +/* FB Informatik */ +/* Universitaet Salzburg */ +/* A-5020 Salzburg, Austria */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_DEFS_H +#define VRONI_DEFS_H + +#include "mydefs.h" + +#define PROG_NAME "V R O N I" +#define PROG_VERSION "7.6" +#define PROG_YEAR "1999-2023" + +/* */ +/* get the definitions for "exterior applications" */ +/* */ +#include "ext_appl_defs.h" + +/* */ +/* colors for OpenGL drawing */ +/* */ +#define VroniBrown 0 +#define VroniGreen 1 +#define VroniBlue 2 +#define VroniWhite 3 +#define VroniRed 4 +#define VroniCyan 5 +#define VroniYellow 6 +#define VroniOrange 7 +#define VroniMagenta 8 +#define VroniBlack 9 +#define VroniNumColors 10 + + +#define NoColor VroniBlack +#define SupColor VroniWhite +#define PntColor VroniGreen +#define SegColor VroniGreen +#define ArcColor VroniCyan +#define CirColor VroniYellow +#define AlertColor VroniRed +#define CurrColor VroniBlue +#define MICColor VroniYellow +#define VDColor VroniRed +#define GridColor VroniBrown +#define TreeColor VroniBrown +#define VDCurrColor VroniMagenta +#define DTCurrColor VroniOrange +#define SiteCurrColor VroniBlue +#define DTColor VroniWhite +#define OffColor VroniWhite +#define WMATColor VroniBlue + +#endif diff --git a/vroni/Include/elapsed.h b/vroni/Include/elapsed.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vroni/Include/elapsed.h @@ -0,0 +1 @@ + diff --git a/vroni/Include/ext_appl_defs.h b/vroni/Include/ext_appl_defs.h new file mode 100644 index 0000000..7ea69eb --- /dev/null +++ b/vroni/Include/ext_appl_defs.h @@ -0,0 +1,190 @@ +/*****************************************************************************/ +/* */ +/* 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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_EXT_APPL_DEFS_H +#define VRONI_EXT_APPL_DEFS_H + +#include "defs.h" +#include +#include + +/* */ +/* the following data types are used for user-defined entities that are to */ +/* be stored as part of my data structures. you are welcome to redefine them */ +/* according to your needs. however, please note that it is your task to */ +/* make sure that the functions and macros for I/O operations are modified */ +/* accordingly in io_parse.c !! also, you'd need to redefine the constants */ +/* eap_NIL, eas_NIL, ean_NIL, eae_NIL, eam_NIL, and eao_NIL in the file */ +/* ext_appl_defs.c to whatever constant integral value or structure that can */ +/* be used for initializing the exterior application structures. see the */ +/* sample use for eap_... below. */ +/* */ + +typedef std::pair eap_type; /* ext. appl. hook for pnt */ +typedef std::pair eas_type; /* ext. appl. hook for seg and arc */ +typedef int ean_type; /* ext. appl. hook for node */ +typedef int eae_type; /* ext. appl. hook for edge */ +typedef int eam_type; /* ext. appl. hook for wmat */ +typedef int eao_type; /* ext. appl. hook for off_data */ + +/* + * sample user-specific eap data: + * + * typedef struct { + * long id; + * char ch[10]; + * } eap_type; + */ + +extern const eap_type eap_NIL; +extern const eas_type eas_NIL; +extern const ean_type ean_NIL; +extern const eam_type eam_NIL; +extern const eao_type eao_NIL; +extern const eae_type eae_NIL; + + +#define ExtApplFuncNewInput + +#define ExtApplFuncRestart + +#define ExtApplFuncFirstPnts + +#define ExtApplFuncDonePnts + +#define ExtApplFuncFirstSegs + +#define ExtApplFuncDoneSegs + +#define ExtApplFuncDoneSegs + +#define ExtApplFuncDoneArcs + +#define ExtApplFuncFirstArcs + +#define ExtApplFuncDoneVD + +#define ExtApplFuncReset + +#define ExtApplFuncIsoOffset + +#define ExtApplFuncIsoOffsetDone + +#define ExtApplFuncOffsetInit + +#define ExtApplFuncOffsetRepeat + +#define ExtApplFuncOffLoops + +#define ExtApplFuncOffDone + +#define ExtApplFuncOffStart + +#define ExtApplFuncOffSegment + +#define ExtApplFuncOffsetEnd + +#define ExtApplFuncWMATInit + +#define ExtApplFuncWMATLoop + +#define ExtApplFuncWMATComputed + +#define ExtApplFuncWMATDone + +#define ExtApplFuncMICInit + +#define ExtApplFuncMICDone + +#define ExtApplFuncMICNotFound + +#define ExtApplFuncVD_Warning + +#define ExtApplFuncVD_Dbg_Warning + +#define ExtApplFuncVD_IO_Warning + +#define ExtApplFuncVD_Info + +#define ExtApplFuncArgEvalParse + +#define ExtApplFuncArgEvalInit + +#define ExtApplFuncArgEvalDone + +#define ExtApplFuncEvalErrorOption + +#define ExtApplFuncEvalErrorExplain + +#define ExtApplFuncReadOptCoord + +#define ExtApplFuncReadOptNumber + +#define ExtApplFuncReadNumber + +#define ExtApplFuncReadPntData + +#define ExtApplFuncReadSiteData + +#define ExtApplFuncReadVectorData + +#define ExtApplFuncWritePntData + +#define ExtApplIsCorrectSide + +#define ExtApplInsertDummyNode + +#define ExtApplResetGraphicsData + +#define ExtApplInitializeEdgeData + +#define ExtApplInitializeProgram + +#define ExtApplRemoveSeg + +#define ExtApplRemoveArc + +#define ExtApplSetStepSize + +#define ExtApplSegPntIntersection + +#define ExtApplArcPntIntersection + +#define ExtApplSegSegIntersection + +#define ExtApplSegArcIntersection + +#define ExtApplArcArcIntersection + +#define ExtApplHandleSeg + +#define ExtApplHandleArc + +#define ExtApplComputeRestarts + +#define ExtApplAddDummyCorners + +#define ExtApplScanVDEdges + +#define ExtApplFuncVRONI_HandleError + +#endif \ No newline at end of file diff --git a/vroni/Include/ext_appl_inout.h b/vroni/Include/ext_appl_inout.h new file mode 100644 index 0000000..289ac9e --- /dev/null +++ b/vroni/Include/ext_appl_inout.h @@ -0,0 +1,94 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2003--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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_EXT_APPL_INOUT_H +#define VRONI_EXT_APPL_INOUT_H + +#include "types.h" + +class vroniObject; + +#ifndef VRONI_COORD_H +typedef struct { + double x; /* x-coordinate */ + double y; /* y-coordinate */ +} coord; /********** point/vector ******************************/ +#endif + +/* Make sure that double arg is defined, to ensure that external appliations do + not break if they don't include fpkernel.h */ +#ifndef double_arg +#define double_arg double +#endif + + +/*****************************************************************************/ +/* */ +/* The following data structures and macros may be modified at the user's */ +/* discretion. They are only used in API_HandleArrayInput() in */ +/* api_functions.c. */ +/* */ +/*****************************************************************************/ + + +typedef struct { + double x1; /* x-coordinate */ + double y1; /* y-coordinate */ +#ifdef EXT_APPL_PNTS + eap_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif +} in_pnts; /********** point/vector ******************************/ + + +typedef struct { + double x1; /* x-coordinate start */ + double y1; /* y-coordinate start */ + double x2; /* x-coordinate end */ + double y2; /* y-coordinate end */ +#ifdef EXT_APPL_SITES + eas_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif +} in_segs; /********** point/vector ******************************/ + + +typedef struct { + double x1; /* x-coordinate start */ + double y1; /* y-coordinate start */ + double x2; /* x-coordinate end */ + double y2; /* y-coordinate end */ + double x3; /* x-coordinate center */ + double y3; /* y-coordinate center */ + vr_bool attr; /* orientation; true for CCW arcs, false for CW arcs */ +#ifdef EXT_APPL_SITES + eas_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif +} in_arcs; /********** point/vector ******************************/ + + +/* api_functions.c */ + +#include "api_functions.h" + +#endif diff --git a/vroni/Include/ext_appl_vroni_object.h b/vroni/Include/ext_appl_vroni_object.h new file mode 100644 index 0000000..b3103a6 --- /dev/null +++ b/vroni/Include/ext_appl_vroni_object.h @@ -0,0 +1,63 @@ +/*****************************************************************************/ +/* */ +/* 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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_EXT_APPL_VRONI_OBJECT_H +#define VRONI_EXT_APPL_VRONI_OBJECT_H + +#include "vroni_object.h" + + +/* */ +/* VRONI object derived class declaration */ +/* */ +class extApplVroniObject : public vroniObject +{ +public: + + // + // CONSTRUCTOR / DESTRUCTOR + // + extApplVroniObject(); + + virtual ~extApplVroniObject(); + + + // + // EXTRA FUNCTIONS + // + bool EdgeDataNeedInitializing(); + + void InitializeAllEdgeData(); + + bool IsDegenerateEdge(int ie); + + +protected: + + +private: + + +}; + + +#endif diff --git a/vroni/Include/fpkernel.h b/vroni/Include/fpkernel.h new file mode 100644 index 0000000..9586052 --- /dev/null +++ b/vroni/Include/fpkernel.h @@ -0,0 +1,231 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_FP_KERNEL_H +#define VRONI_FP_KERNEL_H + +#ifdef WITH_COREBACKEND +/* Set CORE Level to 4. Otherwise all unsigned long no longer work */ +#define CORE_LEVEL 4 + +#ifdef WITH_CORE_EXPR_WRAPPER +#include +#else +#include +#endif /* WITH_CORE_EXPR_WRAPPER */ + + +#undef double +#ifdef WITH_COREBACKEND_BIGFLOAT +#define double CORE::BigFloat +#else +/* allow double to be used as Expr */ +#define double Expr +#endif + +#define double_arg const double & + +//This is used to indicate that double gets a different meaning! +#define DOUBLE_OVERRIDE + +#include + +#define TO_MDOUBLE(x) (x).doubleValue() + +inline CORE::BigInt cut_comma(const Expr & x) { + CORE::BigInt v = floor(x); + if(v < 0) { + return v + 1; + } else { + return v; + } +} + +#include "coreatan2.h" + +inline int intfloor(const Expr & e) { + return floor(e).intValue(); +} + +inline unsigned int uintceil(const Expr & e) { + return (unsigned)ceil(e).intValue(); +} + +//REAL_TO_INT behaves like (int)(x) +#define REAL_TO_INT(x) cut_comma(x).intValue() +#define REAL_TO_GLINT(x) cut_comma(x).intValue() +#define REAL_TO_FLOAT(x) (x).floatValue() +#define BIGINT_TO_INT(x) (x).intValue() +#define TO_REAL(x) double(x) + +//Definitions for functions undefined in CORE +#define isnan(x) 0 +#define atan2(y,x) atan2local((y),(x)) +#define signbit(x) ((x) < 0 ? 1 : 0) + +#define CORE_EXPR_OPS(name, x) { \ + std::map m; \ + (x).rep()->rekCollectOp(m); \ + for(std::map::iterator it = m.begin(); it != m.end(); ++it) { \ + std::cout << it->second << "\t: " << it->first << std::endl; \ + }} + +#ifdef WITH_CORE_EXPR_WRAPPER +inline void CORE_EXPR_SEQ(std::string name, const Expr & x) { + std::map m; + (x).rep()->rekSequen(m); + for (std::map::iterator it = m.begin(); it != m.end(); ++it) { + std::cout << it->second << std::endl; + } +} + +inline void CORE_EXPR_DEBUG1(std::string name, const Expr & x) { + std::cout << name << " depth: " << (x).rep()->getDepth() << std::endl; + std::cout << name << " elementCount: " << (x).rep()->getElementCount() << std::endl; + CORE_EXPR_SEQ(name, (x)); + std::cout << name << " value: " << (x) << std::endl; +} +#else +inline void CORE_EXPR_SEQ(std::string name, const Expr & x) {} +inline void CORE_EXPR_DEBUG1(std::string name, const Expr & x) {} +#endif + +//IO +#define FP_printf formattedIO::fmc_printf +#define FP_fprintf formattedIO::fmc_fprintf + +inline const double * FP_PRNTARG(const double & x) { return &x; } + +//[sf]scanf methods +#define FP_fscanf formattedIO::cfscanf +#define FP_sscanf formattedIO::csscanf + + +// The second argument is the SHA1sum of "shift\n". This avoids a +// conflict with a shift function in CORE - VRONI uses some +// variables named shift +#define shift a68fe7dac8c32f30ad04d52fab4aa46be1068d82 + +#elif defined(WITH_MPFRBACKEND) + +#include + +#include + +typedef double machine_double; +#undef double + +#ifdef WITH_CORE_EXPR_WRAPPER +#include +#define double Expr +#else +#define double Mpfr_class +#endif /* WITH_CORE_EXPR_WRAPPER */ + +#define double_arg const double & + +//This is used to indicate that double gets a different meaning! +#define DOUBLE_OVERRIDE + + +#define TO_MDOUBLE(x) (x).doubleValue() +#define REAL_TO_INT(x) (x).intValue() +#define REAL_TO_GLINT(x) (x).intValue() +#define REAL_TO_FLOAT(x) (x).floatValue() +#define TO_REAL(x) double(x) + +inline void CORE_EXPR_DEBUG1(std::string , const double & ) {} + +inline long intfloor(const double & e) { + return floor(e).intValue(); +} + +inline unsigned long uintceil(const double & e) { + return ceil(e).intValue(); +} + +//Definitions for functions undefined in CORE +#if WITH_CORE_EXPR_WRAPPER +#define is_nan(x) 0 +#define sign_bit(x) ((x) < 0 ? 1 : 0) +#endif + +//IO +#define FP_printf formattedIO::fmc_printf +#define FP_fprintf formattedIO::fmc_fprintf + +inline const double * FP_PRNTARG(const double & x) { return &x; } + +//[sf]scanf methods +#define FP_fscanf formattedIO::cfscanf +#define FP_sscanf formattedIO::csscanf + + +#else + +#include + +#define TO_MDOUBLE(x) (x) +#define REAL_TO_INT(x) (int)(x) +#define REAL_TO_GLINT(x) (GLint)(x) +#define REAL_TO_FLOAT(x) (float)(x) +#define BIGINT_TO_INT(x) (x) +#define TO_REAL(x) (x) + +#define machine_double double + +#define double_arg double + +inline int intfloor(const double e) { + return (int)(floor(e)); +} + +inline unsigned int uintceil(const double e) { + return (unsigned)ceil(e); +} + +#define CORE_EXPR_DEBUG1(x,y) + +#define is_nan(x) isnan(x) +#define sign_bit(x) signbit(x) + +#ifdef DOUBLE_OVERRIDE + #error "DOUBLE_OVERRIDE should not be defined here!" +#endif + +//IO +#define FP_printf printf +#define FP_fprintf fprintf + +#define FP_PRNTARG(x) (x) + +//[sf]scanf methods +#define FP_fscanf fscanf +#define FP_sscanf sscanf + + + +#endif /* LIB_CORE */ + +#endif /* VRONI_FP_KERNEL_H */ + + diff --git a/vroni/Include/geom.h b/vroni/Include/geom.h new file mode 100644 index 0000000..6118202 --- /dev/null +++ b/vroni/Include/geom.h @@ -0,0 +1,129 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2010-2023 M. Held, S. Huber */ +/* */ +/* 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: Stefan Huber, 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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_GEOM_H +#define VRONI_GEOM_H + +#include "util.h" + + +/** Compute squared distance between two points */ +inline double vroniObject::PntPntDistSq(coord pi, coord pj) +{ + const double x = pi.x - pj.x; + const double y = pi.y - pj.y; + return x*x + y*y; +} + +/** Compute distance between two points */ +inline double vroniObject::PntPntDist(coord pi, coord pj) +{ + const double x = pi.x - pj.x; + const double y = pi.y - pj.y; + return sqrt(x*x + y*y); +} + +/** Compute mid point on the line (pi,pj) */ +inline coord vroniObject::MidPoint(coord pi, coord pj) +{ + coord q; + q.x = (pi.x + pj.x) / 2.0; + q.y = (pi.y + pj.y) / 2.0; + return q; +} + +/** Compute centroid point of the triangle (pi,pj,pk) */ +inline coord vroniObject::Centroid(coord pi, coord pj, coord pk) +{ + coord q; + q.x = (pi.x + pj.x + pk.x)/3.0; + q.y = (pi.y + pj.y + pk.y)/3.0; + return q; +} + +/** Build linar combination of vectors p and r by parameter t */ +inline coord vroniObject::LinearComb(const coord & p, const coord & r, + double_arg t) +{ + coord q; + q.x = p.x + t*(r.x-p.x); + q.y = p.y + t*(r.y-p.y); + return q; +} + +/** Get the point q = p + t*v */ +inline coord vroniObject::RayPnt(const coord & p, const coord & v, + double_arg t) +{ + coord q; + q.x = p.x + t*v.x; + q.y = p.y + t*v.y; + return q; +} + +/** Compute (signed) distance of point p to circle (c,r). Positive + * values indicate that p is outside the circle (c,r). */ +inline double vroniObject::PntCircleDist(const coord & c, double_arg r, + const coord & p) +{ + return PntPntDist(p, c) - r; +} + +/** Compute absolute distance of point p tor circle (c,r) */ +inline double vroniObject::AbsPntCircleDist(const coord & c, double_arg r, + const coord & p) +{ + return Abs(PntCircleDist(c, r, p)); +} + +/** Test if point p is on circle (c,r) */ +inline int vroniObject::IsPntOnCircle(const coord & c, double_arg r, const coord & p) +{ + return eq(PntCircleDist(c,r,p), ZERO); +} + + + +/** Compute the signed distance of the point p to the line given by + * the equation a*x + b*y + c = 0. A positive result means that + * p lies in the positive half-plane defined by the line. */ +inline double vroniObject::PntLineDist(double_arg a, double_arg b, double_arg c, const coord & p) +{ + return a*p.x + b*p.y + c; +} + + +/** Compute the absolute distance of the point p to the line given by + * the equation a*x + b*y + c = 0 */ +inline double vroniObject::AbsPntLineDist(double_arg a, double_arg b, double_arg c, const coord & p) +{ + return Abs( PntLineDist(a, b, c, p)); +} + + +inline vr_bool vroniObject::IsBetweenVoronoiNodes(int e, const coord & p, double eps) +{ + return (NodeEdgeClassificator(e, p, eps) == 0.0); +} + +#endif + diff --git a/vroni/Include/header.h b/vroni/Include/header.h new file mode 100644 index 0000000..1de4e17 --- /dev/null +++ b/vroni/Include/header.h @@ -0,0 +1,27 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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-172 */ +/* Voice Mail: (+43 662) 8044-6304 */ +/* Snail Mail: Martin Held */ +/* FB Informatik */ +/* Universitaet Salzburg */ +/* A-5020 Salzburg, Austria */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_HEADER_H +#define VRONI_HEADER_H + + +#endif diff --git a/vroni/Include/intersections.h b/vroni/Include/intersections.h new file mode 100644 index 0000000..e797fb0 --- /dev/null +++ b/vroni/Include/intersections.h @@ -0,0 +1,88 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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.c". */ +/* */ +/*****************************************************************************/ +/* */ +/* 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 */ +/* Universitaet Salzburg */ +/* FB Informatik */ +/* A-5020 Salzburg, Austria */ +/* */ +/*****************************************************************************/ + + + +#ifndef VRONI_INTERSECTIONS_H +#define VRONI_INTERSECTIONS_H + +#include + +//#ifdef VRONI_INFO +#ifdef VRONI_DBG_WARN +#define IntWarning(S1, I1, S2, I2) \ +{\ + if (verbose) { \ + printf("\nwarning in ComputeVD() - the %s %d and the %s %d intersect!\n",\ + S1, I1, S2, I2); \ + if (strcmp(S1, "pnt") == 0) { \ + printf("pnt %d: (%20.16f,%20.16f)\n", I1, \ + UnscaleX(pnts[I1].p.x), \ + UnscaleY(pnts[I1].p.y)); \ + } \ + else if (strcmp(S1, "seg") == 0) { \ + printf("seg %d: (%20.16f,%20.16f) to (%20.16f,%20.16f)\n", I1, \ + UnscaleX(pnts[segs[I1].i1].p.x), \ + UnscaleY(pnts[segs[I1].i1].p.y), \ + UnscaleX(pnts[segs[I1].i2].p.x), \ + UnscaleY(pnts[segs[I1].i2].p.y)); \ + } \ + else if (strcmp(S1, "arc") == 0) { \ + printf("arc %d: (%20.16f,%20.16f) to (%20.16f,%20.16f) centered at (%20.16f,%20.16f)\n", I1, \ + UnscaleX(pnts[arcs[I1].i1].p.x), \ + UnscaleY(pnts[arcs[I1].i1].p.y), \ + UnscaleX(pnts[arcs[I1].i2].p.x), \ + UnscaleY(pnts[arcs[I1].i2].p.y), \ + UnscaleX(arcs[I1].c.x), \ + UnscaleY(arcs[I1].c.y)); \ + } \ + if (strcmp(S2, "pnt") == 0) { \ + printf("pnt %d: (%20.16f,%20.16f)\n", I2, \ + UnscaleX(pnts[I2].p.x), \ + UnscaleY(pnts[I2].p.y)); \ + } \ + else if (strcmp(S2, "seg") == 0) { \ + printf("seg %d: (%20.16f,%20.16f) to (%20.16f,%20.16f)\n", I2, \ + UnscaleX(pnts[segs[I2].i1].p.x), \ + UnscaleY(pnts[segs[I2].i1].p.y), \ + UnscaleX(pnts[segs[I2].i2].p.x), \ + UnscaleY(pnts[segs[I2].i2].p.y)); \ + } \ + else if (strcmp(S2, "arc") == 0) { \ + printf("arc %d: (%20.16f,%20.16f) to (%20.16f,%20.16f) centered at (%20.16f,%20.16f)\n", I2, \ + UnscaleX(pnts[arcs[I2].i1].p.x), \ + UnscaleY(pnts[arcs[I2].i1].p.y), \ + UnscaleX(pnts[arcs[I2].i2].p.x), \ + UnscaleY(pnts[arcs[I2].i2].p.y), \ + UnscaleX(arcs[I2].c.x), \ + UnscaleY(arcs[I2].c.y)); \ + } \ + } \ +} +#else +#define IntWarning(S1, I1, S2, I2) {} +#endif + + + +#endif + diff --git a/vroni/Include/io_dxf.h b/vroni/Include/io_dxf.h new file mode 100644 index 0000000..639664e --- /dev/null +++ b/vroni/Include/io_dxf.h @@ -0,0 +1,40 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2003--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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_IO_DXF_H +#define VRONI_IO_DXF_H + +/* */ +/* I'm not sure whether those are indeed the colors used in DXF files. */ +/* Unfortunately, I do not seem to be able to get my hands on a decent */ +/* specification of DXF... */ +/* */ +#define DXF_NO_COLOR -1 +#define DXF_RED 1 +#define DXF_YELLOW 2 +#define DXF_GREEN 2 +#define DXF_CYAN 4 +#define DXF_BLUE 5 +#define DXF_MAGENTA 6 +#define DXF_WHITE 7 + +#endif diff --git a/vroni/Include/ipe_io.h b/vroni/Include/ipe_io.h new file mode 100644 index 0000000..488f0c2 --- /dev/null +++ b/vroni/Include/ipe_io.h @@ -0,0 +1,104 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1996-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". */ +/* */ +/*****************************************************************************/ +/* */ +/* Purpose: This is an interface to Ipe. */ +/* */ +/* Acknowledgements: based on fragments written by Ch. Spielberger. */ +/* */ +/* E-Mail: held@cs.sbg.ac.at */ +/* Fax Mail: (+43 662) 8044-172 */ +/* Voice Mail: (+43 662) 6044-6304 */ +/* Snail Mail: Martin Held */ +/* Universitaet Salzburg */ +/* FB Informatik */ +/* A-5020 Salzburg, Austria */ +/* */ +/*****************************************************************************/ +#ifndef IPE7_IO_H +#define IPE7_IO_H + +#include "types.h" + + + +#define XMIN 0.0 +#define XMAX 452.0 +#define YMIN 0.0 +#define YMAX 568.0 + +#define LAYER0 "boundary" +#define LAYER1 "voronoi" +#define LAYER2 "MAT" +#define LAYER3 "delaunay" +#define LAYER4 "offset" +#define LAYER5 "MIC" +#define LAYER6 "bd_vertices" +#define LAYER7 "vd_nodes" + +#define COLOR0 "seagreen" +#define COLOR1 "red" +#define COLOR2 "black" +#define COLOR3 "blue" +#define COLOR4 "lightgray" +#define COLOR5 "yellow" +#define COLOR6 "black" +#define COLOR7 "violet" + +#define PEN0 "ultrafat" +#define PEN1 "normal" +#define PEN2 "fat" +#define PEN3 "normal" +#define PEN4 "normal" +#define PEN5 "normal" +#define PEN6 "normal" +#define PEN7 "normal" + + +FILE *InitIpeFile(char *filename); + +FILE *InitIpe(char *filename, double_arg xl, double_arg xr, double_arg yl, double_arg yr); + +void CloseIpeFile(FILE *ipe_file); + +void WriteBeginPath(FILE *ipe_file, double x1, double y1); + +void WriteBeginGroup(FILE *ipe_file, short int layer); + +void WriteEndGroup(FILE *ipe_file); + + +void WriteArcCCW(FILE *ipe_file, double_arg xc, double_arg yc, double_arg r, + double_arg alpha, double_arg beta); + +void WriteArcCW(FILE *ipe_file, double_arg xc, double_arg yc, double_arg r, + double_arg alpha, double_arg beta); + +void WriteMark(FILE *ipe_file, int type, int size, double_arg x, double_arg y); + +void SetIpeDimensions(double_arg xmin, double_arg xmax, double_arg ymin, double_arg ymax); + +void SetWorldDimensions(double_arg xmin, double_arg xmax, double_arg ymin, double_arg ymax); + +void SetScaleFactor(void); + +void InitIpeDimensions(double_arg xmin, double_arg ymin, double_arg xmax, double_arg ymax, + double_arg ixmin, double_arg iymin, double_arg ixmax, double_arg iymax); + +double scaleX(double x); +double scaleY(double y); + +void WriteLineSegment(FILE *ipe_file, + double x1, double y1, double x2, double y2); + +void WriteCircularArc(FILE *ipe_file, double_arg xc, double_arg yc, + double_arg x1, double_arg y1, double_arg x2, double_arg y2, vr_bool ccw); + + +#endif diff --git a/vroni/Include/mydefs.h b/vroni/Include/mydefs.h new file mode 100644 index 0000000..d652c96 --- /dev/null +++ b/vroni/Include/mydefs.h @@ -0,0 +1,13 @@ +#pragma once + +// preprocessor definitions da usare per compilare correttamente + +#define NO_CPUTIME +#define RANDOM +#define RAND +#define HAVE_BOOL +#define GENUINE_ARCS +#define MIC +#define MAT +#define EXT_APPL_PNTS +#define EXT_APPL_SITES \ No newline at end of file diff --git a/vroni/Include/numerics.h b/vroni/Include/numerics.h new file mode 100644 index 0000000..2bc697f --- /dev/null +++ b/vroni/Include/numerics.h @@ -0,0 +1,205 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_NUMERICS_H +#define VRONI_NUMERICS_H + + +#define Det2D(u, v, w) \ + (((u).x - (v).x) * ((v).y - (w).y) + ((v).y - (u).y) * ((v).x - (w).x)) + + +/* */ +/* this macro solves the equation p + s * q = u + t * v */ +/* for the parameter s, with p and u being points and q and v */ +/* being direction vectors of the lines through p and u. */ +/* if the equation cannot be solved (since the two lines are parallel) then */ +/* exists = 0; if the solution is not unique then exists = 2; and */ +/* exists = 1, otherwise. also, w := p + xy[0] * q. */ +/* */ +/* A[2][2], B[2], xy[2], I0, I1, J0, J1 are used internally within this */ +/* macro. */ +/* */ +#define LineLineIntersection(A, B, xy, I0, J0, I1, J1, p, q, u, v, w, exists) \ +{\ + A[0][0] = (q).x; \ + A[1][0] = (q).y; \ + A[0][1] = - (v).x; \ + A[1][1] = - (v).y; \ + B[0] = (u).x - (p).x; \ + B[1] = (u).y - (p).y; \ + LinearEqnSolver_2x2(A, B, xy, exists, I0, J0, I1, J1); \ + if (exists == 1) { \ + (w).x = (p).x + xy[0] * (q).x; \ + (w).y = (p).y + xy[0] * (q).y; \ + }\ +} + + + +/* */ +/* P ... query point */ +/* U ... start point of segment */ +/* A, B, C ... normalized line coefficients, where (B,-A) is the unit */ +/* direction vector of the line segment */ +/* L ... length of the line segment */ +/* */ + +#define IsInSegConeStrict(U, P, A, B, L) \ +(((((P).x - (U).x) * (B) - ((P).y - (U).y) * (A) < (L)) ? ((((P).x - (U).x) * (B) - ((P).y - (U).y) * (A) <= 0.0) ? -1 : 0) : 1)) + + +#define IsInSegCone(U, P, A, B, L) \ +(((((P).x - (U).x) * (B) - ((P).y - (U).y) * (A) <= ((L) + ZERO)) ? ((((P).x - (U).x) * (B) - ((P).y - (U).y) * (A) < -ZERO) ? -1 : 0) : 1)) + + +#define IsInSegConeZero(U, P, A, B, L, eps) \ +(((((P).x - (U).x) * (B) - ((P).y - (U).y) * (A) <= ((L) + (eps))) ? ((((P).x - (U).x) * (B) - ((P).y - (U).y) * (A) < -(eps)) ? -1 : 0) : 1)) + +#define PntSegDist(U, P, A, B, C, L, eps) \ +((IsInSegConeZero(U, P, A, B, L, eps) == 0) ? \ + (PntLineDist(A, B, C, P)) : LARGE) + + +#define AbsPntSegDist(U, P, A, B, C, L, eps) \ +((IsInSegConeZero(U, P, A, B, L, eps) == 0) ? \ + (AbsPntLineDist(A, B, C, P)) : LARGE) + + +#define xParabola(A, a, b, sign, dist, t, k1, k2, r, x) \ +{ \ + if (r * r + 2.0 * t * (r * k1 - dist * k2) - dist * dist <= 0.0) { \ + (x) = A - a * t * k2; \ + } \ + else { \ + (x) = A - a * t * k2 + sign * b * sqrt(r * r + 2.0 * t * (r * k1 - dist * k2) - dist * dist); \ + } \ +} + +#define yParabola(B, a, b, sign, dist, t, k1, k2, r, y) \ +{ \ + if (r * r + 2.0 * t * (r * k1 - dist * k2) - dist * dist <= 0.0) { \ + (y) = B - b * t * k2; \ + } \ + else { \ + (y) = B - b * t * k2 - sign * a * sqrt(r * r + 2.0 * t * (r * k1 - dist * k2) - dist * dist); \ + } \ +} + +#define xHyperEll(A, C, sign, dist, dy, t, k1, k2, r1, r2, r1t, r2t, ht, x) \ +{ \ + r1t = r1 + k1 * t; \ + r2t = r2 + k2 * t; \ + ht = (r2t * r2t - r1t * r1t - dist * dist) / (2.0 * dist); \ + if (r1t * r1t - ht * ht <= 0.0) { \ + (x) = A - C * t; \ + } \ + else { \ + (x) = A - C * t + sign * dy * sqrt(r1t * r1t - ht * ht); \ + } \ +} + + +#define yHyperEll(B, D, sign, dist, dx, t, k1, k2, r1, r2, r1t, r2t, ht, y) \ +{ \ + r1t = r1 + k1 * t; \ + r2t = r2 + k2 * t; \ + ht = (r2t * r2t - r1t * r1t - dist * dist) / (2.0 * dist); \ + if (r1t * r1t - ht * ht <= 0.0) { \ + (y) = B - D * t; \ + } \ + else { \ + (y) = B - D * t - sign * dx * sqrt(r1t * r1t - ht * ht); \ + } \ +} + +/* */ +/* A, B, C ... normalized coefficients of the equation of the arc's chord */ +/* such that the arc's center is to the left of the chord */ +/* P ... query point */ +/* */ +/* note: we assume that the arc is oriented CCW, and that a point-on-circle */ +/* test has been performed! */ +/* */ +#define IsOnArc(A, B, C, P) \ + (PntLineDist(A, B, C, P) <= ZERO) + + +#define IsOnArcStrict(A, B, C, P) \ + (PntLineDist(A, B, C, P) < 0.0) + + +#define IsOnArcZero(A, B, C, P, eps) \ + (PntLineDist(A, B, C, P) <= (eps)) + + +/* */ +/* VS ... unit outwards normal vector of arc at start point */ +/* VE ... unit outwards normal vector of arc at end point */ +/* CP ... vector from arc's center to query point */ +/* */ +/* note: (1) we assume that the arc is oriented CCW, and */ +/* that it spans less than 180 degrees! */ +/* (2) if a point is inside a circle then its distance to the circle */ +/* is negative. */ +/* */ +#define IsInArcCone(VS, VE, CP) \ + ((((VS).x * (CP).y - (VS).y * (CP).x) >= -ZERO) ? \ + ((((VE).y * (CP).x - (VE).x * (CP).y) >= -ZERO) ? 0 : -1) : 1) + + +#define IsInArcConeZero(VS, VE, CP, eps) \ + ((((VS).x * (CP).y - (VS).y * (CP).x) >= -(eps)) ? \ + ((((VE).y * (CP).x - (VE).x * (CP).y) >= -(eps)) ? 0 : -1) : 1) + + +#define IsInArcConeStrict(VS, VE, CP) \ + ((((VS).x * (CP).y - (VS).y * (CP).x) > 0.0) ? \ + ((((VE).y * (CP).x - (VE).x * (CP).y) > 0.0) ? 0 : -1) : 1) + + + + + + +#define PntArcDist(VS, VE, CP, R, eps) \ + ((((VS).x * (CP).y - (VS).y * (CP).x) >= -(eps)) ? \ + ((((VE).y * (CP).x - (VE).x * (CP).y) >= -(eps)) ? (VecLen(CP) - R) \ + : LARGE) : LARGE) + + +//#define AbsPntArcDist(VS, VE, CP, R, Z) \ +// ((((VS).x * (CP).y - (VS).y * (CP).x) >= -(Z)) ? \ +// ((((VE).y * (CP).x - (VE).x * (CP).y) >= -(Z)) ? \ +// (numerics_h_local = VecLen(CP) - R, \ +// ((numerics_h_local < 0.0) ? -numerics_h_local : numerics_h_local)) : \ +// LARGE) : LARGE) + + +#define AbsPntArcDist(VS, VE, CP, R, Z) \ + ((((VS).x * (CP).y - (VS).y * (CP).x) >= -(Z)) ? \ + ((((VE).y * (CP).x - (VE).x * (CP).y) >= -(Z)) ? \ + (((VecLen(CP) - R < 0.0) ? -(VecLen(CP) - R) : VecLen(CP) - R)) : \ + LARGE) : LARGE) + +#endif + diff --git a/vroni/Include/offset.h b/vroni/Include/offset.h new file mode 100644 index 0000000..24274da --- /dev/null +++ b/vroni/Include/offset.h @@ -0,0 +1,218 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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". */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_OFFSET_H +#define VRONI_OFFSET_H + +#include "defs.h" + +/* */ +/* the offset curves are stored as closed loops in the array offset_list[]. */ +/* the individual offset segments are stored in the array offset_data[]. */ +/* the i-th offset curve contains the offset segments whose indices range */ +/* from offset_list[i].start to offset_list[i].end. the actual offset */ +/* distance of the i-th offset curve is stored in offset_list[i].offset. */ +/* there is a total of num_offset_list many offset curves. */ +/* */ +struct off_list { + int start; /* index of first segment of this offset curve . */ + int end; /* index of last segment of this offset curve. */ + double offset; /* boundary clearance for this offset curve. */ + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline off_list() {} +}; /* data for one offset curve. */ + +struct off_data { + int site; /* index of corresponding site (contour segment). */ + t_site type; /* type of corresponding contour segment: PNT, LINE, */ + /* or CCW, CW. */ + coord p; /* coordinates of start point of offset segment */ +#ifdef EXT_APPL_OFF + eao_type ext_appl; +#endif + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline off_data() {} +}; /* data for one offset segment */ + +off_list* GetOffsetList(int i); +off_data* GetOffsetData(int i); + +#define SetEdgeFlagNew(I, F) \ +{\ + assert(InEdgeFlagList(I)); \ + edge_flags[I].e_new = F;\ +} + + +#define SetEdgeFlagDeg(I, F) \ +{\ + assert(InEdgeFlagList(I)); \ + edge_flags[I].deg = F;\ +} + + +#define SetEdgeDataInit(I, F) \ +{\ + assert(InEdgeDataList(I)); \ + edge_data[I].init = F;\ +} + + +#define GetEdgeFlagNew(I) (assert(InEdgeFlagList(I)), edge_flags[I].e_new) + + +#define GetEdgeFlagDeg(I) (assert(InEdgeFlagList(I)), edge_flags[I].deg) + + +#define GetEdgeDataInit(I) (assert(InEdgeDataList(I)), edge_data[I].init) + + +#define AdvanceActiveEdge(I, J, delete) \ +{\ + if (delete) { \ + assert(InActiveEdgeList(J)); \ + --num_active_edges; \ + if ((num_active_edges >= 0) && (J < num_active_edges)) { \ + I = active_edges[J] = active_edges[num_active_edges]; \ + } \ + else { \ + I = NIL; \ + } \ + } \ + else { \ + ++J; \ + if (J < num_active_edges) { \ + I = active_edges[J]; \ + } \ + else { \ + I = NIL; \ + } \ + } \ +} + +// define from offset.cc + +#define OFFS_BLOCK_SIZE 32768 +#define OFFS_HALF_BLOCK_SIZE 1024 + + +#define NewOffsetCurve \ +{ \ + cur_offset_list = num_offset_list; \ + if (cur_offset_list >= max_num_offset_list) { \ + max_num_offset_list += OFFS_HALF_BLOCK_SIZE; \ + gentlyResizeSTLVector(offset_list, max_num_offset_list, "offset:offset_list"); \ + } \ + ++num_offset_list; \ + \ + offset_list[cur_offset_list].start = num_offset_data; \ + offset_list[cur_offset_list].offset = UnscaleV(t); \ + \ +} + + +#define SetOffsetNumber \ +{\ + offset_list[cur_offset_list].end = num_offset_data - 1; \ +} + + +#define GetCurrentOffsetSegNumber num_offset_data + + +#ifdef EXT_APPL_OFF +#define StoreOffsetData(S, T, P) \ +{ \ + if (num_offset_data >= max_num_offset_data) { \ + max_num_offset_data += OFFS_BLOCK_SIZE; \ + gentlyResizeSTLVector(offset_data, max_num_offset_data, "offset:offset_data"); \ + } \ + offset_data[num_offset_data].site = S; \ + offset_data[num_offset_data].type = T; \ + offset_data[num_offset_data].p = P; \ + offset_data[num_offset_data].ext_appl = eao_NIL; \ + \ + ++num_offset_data; \ +} +#else +#define StoreOffsetData(S, T, P) \ +{ \ + if (num_offset_data >= max_num_offset_data) { \ + max_num_offset_data += OFFS_BLOCK_SIZE; \ + gentlyResizeSTLVector(offset_data, max_num_offset_data, "offset:offset_data"); \ + } \ + offset_data[num_offset_data].site = S; \ + offset_data[num_offset_data].type = T; \ + offset_data[num_offset_data].p = P; \ + \ + ++num_offset_data; \ +} +#endif + + + +#ifdef EXT_APPL_OFF +#define GetExtApplOffset(O) \ +(\ + assert(InOffsetData(O)), \ + offset_data[O].ext_appl) + + +#define SetExtApplOffset(O, X) \ +{\ + assert(InOffsetData(O)), \ + offset_data[O].ext_appl = X; \ +} +#endif + + +#define GetOffsetListStart(i) \ +(\ + assert(InOffsetList(i)), \ + offset_list[i].start) + + +#define GetOffsetListEnd(i) \ +(\ + assert(InOffsetList(i)), \ + offset_list[i].end) + + +#define GetOffsetEleType(j) \ +(\ + assert(InOffsetData(j)), \ + offset_data[j].type) + + +#define GetOffsetEleSite(j) \ +(\ + assert(InOffsetData(j)), \ + offset_data[j].site) + + +#define GetOffsetXCoord(j) \ +(\ + assert(InOffsetData(j)), \ + offset_data[j].p.x) + + +#define GetOffsetYCoord(j) \ +(\ + assert(InOffsetData(j)), \ + offset_data[j].p.y) + + +#define GetOffsetPntCoords(j) \ +(\ + assert(InOffsetData(j)), \ + offset_data[j].p) + +#endif + diff --git a/vroni/Include/random.h b/vroni/Include/random.h new file mode 100644 index 0000000..f6fe9ec --- /dev/null +++ b/vroni/Include/random.h @@ -0,0 +1,70 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_RANDOM_H +#define VRONI_RANDOM_H + +#include "defs.h" + +#ifndef RAND + +#define RND_MAX 2147483647 + +#define UniformRandom(x) \ +{\ + x = ((double) random()) / RND_MAX; } + +#define RandomInteger(N) \ + (\ + assert(N > 0), \ + random() % N) + +#define InitRandom(seed) \ +{\ + srandom(seed); } + +#else + +#ifdef RAND_MAX +#define RND_MAX RAND_MAX +#else +#define RND_MAX 32767 +#endif + +#define UniformRandom(x) \ +{\ + x = ((double) rand()) / RND_MAX; \ +} + +#define RandomInteger(N) \ + (\ + assert(N > 0), \ + rand() % N) + +#define InitRandom(seed) \ +{\ + srand(seed); } + +#endif + + +#endif diff --git a/vroni/Include/roots.h b/vroni/Include/roots.h new file mode 100644 index 0000000..f370e91 --- /dev/null +++ b/vroni/Include/roots.h @@ -0,0 +1,273 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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". */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_ROOTS_H +#define VRONI_ROOTS_H + +int Roots3(double lead, double a, double b, double c, double roots[]); +int Roots4(double lead, double a, double b, double c, double d, + double roots[]); + +#define ROOTS_ZERO 1.0e-50 +#define ROOTS_ZERO2 1.0e-100 +//#define ROOTS_ZERO 1.0e-14 +//#define ROOTS_ZERO2 1.0e-28 +#define DISCR_ZERO 1.0e-8 +#define ROOT_SMALL 0.125 /* ROOT_SMALL = 1/8 >> ZERO */ +#define ROOT_INV_SMALL 8.0 /* ROOT_INV_SMALL = 1/ROOT_SMALL */ + +/* */ +/* This macro solves the following second-degree polynomial equation: */ +/* */ +/* a * x^2 + b * x + c = 0. */ +/* */ +/* The roots are stored in roots[0] and roots[1]. Note that only real */ +/* roots are sought. The number of real roots found is stored in num_roots. */ +/* */ +#define Roots2abc(a, b, c, roots, num_roots) \ +{ \ + while (eq(a, ROOT_SMALL) && eq(b, ROOT_SMALL) && eq(c, ROOT_SMALL) && ((a != 0.0) || (b != 0.0) || (c != 0.0))) { \ + a *= 2.0; \ + b *= 2.0; \ + c *= 2.0; \ + } \ + while ((Abs(a) > ROOT_INV_SMALL) && (Abs(b) > ROOT_INV_SMALL) && (Abs(c) > ROOT_INV_SMALL)) { \ + a /= 2.0; \ + b /= 2.0; \ + c /= 2.0; \ + } \ + if (eq(a, ROOTS_ZERO)) { \ + if (eq(b, ROOTS_ZERO)) { \ + if (eq(c, ROOTS_ZERO)) { \ + num_roots = -1; \ + } \ + else { \ + num_roots = 0; \ + } \ + } \ + else { \ + roots[0] = - c / b; \ + num_roots = 1; \ + } \ + } \ + else { \ + basic_h_local_delta = b * b - 4 * a * c; \ + if (basic_h_local_delta > 0.0) { \ + if (b > 0) { \ + basic_h_local = - 0.5 * (b + sqrt(basic_h_local_delta)); \ + } \ + else { \ + basic_h_local = - 0.5 * (b - sqrt(basic_h_local_delta)); \ + } \ + if (eq(basic_h_local, ROOTS_ZERO)) { \ + roots[0] = basic_h_local / a; \ + num_roots = 1; \ + } \ + else { \ + roots[0] = basic_h_local / a; \ + roots[1] = c / basic_h_local; \ + num_roots = 2; \ + } \ + } \ + else if (eq(basic_h_local_delta, DISCR_ZERO)) { \ + roots[0] = - b / (2.0 * a); \ + num_roots = 1; \ + } \ + else { \ + num_roots = 0; \ + } \ + } \ +} + + + + +/* */ +/* This macro solves the following second-degree polynomial equation: */ +/* */ +/* x^2 + p * x + q = 0. */ +/* */ +/* The roots are stored in roots[0] and roots[1]. Note that only real */ +/* roots are sought. The number of real roots found is stored in num_roots. */ +/* */ +#define Roots2pq(p, q, roots, num_roots) \ +{ \ + basic_h_local_delta = p * p - 4 * q; \ + if (basic_h_local_delta > 0.0) { \ + if (p > 0) { \ + basic_h_local = - 0.5 * (p + sqrt(basic_h_local_delta)); \ + } \ + else { \ + basic_h_local = - 0.5 * (p - sqrt(basic_h_local_delta)); \ + } \ + if (eq(basic_h_local, ROOTS_ZERO)) { \ + roots[0] = basic_h_local; \ + num_roots = 1; \ + } \ + else { \ + roots[0] = basic_h_local; \ + roots[1] = q / basic_h_local; \ + num_roots = 2; \ + } \ + } \ + else if (eq(basic_h_local_delta, ROOTS_ZERO2)) { \ + roots[0] = - 0.5 * p; \ + num_roots = 1; \ + } \ + else { \ + num_roots = 0; \ + } \ +} + + + + +/* */ +/* This macro solves the following 2x2 linear system: */ +/* */ +/* A[0][0] * x + A[0][1] * y = B[0] */ +/* A[1][1] * x + A[1][1] * y = B[1] */ +/* */ +/* If a unique solution exists, then exists := 1, and the solution is stored */ +/* in xy[2]. If the solution is not unique, then exists := 2, and a solution */ +/* is stored in xy[2]. Otherwise, exists := 0. */ +/* */ +/* i, j, I, J are dummy integers needed within the macro. */ +/* */ +#define LinearEqnSolver_2x2(A, B, xy, exists, i, j, I, J) \ +{ \ + /* */ \ + /* find a column with a non-zero element */ \ + /* */ \ + exists = 0; \ + if (!eq((A)[0][0], ROOTS_ZERO) || !eq((A)[1][0], ROOTS_ZERO)) { \ + I = 0; \ + J = 1; \ + } \ + else if (!eq((A)[0][1], ROOTS_ZERO) || !eq((A)[1][1], ROOTS_ZERO)) { \ + I = 1; \ + J = 0; \ + } \ + else { \ + if (eq((B)[0], ROOTS_ZERO) && eq((B)[1], ROOTS_ZERO)) { \ + (xy)[0] = (xy)[1] = 0.0; \ + (exists) = 2; \ + } \ + I = J = 0; \ + } \ + \ + /* */ \ + /* determine i s.t. Abs(A[i][I]) is maximum. */ \ + /* */ \ + if ((I > 0) || (J > 0)) { \ + if (Abs((A)[0][I]) > Abs((A)[1][I])) { \ + i = 0; \ + j = 1; \ + } \ + else { \ + i = 1; \ + j = 0; \ + } \ + \ + basic_h_local_quot = (A)[j][I] / (A)[i][I]; \ + basic_h_local_delta = (A)[j][J] - basic_h_local_quot * (A)[i][J]; \ + if (!eq(basic_h_local_delta, ROOTS_ZERO)) { \ + (xy)[J] = ((B)[j] - basic_h_local_quot * (B)[i]) / basic_h_local_delta; \ + (xy)[I] = ((B)[i] - (xy)[J] * (A)[i][J]) / (A)[i][I]; \ + (exists) = 1; \ + } \ + else { \ + basic_h_local_delta = (B)[j] - basic_h_local_quot * (B)[i]; \ + if (eq(basic_h_local_delta, ROOTS_ZERO)) { \ + (xy)[J] = 0.0; \ + (xy)[I] = (B)[i] / (A)[i][I]; \ + (exists) = 2; \ + } \ + else { \ + (exists) = 0; \ + } \ + } \ + } \ +} + + + + +/* */ +/* This macro solves the following 2x2 linear system: */ +/* */ +/* A[0][0] * x + A[0][1] * y = B[0] */ +/* A[1][1] * x + A[1][1] * y = B[1] */ +/* */ +/* If a unique solution exists, then exists := 1, and the solution is stored */ +/* in xy[2]. If the solution is not unique, then exists := 2, and a solution */ +/* is stored in xy[2]. Otherwise, exists := 0. */ +/* */ +/* i, j, I, J are dummy integers needed within the macro. */ +/* */ +#define LinearEqnSolver_2x2_Zero(A, B, xy, exists, i, j, I, J) \ +{ \ + /* */ \ + /* find a column with a non-zero element */ \ + /* */ \ + exists = 0; \ + if (!eq((A)[0][0], ROOTS_ZERO) || !eq((A)[1][0], ROOTS_ZERO)) { \ + I = 0; \ + J = 1; \ + } \ + else if (!eq((A)[0][1], ROOTS_ZERO) || !eq((A)[1][1], ROOTS_ZERO)) { \ + I = 1; \ + J = 0; \ + } \ + else { \ + if (eq((B)[0], ROOTS_ZERO) && eq((B)[1], ROOTS_ZERO)) { \ + (xy)[0] = (xy)[1] = 0.0; \ + (exists) = 2; \ + } \ + I = J = 0; \ + } \ + \ + /* */ \ + /* determine i s.t. Abs(A[i][I]) is maximum. */ \ + /* */ \ + if ((I > 0) || (J > 0)) { \ + if (Abs((A)[0][I]) > Abs((A)[1][I])) { \ + i = 0; \ + j = 1; \ + } \ + else { \ + i = 1; \ + j = 0; \ + } \ + \ + basic_h_local_quot = (A)[j][I] / (A)[i][I]; \ + basic_h_local_delta = (A)[j][J] - basic_h_local_quot * (A)[i][J]; \ + if (!eq(basic_h_local_delta, ROOTS_ZERO)) { \ + (xy)[J] = ((B)[j] - basic_h_local_quot * (B)[i]) / basic_h_local_delta; \ + (xy)[I] = ((B)[i] - (xy)[J] * (A)[i][J]) / (A)[i][I]; \ + (exists) = 1; \ + } \ + else { \ + basic_h_local_delta = (B)[j] - basic_h_local_quot * (B)[i]; \ + if (eq(basic_h_local_delta, ROOTS_ZERO)) { \ + (xy)[J] = 0.0; \ + (xy)[I] = (B)[i] / (A)[i][I]; \ + (exists) = 2; \ + } \ + else { \ + (exists) = 0; \ + } \ + } \ + } \ +} + + + +#endif diff --git a/vroni/Include/stack.h b/vroni/Include/stack.h new file mode 100644 index 0000000..053d1bc --- /dev/null +++ b/vroni/Include/stack.h @@ -0,0 +1,53 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2000-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-172 */ +/* Voice Mail: (+43 662) 8044-6304 */ +/* Snail Mail: Martin Held */ +/* FB Informatik */ +/* Universitaet Salzburg */ +/* A-5020 Salzburg, Austria */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_STACK_H +#define VRONI_STACK_H + +#define Push(data) \ +{\ + ++num_stack; \ + if (num_stack >= max_num_stack) { \ + max_num_stack += STACK_INCR; \ + stack = (STACK_TYPE*) ReallocateArray(stack, max_num_stack, sizeof(STACK_TYPE), STACK_STRING); \ + } \ + stack[num_stack] = data; \ +} + + +#define Pop(data) \ +{\ + assert(num_stack > 0); \ + data = stack[num_stack]; \ + --num_stack; \ +} + + +#define GetStackSize (num_stack) + +#define StackIsNotEmpty (num_stack > 0) + +#define StackIsEmpty (num_stack <= 0) + +#define ResetStack { num_stack = 0; } + +#endif diff --git a/vroni/Include/types.h b/vroni/Include/types.h new file mode 100644 index 0000000..32e2ea5 --- /dev/null +++ b/vroni/Include/types.h @@ -0,0 +1,41 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2001-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: Stefan Huber */ +/* Modified: 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 */ +/* */ +/*****************************************************************************/ + +#include "defs.h" + +#ifndef VRONI_TYPES_H +#define VRONI_TYPES_H + + +#ifdef HAVE_BOOL + #include + typedef bool vr_bool; +#else + #define false 0 + #define true (!false) + typedef unsigned char vr_bool; +#endif + + + +#endif diff --git a/vroni/Include/util.h b/vroni/Include/util.h new file mode 100644 index 0000000..d86682b --- /dev/null +++ b/vroni/Include/util.h @@ -0,0 +1,287 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2010-2023 M. Held, S. Huber */ +/* */ +/* 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: Stefan Huber, 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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_UTIL_H +#define VRONI_UTIL_H + +#ifndef DOUBLE_OVERRIDE +#include +#endif + +#include "consts.h" + + +inline static int Sign(double_arg x) +{ + if ((x == 0.0) || (x == -0.0)) + return 0; + + if ( x > 0.0) + return 1; + else + return -1; +} + + +/** Like Sign but closed interval (-eps, eps) is identified with 0 */ +inline static int SignEps(double_arg x, double_arg eps) +{ + if (x > eps) + return 1; + else if (x < -eps) + return -1; + else + return 0; +} + +inline static double Abs(double_arg x) +{ + return fabs(x); +} + +inline static void Swap_d(double* x, double* y) +{ + double t = *y; + *y = *x; + *x = t; +} + +inline static void Swap_i(int* x, int* y) +{ + int t = *y; + *y = *x; + *x = t; +} + +inline static double Ceiling(double_arg x) +{ + return ceil(x); +} + +#ifndef DOUBLE_OVERRIDE +//function currently unused. In case it is used later, it requires +//another way to calculate the CubicRoot for CORE and possibly MPFR +inline static double CubicRoot(double_arg x) +{ + const double r = pow(x, M_1_3); + if(Sign(x)<0) + return -r; + else + return r; +} +#endif + + + +#define Sq(x) ((x) * (x)) + +#define VroniSwap(i1, i2, i) \ +{(i) = (i1); \ + (i1) = (i2); \ + (i2) = (i); } + +#define Min(a, b) ((a) < (b) ? (a) : (b)) +#define Max(a, b) ((b) < (a) ? (a) : (b)) +#define Min3(a, b, c) (((a) < (b)) ? \ + (((a) < (c)) ? \ + (a) : (c)) \ + : \ + (((b) < (c)) ? \ + (b) : (c))) +#define Max3(a, b, c) (((a) < (b)) ? \ + (((b) < (c)) ? \ + (c) : (b)) \ + : \ + (((a) < (c)) ? \ + (c) : (a))) +#define Min4(a, b, c, d) (((a) < (b)) ? \ + (((a) < (c)) ? \ + (((a) < (d)) ?\ + (a) : (d)) \ + : \ + (((c) < (d)) ? \ + (c) : (d))) \ + : \ + (((b) < (c)) ? \ + (((b) < (d)) ? \ + (b) : (d)) \ + : \ + (((c) < (d)) ? \ + (c) : (d)))) +#define Max4(a, b, c, d) (((a) < (b)) ? \ + (((b) < (c)) ? \ + (((c) < (d)) ?\ + (d) : (c)) \ + : \ + (((b) < (d)) ? \ + (d) : (b))) \ + : \ + (((a) < (c)) ? \ + (((c) < (d)) ? \ + (d) : (c)) \ + : \ + (((a) < (d)) ? \ + (d) : (a)))) + +#define MinMax3(a, b, c, min, max) {\ + if ((a) < (b)) {\ + if ((a) < (c)) {\ + min = (a); \ + if ((b) < (c)) max = (c); \ + else max = (b); \ + }\ + else { \ + min = (c); \ + max = (b); \ + }\ + }\ + else { \ + if ((a) < (c)) {\ + min = (b); \ + max = (c); \ + } \ + else { \ + max = (a); \ + if ((b) < (c)) min = (b); \ + else min = (c); \ + } \ + }\ +} + + +#define MinMax4(a, b, c, d, min, max) {\ + if ((a) < (b)) {\ + if ((a) < (c)) {\ + min = (a); \ + if ((b) < (c)) max = (c); \ + else max = (b); \ + } \ + else { \ + min = (c); \ + max = (b); \ + } \ + }\ + else { \ + if ((a) < (c)) { \ + min = (b); \ + max = (c); \ + } \ + else { \ + max = (a); \ + if ((b) < (c)) min = (b); \ + else min = (c); \ + }\ + } \ + if ((d) < min) min = (d); \ + else if ((d) > max) max = (d); \ +} + + +#define SortTwoNumbers(a, b, c) {\ + if (a > b) { \ + c = a; \ + a = b; \ + b = c; \ + } \ +} + + + +#define SortThreeNumbers(a, b, c, d) {\ + if (a < b) {\ + if (a < c) {\ + if (b > c) {\ + d = b; \ + b = c; \ + c = d; \ + }\ + }\ + else { \ + d = a; \ + a = c; \ + c = b; \ + b = d; \ + }\ + }\ + else { \ + if (a < c) { \ + d = a; \ + a = b; \ + b = d; \ + } \ + else { \ + if (b < c) {\ + d = a; \ + a = b; \ + b = c; \ + c = d; \ + }\ + else { \ + d = a; \ + a = c; \ + c = d; \ + }\ + }\ + }\ +} + + +#define MinMax(a, b, min, max) {\ + if ((b) < (a)) {\ + min = (b); \ + max = (a); \ + } \ + else { \ + min = (a); \ + max = (b); \ + } \ +} + + +#define MinMaxQ(a, b, min, max) \ + (((b) < (a)) ? (min = (b), max = (a)) : (min = (a), max = (b))) + + +#define MinMax3Q(a, b, c, min, max) \ + (((b) < (a)) ? (((c) < (b)) ? (min = (c), max = (a)) : \ + (((c) > (a)) ? (min = (b), max = (c)) : \ + (min = (b), max = (a)))) : \ + (((c) > (b)) ? (min = (a), max = (c)) : \ + (((c) > (a)) ? (min = (a), max = (b)) : \ + (min = (c), max = (b))))) + + + + +/* */ +/* some macros for epsilon-based comparisons with respect to zero... */ +/* */ +#define lt(a, b) ( ((a) < -b) ) +#define ge(a, b) (! ((a) < -b) ) +#define le(a, b) ( ((a) <= b) ) +#define gt(a, b) (! ((a) <= b) ) +#define eq(a, eps) ( (((a) <= eps) && !((a) < -eps)) ) +#define ne(a, eps) ( !eq(a,eps) ) + + +#endif + diff --git a/vroni/Include/vd_data.h b/vroni/Include/vd_data.h new file mode 100644 index 0000000..c100617 --- /dev/null +++ b/vroni/Include/vd_data.h @@ -0,0 +1,1167 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2001-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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_VD_DATA_H +#define VRONI_VD_DATA_H + +/* #define TRACE */ + + + +#define DATA_BLOCK_SIZE 1024 + + +inline void vroniObject::ResetLoopStackSize(int size) +{ + num_loop_stack = size; +} + + +inline void vroniObject::ResetLoopStackMin(int size) +{ + min_loop_stack = size; +} + + +inline void vroniObject::ResetLoopStack() +{ + num_loop_stack = 0; + min_loop_stack = 0; +} + + +inline void vroniObject::GetLoopStackSize(int& size) +{ + size = num_loop_stack; +} + + +inline void vroniObject::GetLoopStackMin(int& size) +{ + size = min_loop_stack; +} + + +inline int vroniObject::GetLoopStackSizeFunc(void) +{ + return num_loop_stack; +} + + +inline int vroniObject::GetLoopStackMinFunc(void) +{ + return min_loop_stack; +} + + +inline int vroniObject::GetLoopStackElementFunc(int I) +{ + assert(I < num_loop_stack); + assert(I >= 0); + + return loop_stack[I]; +} + + +#define GetLoopStackElement(I, E) \ +{\ + assert(I < num_loop_stack); \ + assert(I >= 0); \ + E = loop_stack[I]; \ +} + + +#define PushOntoLoopStack(E) \ +{\ + if (num_loop_stack >= max_num_loop_stack) { \ + max_num_loop_stack += DATA_BLOCK_SIZE; \ + loop_stack = (int*) ReallocateArray(loop_stack, max_num_loop_stack, \ + sizeof(int), "voronoi:loop_stack"); \ + } \ + loop_stack[num_loop_stack] = E; \ + ++num_loop_stack; \ +} + + +#define DeleteFromLoopStack \ +{\ + assert(num_loop_stack > 0); \ + --num_loop_stack; \ +}\ + + +#ifdef TRACE +#define IncreaseThreshold(zero) \ +{\ + ++threshold_counter; \ + if (zero < 0.0) { \ + zero = 0.0; \ + } \ + else if (zero == 0.0) { \ + zero = TINY; \ + } \ + else { \ + zero *= 10.0; \ + } \ +} +#else +#define IncreaseThreshold(zero) \ +{\ + if (zero < 0.0) { \ + zero = 0.0; \ + } \ + else if (zero == 0.0) { \ + zero = TINY; \ + } \ + else { \ + zero *= 10.0; \ + } \ +} +#endif + + +#define SetThreshold(zero, epsilon) \ +{\ + zero = epsilon; \ +} + + + +#define ResetPreserveBuffer \ +{\ + num_preserve = 0; \ +} + + + +#define AddToPreserveBuffer(S, T) \ +{\ + if (num_preserve >= max_num_preserve) { \ + max_num_preserve += DATA_BLOCK_SIZE; \ + preserve = (preserve_buffer*) ReallocateArray(preserve, \ + max_num_preserve, \ + sizeof(preserve_buffer), \ + "voronoi:preserve"); \ + } \ + preserve[num_preserve].site = S; \ + preserve[num_preserve].type = T; \ + ++num_preserve; \ +} + + + +#define AddSiteVisited(I, T) \ +{\ + if (num_visited >= max_num_visited) { \ + max_num_visited += DATA_BLOCK_SIZE; \ + sites_visited = (s_visited*) ReallocateArray(sites_visited, \ + max_num_visited, \ + sizeof(s_visited), \ + "voronoi:sites_visited"); \ + }\ + sites_visited[num_visited].ind = I; \ + sites_visited[num_visited].type = T; \ + ++num_visited; \ +} + + +#define AddPntVisited(I) \ +{\ + if (num_pnt_visited >= max_num_pnt_visited) { \ + max_num_pnt_visited += DATA_BLOCK_SIZE; \ + pnt_visited = (int*) ReallocateArray(pnt_visited, \ + max_num_pnt_visited, \ + sizeof(int), \ + "voronoi:pnt_visited"); \ + }\ + pnt_visited[num_pnt_visited] = I; \ + ++num_pnt_visited; \ +} + + + +#define ResetPntVisited(I) \ +{\ + for (I = 0; I < num_pnt_visited; ++I) { \ + SetPntVisited(pnt_visited[I], false); \ + } \ + num_pnt_visited = 0; \ +} + + + +#define AddNodeChecked(I) \ +{\ + if (num_checked >= max_num_checked) { \ + max_num_checked += DATA_BLOCK_SIZE; \ + nodes_checked = (int*) ReallocateArray(nodes_checked, \ + max_num_checked, \ + sizeof(int), \ + "voronoi:nodes_checked"); \ + }\ + nodes_checked[num_checked] = I; \ + ++num_checked; \ +} + + +#define ResetNodeChecked(I) \ +{\ + for (I = 0; I < num_checked; ++I) { \ + MarkNodeUnchecked(nodes_checked[I]); \ + } \ + num_checked = 0; \ +} + + + +#define InsertSiteNode(E, P, N, I) \ +{ \ + N = StoreNode(P.x, P.y, 0.0); \ + InsertDummyNode(E, N, false); \ + MarkNodeUnchecked(N); \ + SetNodeSite(N, I); \ + SetPntNode(I, N); \ + SetVDPtr(I, PNT, E); \ + SetIncidentSite(I, true); \ +} + + + +#ifdef TRACE +inline unsigned long vroniObject::GetThresholdCounter(void) +{ + return threshold_counter; +} +#endif + + +inline void vroniObject::SetDebugFlagVD(vr_bool dbg_flag) +{ + debug_flag_VD = dbg_flag; + + return; +} + +/** Get first vertex of given site of given type */ +inline int vroniObject::Get1stVtx(int site, int type) +{ + if (type == SEG) { + assert(InSegsList(site)); + return segs[site].i1; + } else if (type == ARC) { + assert(InArcsList(site)); + return arcs[site].i1; + } else { + assert(false); + return NIL; + } +} + +/** Get second vertex of given site of given type */ +inline int vroniObject::Get2ndVtx(int site, int type) +{ + if (type == SEG) { + assert(InSegsList(site)); + return segs[site].i2; + } else if (type == ARC) { + assert(InArcsList(site)); + return arcs[site].i2; + } else { + assert(false); + return NIL; + } +} + + +/** Get first vertex of given segment */ +inline int vroniObject::Get1stVtxSeg(int site) +{ + assert(InSegsList(site)); + return segs[site].i1; +} + + +/** Get second vertex of given segment */ +inline int vroniObject::Get2ndVtxSeg(int site) +{ + assert(InSegsList(site)); + return segs[site].i2; +} + + +/** Get first vertex of given arc */ +inline int vroniObject::Get1stVtxArc(int site) +{ + assert(InArcsList(site)); + return arcs[site].i1; +} + +/** Get second vertex of given arc */ +inline int vroniObject::Get2ndVtxArc(int site) +{ + assert(InArcsList(site)); + return arcs[site].i2; +} + + +/** Set first vertex of site of given type to pnt */ +inline void vroniObject::Set1stVtx(int site, int type, int pnt) +{ + if (type == SEG) { + assert(InSegsList(site)); + segs[site].i1 = pnt; + } else if (type == ARC) { + assert(InArcsList(site)); + arcs[site].i1 = pnt; + } else + assert(false); +} + +/** Set second vertex of site of given type to pnt */ +inline void vroniObject::Set2ndVtx(int site, int type, int pnt) +{ + if (type == SEG) { + assert(InSegsList(site)); + segs[site].i2 = pnt; + } else if (type == ARC) { + assert(InArcsList(site)); + arcs[site].i2 = pnt; + } else + assert(false); +} + + +/** Set first vertex of given segment */ +inline void vroniObject::Set1stVtxSeg(int site, int pnt) +{ + assert(InSegsList(site)); + segs[site].i1 = pnt; +} + +/** Set second vertex of given segment */ +inline void vroniObject::Set2ndVtxSeg(int site, int pnt) +{ + assert(InSegsList(site)); + segs[site].i2 = pnt; +} + + +/** Set first vertex of given arc */ +inline void vroniObject::Set1stVtxArc(int site, int pnt) +{ + assert(InArcsList(site)); + arcs[site].i1 = pnt; +} + +/** Set second vertex of given arc */ +inline void vroniObject::Set2ndVtxArc(int site, int pnt) +{ + assert(InArcsList(site)); + arcs[site].i2 = pnt; +} + +/** Check whether point has been visited */ +inline vr_bool vroniObject::IsPntVisited(int site) +{ + assert(InPntsList(site)); + return pnts[site].vis; +} + +/** Set whether point has been visited */ +inline void vroniObject::SetPntVisited(int site, vr_bool vis) +{ + assert(InPntsList(site)); + pnts[site].vis = vis; +} + + +/** Check if pnt is start point of seg */ +inline vr_bool vroniObject::IsSegStartPnt(int seg, int pnt) +{ + assert(InSegsList(seg)); + return segs[seg].i1 == pnt; +} + +/** Check if pnt is send point of seg */ +inline vr_bool vroniObject::IsSegEndPnt(int seg, int pnt) +{ + assert(InSegsList(seg)); + return segs[seg].i2 == pnt; +} + +/** Get coordinates of input point */ +inline coord vroniObject::GetPntCoords(int pnt) +{ + assert(InPntsList(pnt)); + return pnts[pnt].p; +} + +/** Set x-coordinate of point */ +inline void vroniObject::SetXCoord(int pnt, double_arg x) +{ + assert(InPntsList(pnt)); + pnts[pnt].p.x = x; +} + +/** Set y-coordinate of point */ +inline void vroniObject::SetYCoord(int pnt, double_arg y) +{ + assert(InPntsList(pnt)); + pnts[pnt].p.y = y; +} + +/** Get start point coordinates of seg */ +inline coord vroniObject::GetSegStartCoord(int seg) +{ + assert(InSegsList(seg)); + return pnts[segs[seg].i1].p; +} + +/** Get end point coordinates of seg */ +inline coord vroniObject::GetSegEndCoord(int seg) +{ + assert(InSegsList(seg)); + return pnts[segs[seg].i2].p; +} + + +/** Get start point coordinates of arc */ +inline coord vroniObject::GetArcStartCoord(int arc) +{ + assert(InArcsList(arc)); + return pnts[arcs[arc].i1].p; +} + +/** Get end point coordinates of arc */ +inline coord vroniObject::GetArcEndCoord(int arc) +{ + assert(InArcsList(arc)); + return pnts[arcs[arc].i2].p; +} + + +/** Get center point of arc a */ +inline coord vroniObject::GetArcCenter(int a) +{ + assert(InArcsList(a)); + return arcs[a].c; +} + + +/** Get radius of arc a */ +inline double vroniObject::GetArcRadius(int a) +{ + assert(InArcsList(a)); + return arcs[a].r; +} + +/** Check whether p is start point of a */ +inline vr_bool vroniObject::IsArcStartPnt(int a, int p) +{ + assert(InArcsList(a)); + return (arcs[a].i1 == p); +} + +/** Check whether p is end point of a */ +inline vr_bool vroniObject::IsArcEndPnt(int a, int p) +{ + assert(InArcsList(a)); + return (arcs[a].i2 == p); +} + + + +/** Get original orientation of arc a +* Attention: within VRONI all arcs are oriented CCW! */ +inline vr_bool vroniObject::GetArcOrientation(int a) +{ + assert(InArcsList(a)); + return arcs[a].ccw; +} + + +/** Set radius of arc a */ +inline void vroniObject::SetArcRadius(int a, double_arg r) +{ + assert(InArcsList(a)); + arcs[a].r = r; +} + + +/** Set center of arc a */ +inline void vroniObject::SetArcCenter(int a, coord p) +{ + assert(InArcsList(a)); + arcs[a].c = p; +} + + +/** Set orientation of arc a */ +inline void vroniObject::SetArcOrientation(int a, vr_bool ccw) +{ + assert(InArcsList(a)); + arcs[a].ccw = ccw; +} + +/** Set normal vector of start point of arc a */ +inline void vroniObject::SetArcStartNormal(int a, coord ns) +{ + assert(InArcsList(a)); + arcs[a].ns = ns; +} + +/** Set normal vector of end point of arc a */ +inline void vroniObject::SetArcEndNormal(int a, coord ne) +{ + assert(InArcsList(a)); + arcs[a].ne = ne; +} + + +/** Get normal vector of start point of arc a */ +inline coord vroniObject::GetArcStartNormal(int a) +{ + assert(InArcsList(a)); + return arcs[a].ns; +} + +/** Get normal vector of end point of arc a */ +inline coord vroniObject::GetArcEndNormal(int a) +{ + assert(InArcsList(a)); + return arcs[a].ne; +} + + +/** Set chord equation coefficients of arc s to a, b, d */ +inline void vroniObject::SetChordEqnData(int s, double_arg a, double_arg b, double_arg d) +{ + assert(InArcsList(s)); + arcs[s].a = a; + arcs[s].b = b; + arcs[s].d = d; +} + + +/** Get chord equation coefficients of arc s */ +inline void vroniObject::GetChordEqnData(int s, double* a, double* b, double* d) +{ + assert(InArcsList(s)); + *a = arcs[s].a; + *b = arcs[s].b; + *d = arcs[s].d; +} + +/** Set equation data of segment s */ +inline void vroniObject::SetSegEqnData(int s, double_arg a, double_arg b, double_arg c) +{ + assert(InSegsList(s)); + segs[s].a = a; + segs[s].b = b; + segs[s].c = c; +} + +/** Get equation data of segment s */ +inline void vroniObject::GetSegEqnData(int s, double* a, double* b, double* c) +{ + assert(InSegsList(s)); + *a = segs[s].a; + *b = segs[s].b; + *c = segs[s].c; +} + + +/** Get normal vector of seg s */ +inline coord vroniObject::GetSegNormal(int s) +{ + assert(InSegsList(s)); + return MakeVec(segs[s].a, segs[s].b); +} + +/** Get unit vector from start point to end point of seg s */ +inline coord vroniObject::GetSegDirection(int s) +{ + assert(InSegsList(s)); + return VecCW(GetSegNormal(s)); +} + +/** Get length of segment s*/ +inline double vroniObject::GetSegLgth(int s) +{ + assert(InSegsList(s)); + return segs[s].lgth; +} + +/** Set length of segment s */ +inline void vroniObject::SetSegLgth(int s, double_arg l) +{ + assert(InSegsList(s)); + segs[s].lgth = l; +} + +/** Check whether point p has incident site */ +inline vr_bool vroniObject::HasIncidentSite(int p) +{ + assert(InPntsList(p)); + return pnts[p].s; +} + + +/** set incident site of point p */ +inline void vroniObject::SetIncidentSite(int p, int status) +{ + assert(InPntsList(p)); + pnts[p].s = (status != 0); +} + +/** Check whether point p is to be deleted */ +inline vr_bool vroniObject::IsDeletedPnt(int p) +{ + assert(InPntsList(p)); + return pnts[p].del; +} + + +/** Set whether point p is to be deleted */ +inline void vroniObject::SetDeletedPnt(int p, vr_bool del) +{ + assert(InPntsList(p)); + pnts[p].del = del; + if (del) { + pnts_deleted = true; +#ifdef GRAPHICS + pnts[p].draw = false; +#endif + } +} + +/** Get node of point p */ +inline int vroniObject::GetPntNode(int p) +{ + assert(InPntsList(p)); + return pnts[p].node; +} + +/** Set node of point p */ +inline void vroniObject::SetPntNode(int p, int n) +{ + assert(InPntsList(p)); + assert(InNodesList(n)); + pnts[p].node = n; +} + + +/** Set vd-pointer of point p */ +inline void vroniObject::SetPntVDPtr(int p, int e) +{ + assert(InPntsList(p)); + pnts[p].vd = e; +} + + +/** Get vd-pointer of point p */ +inline int vroniObject::GetPntVDPtr(int p) +{ + assert(InPntsList(p)); + return pnts[p].vd; +} + + +/** Reset vd-pointer of point p */ +inline void vroniObject::ResetPntVDPtr(int p) +{ + assert(InPntsList(p)); + pnts[p].vd = NIL; +} + + +/** Reset vd-pointer of segment s */ +inline void vroniObject::ResetSegVDPtr(int s) +{ + assert(InSegsList(s)); + segs[s].vd = NIL; +} + +/** Set vd-pointer of site s of type t to e */ +inline void vroniObject::SetVDPtr(int s, int t, int e) +{ + assert(InEdgesList(e)); + if (t == PNT) { + assert(InPntsList(s)); + pnts[s].vd = e; + } else if (t == SEG) { + assert(InSegsList(s)); + segs[s].vd = e; + } else if (t == ARC) { + assert(InArcsList(s)); + arcs[s].vd = e; + } else { +#ifdef VRONI_WARN + printf("\nwarning in SetVDPtr() - unknown site type %d\n", t); +#endif + assert(false); + } +} + +/** Get vd-pointer of site s of type t */ +inline int vroniObject::GetVDPtr(int s, int t) +{ + if (t == PNT) { + assert(InPntsList(s)); + return pnts[s].vd; + } else if (t == SEG) { + assert(InSegsList(s)); + return segs[s].vd; + } else if (t == ARC) { + assert(InArcsList(s)); + return arcs[s].vd; + } else { +#ifdef VRONI_WARN + printf("\nwarning in GetVDPtr() - unknown site type %d\n", t); +#endif + assert(false); + return NIL; + } +} + +/** Set start node of edge e to n */ +inline void vroniObject::SetStartNode(int e, int n) +{ + assert(InEdgesList(e)); + assert(InNodesList(n)); + edges[e].n1 = n; +} + +/** Set end node of edge e to n */ +inline void vroniObject::SetEndNode(int e, int n) +{ + assert(InEdgesList(e)); + assert(InNodesList(n)); + edges[e].n2 = n; +} + +/** Get start node of edge e */ +inline int vroniObject::GetStartNode(int e) +{ + assert(InEdgesList(e)); + return edges[e].n1; +} + +/** Get end node of edge e */ +inline int vroniObject::GetEndNode(int e) +{ + assert(InEdgesList(e)); + return edges[e].n2; +} + + +/** Ist n the start node of edge e? */ +inline vr_bool vroniObject::IsStartNode(int e, int n) +{ + assert(InEdgesList(e)); + return (edges[e].n1 == n); +} + + +/** Ist n the end node of edge e? */ +inline vr_bool vroniObject::IsEndNode(int e, int n) +{ + assert(InEdgesList(e)); + return (edges[e].n2 == n); +} + + +/** Is edge e incident to node n? */ +inline vr_bool vroniObject::IsEdgeIncident(int e, int n) +{ + assert(InEdgesList(e)); + assert(InNodesList(n)); + + return edges[e].n1 == n || edges[e].n2 == n; +} + + +/** Get the opposite node to n at edge e */ +inline int vroniObject::GetOtherNode(int e, int n) +{ + assert(IsEdgeIncident(e, n)); + return (edges[e].n1 == n) ? edges[e].n2 : edges[e].n1; +} + + +/** Get site and type left to edge e */ +inline void vroniObject::GetLftSiteData(int e, int* s, t_site* t) +{ + assert(InEdgesList(e)); + *s = edges[e].lft; + *t = edges[e].ltype; +} + + +/** Get site and type right to edge e */ +inline void vroniObject::GetRgtSiteData(int e, int* s, t_site* t) +{ + assert(InEdgesList(e)); + *s = edges[e].rgt; + *t = edges[e].rtype; +} + + +/** Get type of site left to edge e */ +inline t_site vroniObject::GetLftSiteType(int e) +{ + assert(InEdgesList(e)); + return edges[e].ltype; +} + + +/** Get type of site right to edge e */ +inline t_site vroniObject::GetRgtSiteType(int e) +{ + assert(InEdgesList(e)); + return edges[e].rtype; +} + +/** Get site left to edge e */ +inline int vroniObject::GetLftSite(int e) +{ + assert(InEdgesList(e)); + return edges[e].lft; +} + + +/** Get site right to edge e */ +inline int vroniObject::GetRgtSite(int e) +{ + assert(InEdgesList(e)); + return edges[e].rgt; +} + + +/** Given an edge e and a defining site s1 of type t1. +* Retrieve opposite site s2 and its type t2. */ +inline void vroniObject::GetOtherSiteData(int e, int s1, t_site t1, + int* s2, t_site* t2) +{ + assert(InEdgesList(e)); + + if ((edges[e].lft == s1) && (edges[e].ltype == t1)) { + *s2 = edges[e].rgt; + *t2 = edges[e].rtype; + } else { + assert((edges[e].rgt == s1) && (edges[e].rtype == t1)); + *s2 = edges[e].lft; + *t2 = edges[e].ltype; + } +} + + +/** Is node n a degree-2 node? */ +inline vr_bool vroniObject::IsDeg2Node(int n) +{ + assert(InNodesList(n)); + return nodes[n].deg2; +} + + +/** Set is-degree-2 flag of node n */ +inline void vroniObject::SetNodeDegree(int n, vr_bool f) +{ + assert(InNodesList(n)); + nodes[n].deg2 = f; +} + +/** If site s of type t the left site of edge e? */ +inline vr_bool vroniObject::IsLftSite(int e, int s, t_site t) +{ + assert(InEdgesList(e)); + return edges[e].lft == s && edges[e].ltype == t; +} + + +/** If site s of type t the right site of edge e? */ +inline vr_bool vroniObject::IsRgtSite(int e, int s, t_site t) +{ + assert(InEdgesList(e)); + return edges[e].rgt == s && edges[e].rtype == t; +} + +/** Is site s of type t a left or right site of edge e? */ +inline vr_bool vroniObject::IsLftRgtSite(int e, int s, t_site t) +{ + return IsLftSite(e, s, t) || IsRgtSite(e, s, t); +} + +/** Is left site of edge e the point s? +* Attention: We do not check for site type! */ +inline vr_bool vroniObject::IsLftPnt(int e, int s) +{ + assert(InEdgesList(e)); + return edges[e].lft == s; +} + +/** Is right site of edge e the point s? +* Attention: We do not check for site type! */ +inline vr_bool vroniObject::IsRgtPnt(int e, int s) +{ + assert(InEdgesList(e)); + return edges[e].rgt == s; +} + + +/** Get CCW edge of edge e at node n */ +inline int vroniObject::GetCCWEdge(int e, int n) +{ + assert(IsEdgeIncident(e, n)); + return edges[e].n1 == n ? edges[e].s_ccw : edges[e].e_ccw; +} + +/** Get CW edge of edge e at node n */ +inline int vroniObject::GetCWEdge(int e, int n) +{ + assert(IsEdgeIncident(e, n)); + return edges[e].n1 == n ? edges[e].s_cw : edges[e].e_cw; +} + + +/** Set CCW edge of edge e at node n to e1 */ +inline void vroniObject::SetCCWEdge(int e, int n, int e1) +{ + assert(IsEdgeIncident(e, n)); + + if (edges[e].n1 == n) + edges[e].s_ccw = e1; + else + edges[e].e_ccw = e1; +} + + +/** Set CW edge of edge e at node n to e1 */ +inline void vroniObject::SetCWEdge(int e, int n, int e1) +{ + assert(IsEdgeIncident(e, n)); + + if (edges[e].n1 == n) + edges[e].s_cw = e1; + else + edges[e].e_cw = e1; +} + + +/** Reset CW edge of edge e at node n to e1 */ +inline void vroniObject::ResetCWEdge(int e, int n) +{ + SetCWEdge(e, n, NIL); +} + +/** Reset CCW edge of edge e at node n to e1 */ +inline void vroniObject::ResetCCWEdge(int e, int n) +{ + SetCCWEdge(e, n, NIL); +} + + +/** Get status of node n */ +inline n_status vroniObject::GetNodeStatus(int n) +{ + assert(InNodesList(n)); + return nodes[n].status; +} + +/** Set status of node n to s */ +inline void vroniObject::SetNodeStatus(int n, n_status s) +{ + assert(InNodesList(n)); + nodes[n].status = s; +} + + +/** Mark node n as deleted */ +inline void vroniObject::MarkNodeDeleted(int n) +{ + SetNodeStatus(n, DELETED); +} + +/** Mark node n as visited */ +inline void vroniObject::MarkNodeVisited(int n) +{ + SetNodeStatus(n, VISITED); +} + +/** Mark node n as unchecked */ +inline void vroniObject::MarkNodeUnchecked(int n) +{ + SetNodeStatus(n, UNCHECKED); +} + +/** Mark node n as checked */ +inline void vroniObject::MarkNodeChecked(int n) +{ + SetNodeStatus(n, CHECKED); +} + +/** Mark node n as dummy */ +inline void vroniObject::MarkNodeDummy(int n) +{ + SetNodeStatus(n, DUMMY); +} + +/** Is node n marked as deleted? */ +inline vr_bool vroniObject::IsNodeDeleted(int n) +{ + return GetNodeStatus(n) == DELETED; +} + +/** Is node n marked as visited? */ +inline vr_bool vroniObject::IsNodeVisited(int n) +{ + return GetNodeStatus(n) == VISITED; +} + +/** Is node n marked as checked? */ +inline vr_bool vroniObject::IsNodeChecked(int n) +{ + return GetNodeStatus(n) == CHECKED; +} + +/** Is node n marked as unchecked? */ +inline vr_bool vroniObject::IsNodeUnchecked(int n) +{ + return GetNodeStatus(n) == UNCHECKED; +} + +/** Is node n marked as dummy? */ +inline vr_bool vroniObject::IsNodeDummy(int n) +{ + return GetNodeStatus(n) == DUMMY; +} + +/** Mark edge e as deleted */ +inline void vroniObject::MarkEdgeDeleted(int e) +{ + assert(InEdgesList(e)); + edges[e].del = true; +} + +/** Is edge e marked as deleted? */ +inline vr_bool vroniObject::IsEdgeDeleted(int e) +{ + assert(InEdgesList(e)); + return edges[e].del; +} + + +/** Is this edge not marked as deleted and has non-NIL left and right sites? */ +inline vr_bool vroniObject::IsEdgeActive(int e) +{ + assert(InEdgesList(e)); + return !IsEdgeDeleted(e) && edges[e].lft != NIL && edges[e].rgt != NIL; +} + + +/** Is this edge e a genuine edge? That is, edge e is active (IsEdgeActive) and +* if left or right sites are points, then the indices of the points are +* greater (resp. less) than minidx (resp. maxidx) */ +inline vr_bool vroniObject::IsEdgeGenuine(int e, int minidx, int maxidx) +{ + assert(InEdgesList(e)); + + if (!IsEdgeActive(e)) + return false; + + if (GetLftSiteType(e) == PNT) + if (GetLftSite(e) <= minidx || GetLftSite(e) >= maxidx) + return false; + + if (GetRgtSiteType(e) == PNT) + if (GetRgtSite(e) <= minidx || GetRgtSite(e) >= maxidx) + return false; + + return true; +} + + +/** Get coordinates of node n */ +inline coord vroniObject::GetNodeCoord(int n) +{ + assert(InNodesList(n)); + return nodes[n].p; +} + +/** Get parameter (clearance [squared]) of node n */ +inline double vroniObject::GetNodeParam(int n) +{ + assert(InNodesList(n)); + return nodes[n].r2; +} + +/** Get coordinate and parameter of node n */ +inline void vroniObject::GetNodeData(int n, coord* p, double* r) +{ + *p = GetNodeCoord(n); + *r = GetNodeParam(n); +} + +/** Get parameter of start and end node of edge e */ +inline void vroniObject::GetEdgeParam(int e, double* rs, double *re) +{ + *rs = GetNodeParam(GetStartNode(e)); + *re = GetNodeParam(GetEndNode(e)); +} + +/** Get an edge incident to node n */ +inline int vroniObject::GetIncidentEdge(int n) +{ + assert(InNodesList(n)); + return nodes[n].edge; +} + + +/** Set the edge-pointer of node n to e */ +inline void vroniObject::SetIncidentEdge(int n, int e) +{ + assert(InNodesList(n)); + assert(InEdgesList(e)); + nodes[n].edge = e; +} + + +/** Get a site where node n belongs to */ +inline int vroniObject::GetNodeSite(int n) +{ + assert(InNodesList(n)); + return nodes[n].site; +} + + +/** Set site-pointer of node n to s */ +inline void vroniObject::SetNodeSite(int n, int s) +{ + assert(InNodesList(n)); + assert(InPntsList(s)); + nodes[n].site = s; +} + + + +#endif + diff --git a/vroni/Include/vddata.h b/vroni/Include/vddata.h new file mode 100644 index 0000000..f12e290 --- /dev/null +++ b/vroni/Include/vddata.h @@ -0,0 +1,349 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2010-2023 M. Held, S. Huber */ +/* */ +/* 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: Stefan Huber, 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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_VDDATA_H +#define VRONI_VDDATA_H + +#ifndef DOUBLE_OVERRIDE +#include +#endif + +#include "consts.h" +#include "ext_appl_defs.h" +#include "wmat.h" + + +#if defined(OGL_GRAPHICS) + #ifndef GRAPHICS + #define GRAPHICS + #endif +#endif + + +// tipo di bisettore +typedef enum { + LINE, + PARABOLA, + HYPERBOLA, + HYPERELL, + NONE +} BisectorType ; + + + +/** Different types of input sites, Voronoi diagram objects, Delaunay + * triangulation object, and offsetting object */ +typedef enum +{ + /** Segment */ + SEG, + /** Arc */ + ARC, + /** Point */ + PNT, + + /** Voronoi node */ + VDN, + /** Voronoi edge */ + VDE, + + /** Delaunay triangulation edge */ + DTE, + + /** CCW offset arc */ + CCW, + /** CW offset arc */ + CW, + + UNKNOWN +} t_site; + + + +/** Status of voronoi node */ +typedef enum +{ + /** not yet checked */ + UNCHECKED, + /** keep this node */ + CHECKED, + /** delete this node */ + DELETED, + /** already visited, marked for deletion */ + VISITED, + /** this is a dummy node */ + DUMMY, + MISC +} n_status; + + + + + +/** Input vertex */ +struct pnt +{ + /** Position of vertex */ + coord p; + + /** An edge to the Voronoi cell of this point */ + int vd; + /** A Voronoi node that concides with it */ + int node; + + /** Already visited */ + vr_bool vis; + /** Segment/arc that is incident has already been inserted. */ + vr_bool s; + + /** Will be deleted during next restart */ + vr_bool del; + +#ifdef WRITE_VD + int vd_edge; + int idx; +#endif + +#ifdef GRAPHICS + /** We draw this point */ + vr_bool draw; +#endif + +#ifdef ORDERED + /** number assinged in increasing order for every pnt */ + int key; +#endif + +#ifdef EXT_APPL_PNTS + eap_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline pnt() {} + +}; + + +/** Input segment */ +struct seg +{ + /** Start point */ + int i1; + /** End point */ + int i2; + + /** parameter in a*x + b*x + c = 0 */ + double a; + /** parameter in a*x + b*x + c = 0 */ + double b; + /** parameter in a*x + b*x + c = 0 */ + double c; + + /** length of line segment */ + double lgth; + + /** an edge of the Voroni cell of this seg*/ + int vd; + +#ifdef WRITE_VD + int vd_edge; +#endif + +#ifdef GRAPHICS + /** We draw this point */ + vr_bool draw; +#endif + +#ifdef ORDERED + /** number assigned in increasing order for every pnt */ + int key; +#endif + +#ifdef EXT_APPL_SITES + eas_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline seg() {} + +}; + + +/** Input arc */ +struct arc +{ + /** start point */ + int i1; + /** end point */ + int i2; + + /** center point */ + coord c; + /** radius */ + double r; + /** orientation */ + vr_bool ccw; + + /** unit normal vector at start point point outwards */ + coord ns; + /** unit normal vector at end point point outwards */ + coord ne; + + /** parameter of chord line equation a*x + b*y + d = 0 */ + double a; + /** parameter of chord line equation a*x + b*y + d = 0 */ + double b; + /** parameter of chord line equation a*x + b*y + d = 0 */ + double d; + + /** an edge of the voronoi cell of this arc */ + int vd; + +#ifdef GRAPHICS + /** We draw this point */ + vr_bool draw; +#endif + +#ifdef ORDERED + /** number assigned in increasing order for every pnt */ + int key; +#endif + +#ifdef EXT_APPL_SITES + eas_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline arc() {} + +}; + + + + + +/** Voronoi node */ +struct node +{ + /** Position */ + coord p; + /** Clearance. + * Attention: During pnt-VD generation this is the squared clearance!!! */ + double r2; + /** A degree-two node */ + vr_bool deg2; + + /** Current status of node */ + n_status status; + + /** an incident edge */ + int edge; + /** an input point, if node coincides with some. NIL otherwise. */ + int site; + +#ifdef WRITE_VD + int idx; +#endif + +#ifdef EXT_APPL_VD + ean_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline node() {} +}; + + + +struct edge { + int n1; /* start node */ + int n2; /* end node */ + int lft; /* left defining site */ + int rgt; /* right defining site */ + t_site ltype; /* type of left defining site: PNT, SEG, or ARC */ + t_site rtype; /* type of right defining site: PNT, SEG, or ARC */ + int s_ccw; /* next edge in CCW order around start node */ + int s_cw; /* next edge in CW order around start node */ + int e_ccw; /* next edge in CCW order around end node */ + int e_cw; /* next edge in CW order around end node */ + vr_bool del; /* edge to be deleted during the incremental insertion? */ +#ifdef MAT + w_mat_data w_mat; /* data for the (weighted) medial axis */ +#endif +#ifdef EXT_APPL_VD + eae_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline edge() {} +}; /********** Voronoi edge ******************************/ + + +typedef struct { + vr_bool active; /* for repeated offsetting: true if the offset value is */ + /* less than the maximum of the clearances of the nodes */ + /* of this VD edge. */ + vr_bool e_new; /* true if no offset curve (at the current offset) has */ + /* already intersected this bisector. */ + vr_bool deg; /* true if the clearance of the start node of this edge */ + /* is identical to the clearance of the end node */ +} e_flag; /************* status flags for Voronoi edges ***********/ + +struct e_formula { + vr_bool init; /* true if a parameterization of this bisectors has not */ + /* yet been computed. */ + double A; /* coefficient of parameterization; see data_off.c */ + double B; /* coefficient of parameterization; see data_off.c */ +#ifdef GENUINE_ARCS + double C; /* coefficient of parameterization; see data_off.c */ + double D; /* coefficient of parameterization; see data_off.c */ +#endif + double d; /* coefficient of parameterization; see data_off.c */ + vr_bool k1; /* positive or negative sliding direction of site #1 */ + vr_bool k2; /* positive or negative sliding direction of site #2 */ + vr_bool sign; /* positive or negative sign in the parameterization? */ + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline e_formula() {} +}; /******* parameterization data for Voronoi edges ********/ + +#ifdef ORDERED +struct ordered_sites +{ + int ind; + int key; + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline ordered_sites() {} +}; +#endif + +#ifdef SORTED +struct sorted_sites +{ + int ind; + double lgth; + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline sorted_sites() {} +}; +#endif + +#endif + diff --git a/vroni/Include/vroni_object.h b/vroni/Include/vroni_object.h new file mode 100644 index 0000000..7daa4bf --- /dev/null +++ b/vroni/Include/vroni_object.h @@ -0,0 +1,3108 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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-172 */ +/* Voice Mail: (+43 662) 8044-6304 */ +/* Snail Mail: Martin Held */ +/* FB Informatik */ +/* Universitaet Salzburg */ +/* A-5020 Salzburg, Austria */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_OBJECT_H +#define VRONI_OBJECT_H + +#include +#include +#include +#include +#include + +#ifndef NO_CPUTIME +#ifdef CPUTIME_BY_CHRONO +#include +#endif +#endif + +#ifdef CPUTIME_VIA_CLOCK +#include +#endif + +#ifdef OGL_GRAPHICS +#ifdef __APPLE__ +#include +#else +#include /* glut.h includes gl.h and glu.h */ +#endif +#endif + +// da heap.cc +#define HEAP_BLOCK_SIZE 32768 + +#include "coord.h" +#include "vddata.h" +#include "vronivector.h" +#include "ext_appl_inout.h" +#include "defs.h" +#include "offset.h" +#include "util.h" + +/* */ +/* class predeclarations to avoid having more inclusions */ +/* */ + + +/* */ +/* types: classes, enums, typedefs */ +/* */ + +/* from data_off.cc */ + +#define STACK_INCR 32768 +#define STACK_TYPE int +#define STACK_STRING "data_off:stack" + +/* from vd_basic.cc */ + +#define VRONI_MAXSOL 80 + + +/* from header.h */ +typedef enum {vroniCHARS, + vroniINTEGER, + vroniDOUBLE, + vroniBOOLEAN, + vroniCOORD, + vroniN_STATUS, + vroniT_SITE, + vroniPNTS} my_types; + +/* from intersections.cc - type definitions for grid for geometric hashing */ +struct grid_cell; + +typedef struct point_entry +{ + int num; + std::set cells; +} point_entry; + +struct comp_seg_iscoord +{ + comp_seg_iscoord(double val) { eps = val; } + bool operator()(const coord& a, const coord& b) const + { + return (lt(a.x - b.x, eps) || (eq(a.x - b.x, eps) && (a.y < b.y))); + } + + double eps; + + private: + comp_seg_iscoord(); +}; + +typedef struct seg_entry +{ + seg_entry(double val) { + intersections.reset( + new std::set(comp_seg_iscoord(val)) + ); + } + + int num; + std::unique_ptr> intersections; + + private: + seg_entry(); + +} seg_entry; + +#ifdef GENUINE_ARCS +typedef struct arc_intersection +{ + coord c; + double alpha; +} arc_intersection; + +struct comp_arc_iscoord +{ + bool operator()(const arc_intersection& a, const arc_intersection& b) const + { + return a.alpha < b.alpha; + } +}; + +typedef struct arc_entry +{ + int num; + std::set intersections; +} arc_entry; +#endif + +typedef struct grid_cell +{ + int i, j; + double x_min, x_max; + double y_min, y_max; + + std::set points; + std::set segs; +#ifdef GENUINE_ARCS + std::set arcs; +#endif +} grid_cell; + + +typedef struct grid +{ + grid_cell** cells; + int n_x, n_y; + double d_x, d_y; + double *x_min, *y_min, *x_max, *y_max; + + std::map points; + std::map segs; +#ifdef GENUINE_ARCS + std::map arcs; +#endif +} grid; + + +/* */ +/* global variables */ +/* */ + + +/* */ +/* VRONI object base class declaration */ +/* */ +class vroniObject +{ +public: + + // + // CONSTRUCTOR / DESTRUCTOR + // + vroniObject(); + + virtual ~vroniObject(); + + + // + // API FUNCTIONS + // + void apiHandleError(void); /* VRONI exception handling */ + + void apiInitializeProgram(void); /* call this routine once prior */ + /* calling any other routine of */ + /* VRONI */ + + void apiResetAll(void); /* call this routine whenever */ + /* new data is to be input and */ + /* VRONI's data structures are */ + /* to be reset; note that this */ + /* function won't free memory */ + /* allocated */ + + void apiTerminateProgram(void); /* call this routine to release */ + /* all memory allocated by VRONI*/ + + void apiHandleInput(char input_file[], /* name of the input file */ + vr_bool *new_input, /* true if new data has been */ + /* read */ + vr_bool read_polygon, /* read ".dat" format */ + vr_bool read_poly, /* read ".poly" format */ + vr_bool read_sites, /* read ".site" format */ + vr_bool read_xdr, /* read ".xdr" format */ + vr_bool read_e00, /* read ".e00" format */ + vr_bool read_polylines,/* read ".polylines" format */ + vr_bool read_usgs, /* read ".usgs" format */ + vr_bool read_dxf, /* read ".dxf" format */ + vr_bool read_pnts, /* read ".pnt" format */ + vr_bool read_graphml);/* read ".graphml" format */ + + void apiFileInput(char input_file[], /* name of the input file */ + vr_bool *new_input); /* true if new data has been */ + /* read */ + /* this function requires the */ + /* user to stick to my naming */ + /* convention for the extension */ + /* of the input file relative */ + /* to the data format used */ + + void apiArrayInput(int number_of_points, /* data in point_data[0,..,k] */ + /* for k := number_of_points-1 */ + in_pnts *point_data, /* see ext_appl_inout.h */ + int number_of_segments, + in_segs *segment_data, /* see ext_appl_inout.h */ + int number_of_arcs, + in_arcs *arc_data, /* see ext_appl_inout.h */ + vr_bool *new_input); + + void apiComputeVD(vr_bool save_data, /* save input data to file? */ + vr_bool new_data, /* first call for this data? */ + vr_bool time, /* do you want to time the */ + /* computation? */ + int bound, /* scale factor for bounding */ + /* box; default value: 3 */ + int sample, /* sampling factor for sampling */ + /* segs/arcs; default: 0; */ + /* see SampleData() in */ + /* approx.cc */ + int approx, /* approximation factor for */ + /* circular arcs; default: 0; */ + /* see ApproxArcsHeuristic() in */ + /* approx.cc. obsolet by now! */ + char output_file[], /* name of the output file; */ + /* irrelevant if save_data is */ + /* false */ + vr_bool discard_duplicate_sites, + /* shall the code check prior */ + /* to the computation whether */ + /* duplicate segs/arcs have */ + /* been input? default: false. */ + vr_bool pnts_only, /* compute VD/DT of points only */ + vr_bool write_vd_dt, /* output point VD/DT */ + char vd_dt_file[], /* output file for point VD/DT */ + vr_bool clean_up); /* shall we clean up the data */ + /* prior to the VD computation? */ + + void apiComputeOff(vr_bool time, /* do you want to time the */ + /* computation? */ + char off_file[], /* name of the file that will */ + /* contain the offsets computed */ + vr_bool write_off, /* shall we output the offsets */ + /* to off_file[]? */ + vr_bool dxf_format, /* if offsets are to be output: */ + /* shall we use DXF format? */ + double t_offset, /* compute offset curve(s) for */ + /* offset distance t_offset */ + double d_offset, /* incremental step-over */ + /* distance for further offset */ + /* curves */ + vr_bool auto_offset, /* shall we use my heuristic */ + /* for finding offset distances */ + /* that create a family of */ + /* offsets? */ + vr_bool left_offset, /* true if offsets are to be */ + /* computed only on the left */ + /* side of input segments */ + vr_bool right_offset); /* true if offsets are to be */ + /* computed only on the right */ + /* side of input segments */ + +#ifdef MAT + void apiComputeWMAT(vr_bool auto_wmat, /* shall we use my heuristic */ + /* for finding nice WMAT */ + /* thresholds? */ + double wmat_angle, /* angle threshold for WMAT */ + /* computation;in radians, out */ + /* of the interval [0, pi] */ + double wmat_dist, /* distance threshold for WMAT */ + /* computation */ + vr_bool time, /* do you want to time the */ + /* computation? */ + vr_bool left_wmat, /* true if WMAT is to be */ + /* computed only on the left */ + /* side of input segments */ + vr_bool right_wmat); /* true if WMAT is to be */ + /* computed only on the right */ + /* side of input segments */ +#endif + +#ifdef WRITE_VD + void apiOutput_VD(char vd_file[], /* name of the file that will */ + /* contain the VD polygons */ + double vd_apx_dist, /* sampling distance used for */ + /* approximating conic VD edges */ + vr_bool left_vd, /* true if VD is to be */ + /* output only on the left */ + /* side of input segments */ + vr_bool right_vd); /* true if VD is to be */ + /* output on the right */ + /* side of input segments */ +#endif + + void apiComputeOutputMIC(vr_bool time, /* do you want to time the */ + /* computation? */ + vr_bool lft_mic, /* true if MIC is to be */ + /* computed only on the left */ + /* side of input segments */ + vr_bool rgt_mic, /* true if MIC is to be */ + /* computed only on the right */ + /* side of input segments */ + coord *center, /* x,y-coordinates of a MIC */ + /* center */ + double *radius); /* radius of a MIC circle */ + + void apiResetOffsetData(void); /* discard all offsets computed */ + /* so far */ + + const char* apiGetProgName(); + const char* apiGetProgVersion(); + const char* apiGetProgYear(); + + /* */ + /* API function apiOutputOffsets() allows a user to traverse my offset */ + /* data structure and extract the offset data and "write" it to an entity */ + /* "output". See WriteOffsets() in offsets.cc for a sample use. Needless */ + /* to say, it is the user's responsibility to provide apiOutputOffsets() */ + /* with the adequate function arguments. */ + /* */ + void apiOutputOffsets(void *output, /* this is a pointer to a */ + /* user-defined object, such as */ + /* a file or a structure; */ + void (vroniObject::*StartOffsetsFuncPtr)( + void *output, + int num_offset_loops), + void (vroniObject::*StartOffsetLoopFuncPtr)( + void *output, + int num_offset_elements), + void (vroniObject::*WriteOffSetSegFuncPtr)( + void *output, +#ifdef EXT_APPL_OFF + eao_type ext_appl_off, +#endif + double_arg x1, double_arg y1, + double_arg x2, double_arg y2), + void (vroniObject::*WriteOffsetArcFuncPtr)( + void *output, +#ifdef EXT_APPL_OFF + eao_type ext_appl_off, +#endif + double_arg x1, double_arg y1, + double_arg x2, double_arg y2, + double_arg xc, double_arg yc, + vr_bool ccw), + void (vroniObject::*EndOffsetLoopFuncPtr)( + void *output, + int num_offset_segs, + int num_offset_arcs, + double x0, double y0), + void (vroniObject::*EndOffsetsFuncPtr)( + void *output, + int num_offset_loops, + int num_offset_segs, + int num_offset_arcs)); + + + // + // INPUT GEOMETRY + // + + /* data.cc: */ + + int GetNumberOfPoints(void); + + int GetNumberOfSegments(void); + + int GetNumberOfArcs(void); + +#ifdef EXT_APPL_SITES + void AddSeg(int *i1, double_arg xc2, double_arg yc2, eas_type ext_appl); + + void AddArc(int *i1, double_arg xc3, double_arg yc3, + double_arg xc2, double_arg yc2, + int last_attr, eas_type ext_appl); +#else + void AddSeg(int *i1, double_arg xc2, double_arg yc2); + + void AddArc(int *i1, double_arg xc3, double_arg yc3, + double_arg xc2, double_arg yc2, + int last_attr); +#endif + +#ifdef EXT_APPL_SITES + void CloseSeg(int i1, int i2, eas_type ext_appl); + + void CloseArc(int i1, int i2, double_arg xc2, double_arg yc2, + int last_attr, eas_type ext_appl); +#else + void CloseSeg(int i1, int i2); + + void CloseArc(int i1, int i2, double_arg xc2, double_arg yc2, + int last_attr); +#endif + +#ifdef EXT_APPL_PNTS + int HandlePnt(double_arg xc1, double_arg yc1, eap_type ext_appl); + + eap_type GetExtApplPnt(int i); + + void SetExtApplPnt(int i, eap_type x); +#else + int HandlePnt(double_arg xc1, double_arg yc1); +#endif + +#ifdef EXT_APPL_SITES + void HandleSeg(double_arg xc1, double_arg yc1, + double_arg xc2, double_arg yc2, + eas_type ext_appl); + + void HandleArc(double_arg xc1, double_arg yc1, + double_arg xc2, double_arg yc2, + double_arg xc3, double_arg yc3, int attr, eas_type ext_appl); + + eas_type GetExtApplSeg(int s); + + void SetExtApplSeg(int s, eas_type t); + + eas_type GetExtApplArc(int s); + + void SetExtApplArc(int s, eas_type t); +#else + void HandleSeg(double_arg xc1, double_arg yc1, + double_arg xc2, double_arg yc2); + + void HandleArc(double_arg xc1, double_arg yc1, + double_arg xc2, double_arg yc2, + double_arg xc3, double_arg yc3, int attr); +#endif + + + // + // ACCESS VD NODES AND EDGES + // + + /* vd_basic.cc: */ + + vr_bool GetVDStatus(void); + + int GetNumberOfNodes(void); + + int GetNumberOfEdges(void); + + void InitStorageNodes(int number); + + void InitStorageEdges(int number); + + inline void IncrementVDIdentifier() { ++VD_identifier; } + + void PrintVDCounters(void); + + double ClassifySolSite(int i, t_site i_type, coord c, double r); + + + /* vddata.cc: */ + +#ifdef EXT_APPL_VD + ean_type GetExtApplNode(int i); + + void SetExtApplNode(int i, ean_type ext_appl); + + eae_type GetExtApplEdge(int i); + + void SetExtApplEdge(int i, eae_type ext_appl); +#endif + + /** Get first vertex of given site of given type */ + int Get1stVtx(int site, int type); + + /** Get second vertex of given site of given type */ + int Get2ndVtx(int site, int type); + + /** Get first vertex of given segment */ + int Get1stVtxSeg(int site); + + /** Get second vertex of given segment */ + int Get2ndVtxSeg(int site); + + /** Get first vertex of given arc */ + int Get1stVtxArc(int site); + + /** Get second vertex of given arc */ + int Get2ndVtxArc(int site); + + /** Set first vertex of site of given type to pnt */ + void Set1stVtx(int site, int type, int pnt); + + /** Set second vertex of site of given type to pnt */ + void Set2ndVtx(int site, int type, int pnt); + + /** Set first vertex of given segment */ + void Set1stVtxSeg(int site, int pnt); + + /** Set second vertex of given segment */ + void Set2ndVtxSeg(int site, int pnt); + + /** Set first vertex of given arc */ + void Set1stVtxArc(int site, int pnt); + + /** Set second vertex of given arc */ + void Set2ndVtxArc(int site, int pnt); + + /** Check whether point has been visited */ + vr_bool IsPntVisited(int site); + + /** Set whether point has been visited */ + void SetPntVisited(int site, vr_bool vis); + + /** Check if pnt is start point of seg */ + vr_bool IsSegStartPnt(int seg, int pnt); + + /** Check if pnt is send point of seg */ + vr_bool IsSegEndPnt(int seg, int pnt); + + /** Get coordinates of input point */ + coord GetPntCoords(int pnt); + + /** Set x-coordinate of point */ + void SetXCoord(int pnt, double_arg x); + + /** Set y-coordinate of point */ + void SetYCoord(int pnt, double_arg y); + + /** Get start point coordinates of seg */ + coord GetSegStartCoord(int seg); + + /** Get end point coordinates of seg */ + coord GetSegEndCoord(int seg); + + /** Get start point coordinates of arc */ + coord GetArcStartCoord(int arc); + + /** Get end point coordinates of arc */ + coord GetArcEndCoord(int arc); + + /** Get center point of arc a */ + coord GetArcCenter(int a); + + /** Get radius of arc a */ + double GetArcRadius(int a); + + /** Check whether p is start point of a */ + vr_bool IsArcStartPnt(int a, int p); + + /** Check whether p is end point of a */ + vr_bool IsArcEndPnt(int a, int p); + + /** Get original orientation of arc a + * Attention: within VRONI all arcs are oriented CCW! */ + vr_bool GetArcOrientation(int a); + + /** Set radius of arc a */ + void SetArcRadius(int a, double_arg r); + + /** Set center of arc a */ + void SetArcCenter(int a, coord p); + + /** Set orientation of arc a */ + void SetArcOrientation(int a, vr_bool ccw); + + /** Set normal vector of start point of arc a */ + void SetArcStartNormal(int a, coord ns); + + /** Set normal vector of end point of arc a */ + void SetArcEndNormal(int a, coord ne); + + /** Get normal vector of start point of arc a */ + coord GetArcStartNormal(int a); + + /** Get normal vector of end point of arc a */ + coord GetArcEndNormal(int a); + + /** Set chord equation coefficients of arc s to a, b, d */ + void SetChordEqnData(int s, double_arg a, + double_arg b, double_arg d); + + /** Get chord equation coefficients of arc s */ + void GetChordEqnData(int s, double* a, double* b, double* d); + + /** Set equation data of segment s */ + void SetSegEqnData(int s, double_arg a, + double_arg b, double_arg c); + + /** Get equation data of segment s */ + void GetSegEqnData(int s, double* a, double* b, double* c); + + /** Get normal vector of seg s */ + coord GetSegNormal(int s); + + /** Get unit vector from start point to end point of seg s */ + coord GetSegDirection(int s); + + /** Get length of segment s*/ + double GetSegLgth(int s); + + /** Set length of segment s */ + void SetSegLgth(int s, double_arg l); + + /** Check whether point p has incident site */ + vr_bool HasIncidentSite(int p); + + /** set incident site of point p */ + void SetIncidentSite(int p, int status); + + /** Check whether point p is to be deleted */ + vr_bool IsDeletedPnt(int p); + + /** Set whether point p is to be deleted */ + void SetDeletedPnt(int p, vr_bool del); + + /** Get node of point p */ + int GetPntNode(int p); + + /** Set node of point p */ + void SetPntNode(int p, int n); + + /** Set vd-pointer of point p */ + void SetPntVDPtr(int p, int e); + + /** Get vd-pointer of point p */ + int GetPntVDPtr(int p); + + /** Reset vd-pointer of point p */ + void ResetPntVDPtr(int p); + + /** Reset vd-pointer of segment s */ + void ResetSegVDPtr(int s); + + /** Set vd-pointer of site s of type t to e */ + void SetVDPtr(int s, int t, int e); + + /** Get vd-pointer of site s of type t */ + int GetVDPtr(int s, int t); + + /** Set start node of edge e to n */ + void SetStartNode(int e, int n); + + /** Set end node of edge e to n */ + void SetEndNode(int e, int n); + + /** Get start node of edge e */ + int GetStartNode(int e); + + /** Get end node of edge e */ + int GetEndNode(int e); + + /** Is n the start node of edge e? */ + vr_bool IsStartNode(int e, int n); + + /** Is n the end node of edge e? */ + vr_bool IsEndNode(int e, int n); + + /** Is edge e incident to node n? */ + vr_bool IsEdgeIncident(int e, int n); + + /** Get the opposite node to n at edge e */ + int GetOtherNode(int e, int n); + + /** Get site and type left to edge e */ + void GetLftSiteData(int e, int* s, t_site* t); + + /** Get site and type right to edge e */ + void GetRgtSiteData(int e, int* s, t_site* t); + + /** Get type of site left to edge e */ + t_site GetLftSiteType(int e); + + /** Get type of site right to edge e */ + t_site GetRgtSiteType(int e); + + /** Get site left to edge e */ + int GetLftSite(int e); + + /** Get site right to edge e */ + int GetRgtSite(int e); + + /** Given an edge e and a defining site s1 of type t1. + * Retrieve opposite site s2 and its type t2. */ + void GetOtherSiteData(int e, int s1, t_site t1, + int* s2, t_site* t2); + + /** Is node n a degree-2 node? */ + vr_bool IsDeg2Node(int n); + + /** Set is-degree-2 flag of node n */ + void SetNodeDegree(int n, vr_bool f); + + /** If site s of type t the left site of edge e? */ + vr_bool IsLftSite(int e, int s, t_site t); + + /** If site s of type t the right site of edge e? */ + vr_bool IsRgtSite(int e, int s, t_site t); + + /** Is site s of type t a left or right site of edge e? */ + vr_bool IsLftRgtSite(int e, int s, t_site t); + + /** Is left site of edge e the point s? + * Attention: We do not check for site type! */ + vr_bool IsLftPnt(int e, int s); + + /** Is right site of edge e the point s? + * Attention: We do not check for site type! */ + vr_bool IsRgtPnt(int e, int s); + + /** Get CCW edge of edge e at node n */ + int GetCCWEdge(int e, int n); + + /** Get CW edge of edge e at node n */ + int GetCWEdge(int e, int n); + + /** Set CCW edge of edge e at node n to e1 */ + void SetCCWEdge(int e, int n, int e1); + + /** Set CW edge of edge e at node n to e1 */ + void SetCWEdge(int e, int n, int e1); + + /** Reset CW edge of edge e at node n to e1 */ + void ResetCWEdge(int e, int n); + + /** Reset CCW edge of edge e at node n to e1 */ + void ResetCCWEdge(int e, int n); + + /** Get status of node n */ + n_status GetNodeStatus(int n); + + /** Set status of node n to s */ + void SetNodeStatus(int n, n_status s); + + /** Mark node n as deleted */ + void MarkNodeDeleted(int n); + + /** Mark node n as visited */ + void MarkNodeVisited(int n); + + /** Mark node n as unchecked */ + void MarkNodeUnchecked(int n); + + /** Mark node n as checked */ + void MarkNodeChecked(int n); + + /** Mark node n as dummy */ + void MarkNodeDummy(int n); + + /** Is node n marked as deleted? */ + vr_bool IsNodeDeleted(int n); + + /** Is node n marked as visited? */ + vr_bool IsNodeVisited(int n); + + /** Is node n marked as checked? */ + vr_bool IsNodeChecked(int n); + + /** Is node n marked as unchecked? */ + vr_bool IsNodeUnchecked(int n); + + /** Is node n marked as dummy? */ + vr_bool IsNodeDummy(int n); + + /** Mark edge e as deleted */ + void MarkEdgeDeleted(int e); + + /** Is edge e marked as deleted? */ + vr_bool IsEdgeDeleted(int e); + + /** Is this edge not marked as deleted and has non-NIL left and right sites? */ + vr_bool IsEdgeActive(int e); + + /** Is this edge e a genuine edge? That is, edge e is active (IsEdgeActive) and + * if left or right sites are points, then the indices of the points are + * greater (resp. less) than minidx (resp. maxidx) */ + vr_bool IsEdgeGenuine(int e, int minidx, int maxidx); + + /** Get coordinates of node n */ + coord GetNodeCoord(int n); + + /** Get parameter (clearance [squared]) of node n */ + double GetNodeParam(int n); + + /** Get coordinate and parameter of node n */ + void GetNodeData(int n, coord* p, double* r); + + /** Get parameter of start and end node of edge e */ + void GetEdgeParam(int e, double* rs, double *re); + + /** Get an edge incident to node n */ + int GetIncidentEdge(int n); + + /** Set the edge-pointer of node n to e */ + void SetIncidentEdge(int n, int e); + + /** Get a site where node n belongs to */ + int GetNodeSite(int n); + + /** Set site-pointer of node n to s */ + void SetNodeSite(int n, int s); + + /** Update node n of edge e to node n0 */ + void UpdateNodeEdgeData(int e, int n, int n0); + + /** Consider edges and nodes e1-n1-e0-n2-e2 in CW order. Set cw and ccw + * pointers of e0 to e1, e2, GetCWEdge(e1,n1), GetCCWEdge(e2,n2) and vice + * versa. */ + void CloseVoronoiCell(int e1, int e0, int e2, int n1, int n2); + + /** Copy segment s1 to segment s */ + void CopySegData(int s, int s1); + + /** Copy arc s1 to arc s */ + void CopyArcData(int s, int s1); + +#ifdef WRITE_VD + void SetVDEdge(int s, int t, int e); + int GetVDEdge(int s, int t); + void SetPntIndex(int i, int n); + int GetPntIndex(int i); + void SetNodeIndex(int i, int n); + int GetNodeIndex(int i); +#endif + +#ifdef ORDERED + /** Set key of site s of type t to n */ + void SetSiteNumber(int s, t_site t, int n); + + /** Get key of site s of type n */ + int GetSiteNumber(int s, t_site t); +#endif + + /* from basic.h */ + inline double ScaleX(double xc) { + return (scale_factor * (xc - shift.x)); + } + inline double ScaleY(double yc) { + return (scale_factor * (yc - shift.y)); } + inline double ScaleV(double value) { + return (value * scale_factor); } + inline double UnscaleX(double xc) { + assert(scale_factor > 0.0); + return (xc / scale_factor + shift.x); + } + inline double UnscaleY(double yc) { + assert(scale_factor > 0.0); + return (yc / scale_factor + shift.y); + } + inline double UnscaleV(double value) { + assert(scale_factor > 0.0); + return (value / scale_factor); + } + + void SetRootTooLarge(double_arg t); + +#ifdef VRONI_INFO + void InitRelaxationMemory(double_arg t); + void UpdateRelaxationMemory(double_arg t); + void ConfirmRelaxationMemory(); + double ReportRelaxationMemory(); +#endif + + + // + // BISECTOR COORDINATE EVALUATION + // + + /* offset.cc */ + + void EvaluateBisectorData(int i, double_arg t, coord *w); + + + + protected: + + // + // PROTECTED VARIABLES (i.e. accessible by derived classes) + // + + /* io_debug.cc: */ +#ifdef TRACE + coord clip_min; + coord clip_max; +#endif + + /* driver.cc */ + vr_bool save_data; + vr_bool read_poly; + vr_bool read_polygon; + vr_bool read_sites; + vr_bool read_xdr; + vr_bool read_graphml; + vr_bool read_polylines; + vr_bool read_e00; + vr_bool read_usgs; + vr_bool read_dxf; + vr_bool read_pnts; + vr_bool read_file; + vr_bool write_ipe; + vr_bool write_vd_dt; + vr_bool help; + vr_bool time_it; + vr_bool print_copy; + vr_bool discard_dupl_s; + vr_bool write_off; + vr_bool auto_offset; + vr_bool left_offset; + vr_bool right_offset; + vr_bool compute_wmat; + vr_bool auto_wmat; + vr_bool pnts_only; + vr_bool compute_mic; + vr_bool dxf_format; + vr_bool write_ma; + vr_bool clean_up; + vr_bool new_input; + vr_bool write_vd; + vr_bool left_vd; + vr_bool right_vd; + vr_bool vr_incr; + + FILE *vr_file_handle; + + int driver_step_size; + int p_step_size; + int o_step_size; + int a_step_size; + int sample; + int bound; + int approx; + int io_flag; + int inputprec; + int mpfr_prec; + int vr_seed; + + double t_offset; + double d_offset; + double wmat_angle; + double wmat_dist; + double vd_apx_dist; + + char vd_file[256]; + char input_file[256]; + char output_file[256]; + char off_file[256]; + char vd_dt_file[256]; + char ma_file[256]; + char vr_file[256]; + +#if defined (OGL_GRAPHICS) + vr_bool off_init; + vr_bool data_read; + vr_bool finished; + vr_bool off_finished; + vr_bool computed; + vr_bool wmat_computed; + vr_bool mic_computed; + vr_bool vd_output; + vr_bool first_input; + int first_pnt; + int last_pnt; + int new_pnts; +#ifdef TRACE + double xc2, yc2; +#endif +#ifdef API_PARABOLIC + int count_pnts; + coord p1, p2; + double t1, t2; +#endif +#endif + + /* redraw.cc */ +#ifdef GRAPHICS + + typedef struct + { + int index; /* index of a pnt, seg, arc or node of the VD */ + int color; /* color information; see defs.h */ + } buffer; /* generic buffer type for drawing objects. */ + /* the index is the array index of the object */ + /* referenced; see data.cc (for pnt, seg, arc) */ + /* and vd.cc (for vdn). */ + + buffer *pnt_buf; + buffer *seg_buf; + buffer *arc_buf; + buffer *vdn_buf; + + int num_pnt_buf, max_num_pnt_buf; + int num_seg_buf, max_num_seg_buf; + int num_arc_buf, max_num_arc_buf; + int num_vdn_buf, max_num_vdn_buf; + + struct vde_buffer + { + coord p1; /* (x,y) coords of start point of a line seg */ + coord p2; /* (x,y) coords of end point of a line seg */ + int color; /* color information; see defs.h */ + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline vde_buffer() {} + }; /* buffer for drawing edges of the VD */ + + vronivector vde_buf; + int num_vde_buf, max_num_vde_buf; + + struct off_buffer + { + coord p1; /* (x,y) coords of start point */ + coord p2; /* (x,y) coords of end point */ + coord p3; /* (x,y) coords of center (for an arc) */ + double r; /* radius (for an arc) */ + vr_bool ccw; /* orientation (for an arc) */ + int color; /* color information; see defs.h */ + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline off_buffer() {} + }; /* buffer for drawing offset arcs and segs */ + + vronivector off_buf; + int num_off_buf, max_num_off_buf; + + + typedef struct + { + int index; /* index of an object (pnt, seg, ... ) */ + t_site type; /* type of the object; see defs.h */ + int color; /* color information; see defs.h */ + } cur_buffer; /* buffer for drawing "current" objects; used */ + /* if the code is in "step mode" */ + + cur_buffer *cur_buf = (cur_buffer*)NULL; + int num_cur_buf, max_num_cur_buf; + + struct cir_buffer + { + coord cntr; /* center of a circle */ + double radius; /* radius of a circle */ + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline cir_buffer() {} + }; + + vronivector cir_buf; + int num_cir_buf, max_num_cir_buf; +#endif + + /* api_functions.cc */ +#ifdef GRAPHICS + vr_bool graphics; + vr_bool draw_pnts; + vr_bool draw_segs; + vr_bool draw_off; + vr_bool draw_arcs; + vr_bool draw_vde; + vr_bool draw_vdn; + vr_bool draw_dte; + vr_bool draw_mat; + vr_bool draw_mic; +#endif + + /* data_off.cc */ + STACK_TYPE *stack; + STACK_TYPE num_stack; + STACK_TYPE max_num_stack; + + vronivector edge_data; + int num_edge_data; + int max_num_edge_data; + + e_flag *edge_flags; + int num_edge_flags; + int max_num_edge_flags; + + int *active_edges; + int num_active_edges; + int max_num_active_edges; + + int min_pnt_ind; + int max_pnt_ind; + + vr_bool e_data_init; + + int data_off_VD_ID; + + /* mic.cc */ + vr_bool MIC_computed; + + /* offset.cc */ + vronivector offset_list; + int num_offset_list; + int max_num_offset_list; + + vronivector offset_data; + int num_offset_data; + int max_num_offset_data; + + int cur_offset_list; + + double max_t_offset; + +#ifdef VISUAL_TEST_OFFSETS + vr_bool small_increment; +#endif + + vr_bool unscaleXYZ; + + double t; + double d_off; + vr_bool data_written; + int offset_VD_ID; + + /* wmat.cc */ + vr_bool WMAT_computed; + + // + // PROTECTED FUNCTIONS (i.e. accessible by derived classes) + // + + void VD_Dbg_Warning(const char* VD_Warning_String) + { +#ifdef VRONI_DBG_WARN + fflush(stdout); + fprintf(stdout, "\nwarning in %s\n", VD_Warning_String); + fflush(stdout); +#endif + ExtApplFuncVD_Dbg_Warning; + } + void VD_IO_Warning(const char* VD_Warning_String) + { + io_troubles = true; +#ifdef VRONI_IO_WARN + if (verbose) { + fflush(stdout); + fprintf(stdout, "\nI/O warning in %s\n", VD_Warning_String); + fflush(stdout); + } +#endif + ExtApplFuncVD_IO_Warning; + } + + + void VD_Warning(const char* VD_Warning_String) + { +#ifdef VRONI_WARN + if (!quiet) { + fflush(stdout); + fprintf(stdout, "\nwarning in %s\n", VD_Warning_String); + fflush(stdout); + } +#endif + ExtApplFuncVD_Warning; + } + + void VD_Info(const char* VD_Info_String) + { +#ifdef VRONI_INFO + if (verbose && !quiet) { + fflush(stdout); + fprintf(stdout, "%s", VD_Info_String); + fflush(stdout); + } +#endif + ExtApplFuncVD_Info; + } + + + /* compute.cc: */ + + void ComputeVD(vr_bool save_data, vr_bool new_input, int step_size, + vr_bool time, int bound, int sample, int approx, + char output_file[], vr_bool discard_duplicate_sites, + int p_step_size, vr_bool *finished, int a_step_size, + vr_bool pnts_only, vr_bool write_vd, + char vd_dt_file[], vr_bool left_vd, vr_bool right_vd, + vr_bool clean_up); + + + /* memory.cc: */ + + void *ReallocateArray(void *old_ptr, int number, size_t size, + char const *var_name); + + void FreeMemory(void **ptr, char const *var_name); + +#ifdef DEBUG_MEMORY + vr_bool IndexOutOfBounds(void *array_ptr, char const *var_name, + size_t size, int index); +#endif + + unsigned long ReportMaxNumberBytes(void); + + unsigned long ReportCurrNumberBytes(void); + + vr_bool AllMemoryFreed(); + + + /* data.cc: */ + + void ExtendPnts(int number); + + vr_bool GetSupportVtxFlag(void); + + void SetSupportVtxFlag(vr_bool flag); + + void CheckIsolatedPnts(void); + + void PrintSiteData(int s, t_site t, const char *string); + + void FindClosestSeg(double_arg xl, double_arg yl); + + void FindClosestPnt(double_arg xl, double_arg yl); + + void InitSiteOrder(t_site type); + + int GetNextSite(void); + + void RemoveSegment(int i); + + void RemoveArc(int i); + + void SplitSegmentIntoHalves(int i1); + + int SplitSeg(int i1, int i2); + + int SplitArc(int i1, int i2); + + void MergePoints(int i1, int i2); + + void ResetFlags(void); + + void MarkDrawSite(int i, t_site type); + + void ResetDrawSite(int i, t_site type); + + void ResetInputData(void); + + void FreeInputData(); + +#ifdef EXT_APPL_PNTS + void InitPntSite(pnt *pointer, double_arg x, double_arg y, + eap_type ext_appl); +#else + void InitPntSite(pnt *pointer, double_arg x, double_arg y); +#endif + +#ifdef EXT_APPL_PNTS + int StorePnt(double_arg x, double_arg y, eap_type ext_appl); +#else + int StorePnt(double_arg x, double_arg y); +#endif + +#ifdef EXT_APPL_SITES + int StoreSeg(int i1, int i2, eas_type ext_appl); + + int StoreArc(int i1, int i2, double_arg xc, double_arg yc, vr_bool ccw, + eas_type ext_appl); +#else + int StoreSeg(int i1, int i2); + + int StoreArc(int i1, int i2, double_arg xc, double_arg yc, vr_bool ccw); +#endif + + void InitPnts(int number); + + void InitSegs(int number); + + void InitArcs(int number); + + void SetBoundingBox(void); + + void CheckBoundingBox(void); + + void AddDummyCorners(int bound); + + vr_bool InPntsList(int index); + + vr_bool InSegsList(int index); + + vr_bool InArcsList(int index); + + void InitStoragePnts(int number); + + void InitStorageSegs(int number); + + void InitStorageArcs(int number); + + void ScaleData(void); + + void ResizePnts(int number); + + void DXFStartPoly(); + + void DXFClosePoly(double bulge); + + void DXFAddPolyVertex(double_arg xc1, double_arg yc1, double bulge); + + + /* redraw.cc: */ + +#ifdef GRAPHICS + void AddNodeToBuffer(int index, int color); + void AddPntToBuffer(int index, int color); + void AddSegToBuffer(int index, int color); + void AddArcToBuffer(int index, int color1); + void AddToCurBuffer(int index, t_site type, int color); + void FreeDrawingBuffer(void); + void ResetBufferData(void); + void ResetOffsetBuffer(void); + void ResetCurBuffer(void); + void ResetVDBuffer(void); + void UpdateBuffer(void); + void AddEdgeToBuffer(double_arg x1, double_arg y1, + double_arg x2, double_arg y2, int color); + void AddCirToBuffer(coord cntr, double_arg radius); + void WriteIpeOutput(char *filename); + void AddOffToBuffer(double_arg x1, double_arg y1, + double_arg x2, double_arg y2, + double_arg x3, double_arg y3, + double_arg r, vr_bool ccw, int color); +#ifdef OGL_GRAPHICS + void BuffToDrawArc(int j, int color); + void BuffToDrawSeg(int j, int color); + void Redraw(void); +#endif // OGL_GRAPHICS +#endif + + + /* graphics_ogl.cc */ + +#ifdef GRAPHICS +#ifdef OGL_GRAPHICS + void ResetGraphicsData(void); + void UpdateScaleData(void); + void DrawSeg(coord pnt1, coord pnt2, int color); + void DrawPnt(coord pnt, int color, vr_bool large_radius); + void DrawArc(coord pnt1, coord pnt2, coord pnt3, double radius, int color); + void DrawText(coord pos, int color, const char* fmt, ...); + void DrawCircle(coord pnt3, double radius, int color); + void ResetRubberLine(void); + void FlushDisplay(void); +#endif // OGL_GRAPHICS +#endif + + + /* driver.cc: */ + + void HandleWriteVDOutput(void); + + void ParseCommandLineArgs(int argc, char *argv[], vr_bool *graphics, + vr_bool *color_graphics, vr_bool *full_screen); + + void GetInputData(vr_bool *input_received); + + void ProceedWithoutGraphics(vr_bool input_received); + + void HandleComputeVD(void); + + void ClosePolygon(void); + + void StartNewPolygon(void); + + void AddPolygonVertex(double_arg xc1, double_arg yc1); + + void ResetOnlineGraphicsData(void); + + void ResetDriverData(void); + + + /* io_basic.cc: */ + + void ReadBDM(char input_file[], vr_bool *new_input); + + void ReadPolylines(char input_file[], vr_bool *new_input); + + void ReadSites(char input_file[], vr_bool *new_input); + + void ReadContour(FILE *input); + + void ReadPolygon(char input_file[], vr_bool *new_input); + + void ReadPoly(char input_file[], vr_bool *new_input); + + void ReadPoints(char input_file[], vr_bool *new_input); + + FILE *OpenFileVD(const char *file_name, const char *access); + + + /* io_debug.cc: */ + + void WriteSites(const char *output_file); + +#ifdef TRACE + + void WriteSiteData(int j, t_site type, const char* qual_string); + + void WriteProcessedSites(const char *output_file); + + void ClipWriteSiteData(int j, t_site type, const char *output_file); + + void ExportClipWindow(double_arg x1, double_arg y1, + double_arg x2, double_arg y2); + + void WriteDisplayedSites(double_arg xmin, double_arg ymin, + double_arg xmax, double_arg ymax, + const char *output_file); + +#endif + + + /* io_dxf.cc: */ + + void ReadDXFFile(char input_file[], vr_bool *new_input); + + void WriteDXFLWPoly_Vertex(FILE *dxf_file, double_arg xc1, + double_arg yc1, double_arg bulge); + + void WriteDXFLWPoly_Start(FILE *dxf_file, vr_bool closed, int color); + + void WriteDXFPoly_Vertex(FILE *dxf_file, double_arg xc1, double_arg yc1, + double_arg bulge); + + void WriteDXFPoly_Start(FILE *dxf_file, vr_bool closed, int color); + + void WriteDXFArc(FILE *dxf_file, double_arg xc1, double_arg yc1, + double_arg xc2, double_arg yc2, + double_arg xc3, double_arg yc3, vr_bool ccw_flag, + int color); + + void WriteDXFCircle(FILE *dxf_file, double_arg xc1, double_arg yc1, + double_arg radius, int color); + + void WriteDXFPoint(FILE *dxf_file, double_arg xc1, double_arg yc1, + int color); + + void WriteDXFLine(FILE *dxf_file, double_arg xc1, double_arg yc1, + double_arg xc2, double_arg yc2, int color); + + void WriteDXFEntity(FILE *dxf_file, int color); + + void StartDXFFile(FILE *dxf_file); + + void FinishDXFFile(FILE *dxf_file); + + void WriteDXFPoly_End(FILE *dxf_file); + + + /* io_help.cc: */ + + void Copyright(void); + + void Help(void); + + void PrintVarValue(FILE *output, void *v, char const *var_name, my_types t); + + + /* io_misc.cc: */ + + void SkipText(FILE *in_file, char ch); + + char ParseText(FILE *in_file, char ch1, char ch2); + + vr_bool FindText(FILE *in_file, char ch); + + void HandleBlock(FILE *in_file); + + void ReadXDRFile(char input_file[], vr_bool *new_input); + + vr_bool ReadGraphMLNode(FILE *input); + + vr_bool ReadGraphMLEdge(FILE *input); + + void ReadGraphML(char input_file[], vr_bool *new_input); + + void ReadE00File(char input_file[], vr_bool *new_input); + + void ReadUSGS(char input_file[], vr_bool *new_input); + + void AddXMLseg(int *i1, double_arg xt, double_arg yt, + double_arg xc, double_arg yc, double_arg r, char type, + int i0); + + vr_bool ReadIpePath(FILE *input); + + vr_bool ReadIpeMark(FILE *input); + + void ReadXML(char input_file[], vr_bool *new_input); + + + /* io_other.cc: */ + + void WriteCgalSites(char output_file[]); + + + /* io_vddt.cc: */ + + void WriteVoronoiRegion(int i, FILE *output); + + void WriteVDDT(char output_file[]); + + + /* io_parse.cc: */ + + vr_bool ReadOptionalNumber(FILE *input, int *data); + + vr_bool ReadOptionalCoord(FILE *input, double *xy); + + vr_bool ReadNumber(FILE *input, int *data); + +#ifdef EXT_APPL_PNTS + vr_bool ReadPntData(FILE *input, double *xc, double *yc, + eap_type *eap_data); +#else + vr_bool ReadPntData(FILE *input, double *xc, double *yc); +#endif +#ifdef EXT_APPL_SITES + vr_bool ReadSiteData(FILE *input, double *xc, double *yc, + eas_type *eas_data); +#else + vr_bool ReadSiteData(FILE *input, double *xc, double *yc); +#endif + vr_bool ReadVectorData(FILE *input, double *xc, double *yc); +#ifdef EXT_APPL_PNTS + void WritePntData(FILE *output, double_arg xc, double_arg yc, + eap_type *eap_data); +#else + void WritePntData(FILE *output, double_arg xc, double_arg yc); +#endif + short fSeeks(FILE *input, const char *strings[], short nbr); + + /* arg_eval.cc: */ + + vr_bool ArgEval(int argc, char *argv[], vr_bool *color_graphics, + vr_bool *graphics, vr_bool *save_data, char *output_file, + vr_bool *read_input, char *input_file, vr_bool *read_poly, + int *step_size, vr_bool *verbose, vr_bool *write_ipe, + vr_bool *help, vr_bool *time, vr_bool *statistics, + vr_bool *copy, vr_bool *quiet, int *bound, int *sample, + vr_bool *scale, int *approx, vr_bool *read_sites, + vr_bool *read_xdr, vr_bool *read_graphml, + vr_bool *discard_dupl_s, + int *p_step_size, vr_bool *read_e00, vr_bool *read_dxf, + vr_bool *read_polylines, double *t_offset, double *d_offset, + vr_bool *write_off, char *off_file, int *o_step_size, + vr_bool *auto_offset, vr_bool *full_screen, + vr_bool *read_usgs, vr_bool *left_offset, + vr_bool *right_offset, vr_bool *compute_wmat, + double *wmat_angle, double *wmat_dist, vr_bool *auto_wmat, + vr_bool *pnts_only, vr_bool *compute_mic, int *a_step_size, + vr_bool *check_data, + vr_bool *write_vd_dt, char *vd_dt_file, vr_bool *read_pnts, + vr_bool *dxf_format, vr_bool *read_file, + vr_bool *write_ma, char *ma_file, vr_bool *clean_up, + vr_bool *write_vd, char *vd_file, double *vd_apx_dist, + vr_bool *left_vd, vr_bool *right_vd, + vr_bool *vr_incr, char *vr_file, + int *inputprec, int *mpfr_prec, int *vr_seed); + + void EvalError(void); + + + /* clean_data.cc: */ + + void CleanData(int *removed, int *removed_segs, int *removed_arcs, + vr_bool discard_duplicate_sites); + + void RepairPntLinks(int i_del, int i_old, vr_bool repair_now); + + void FreeReverseIndex(void); + + vr_bool GetDataSorted(void); + + void ResetCleanStatus(void); + + + /* prepro.cc: */ + + void AddSupportVertices(void); + + void RemoveSupportVertices(void); + + void SetPreprocessingThreshold(double_arg threshold); + + void ExtendBoundingBox(void); + + void PreprocessSegments(int *num_critical_segs); + + void PreprocessArcs(int *num_critical_arcs); + + void AdjustArcs(int *num_critical_arcs); + + void HandleBulge(const coord & p1, const coord & p2, double *bulge, + coord *center, double *radius, int *attr); + + void ComputeBulge(const coord & p1, const coord & p2, double *bulge, + const coord & center, double_arg radius, int attr); + + void ReplaceArc(int i); + + void ReplaceSeg(int i); + + + /* approx.cc: */ + + void ApproxArcsHeuristic(int approx); + + void ApproxArcsBounded(double arc_absolute, double arc_relative); + + void SampleData(int sample); + + + /* numerics.cc: */ + + double PntSiteConeClassificator(int i, t_site ti, coord q1, coord q2, + const coord & q, double eps); + +#ifdef WITH_MPFRBACKEND + void set_mpfrbackend_prec(mpfr_prec_t mpfr_prec, vr_bool verbose); +#endif + + double ComputeSiteDistance(int i, t_site ti, const coord & p); + + vr_bool IntersectRayOffsetSeg(const coord & p, const coord & v, + double_arg a, double_arg b, double_arg c, + int k1, int k2, coord *centers, double *radii, + int *num_solutions); + + vr_bool SegSegBisector(int i, int j, double_arg ai, double_arg bi, + double_arg aj, double_arg bj, double_arg cj, coord *P, coord *V); + + + vr_bool IterativeIntersection(t_site type1, t_site type2, /* object types */ + double_arg a, double_arg b, double_arg c, /* line 1 */ + const coord & c1, double_arg r1, /* circle 1 */ + const coord & p2, /* start point or center of obj 2 */ + double t_s, double t_e, /* parameters of obj 2 */ + const coord & v2, /* direction vector of seg 2 */ + double_arg r2, /* radius of arc 2 */ + double *t_q, coord *q); + + + /* vd_basic.cc: */ + + int ClassifySolutions(int i, int j, int k, int e, + t_site i_type, t_site j_type, t_site k_type, + vr_bool i_orig, vr_bool j_orig, vr_bool k_orig, + coord *centers, double *radii, int *num_sol, + double eps, vr_bool *problematic); + + vr_bool IntersectRayBisector(int i1, const coord & v, int e, coord *w, + double *r2); + + void SetDeg2Flag(void); + + vr_bool GetDeg2Flag(void); + + void SetNodesSqdFlag(); + + vr_bool GetNodesSqdFlag(void); + +#ifdef GRAPHICS + void FindClosestNode(double_arg xl, double_arg yl); +#endif + + int GetVDIdentifier(void); + + void SetVDStatusTrue(void); + + void ResetVDStatus(void); + + void TakeSquareOfNodes(void); + + void InsertDummyNode(int e, int n, vr_bool store); + + void DeleteDummyNodes(void); + + void DeleteNode(int n); + + void DeleteEdge(int e); + + vr_bool CheckVD(vr_bool arcs_recovered); + + vr_bool InEdgesList(int index); + + vr_bool InNodesList(int index); + + int StoreNode(double_arg x, double_arg y, double_arg r2); + + void InitNodes(int number); + + int StoreEdge(int n1, int n2, int lft, int rgt, t_site ltype, t_site rtype); + + void InitEdges(int number); + + void FreeVDData(); + + void ResetVDData(void); + + void ComputeInitialVD(void); + +#ifdef GRAPHICS + void AddVDEdgeToBuffer(int i); + void AddVDToBuffer(vr_bool left_vd, vr_bool right_vd); + void AddDelToBuffer(void); + vr_bool CheckVDCell(int i, int e0, t_site t, vr_bool arcs_recovered); +#endif + + void PrintNodeData(int n, const char *string); + + void PrintEdgeData(int e, const char *string); + + void PrintVDData(const char *string); + + + /* vd_arc.cc: */ + + vr_bool IsSameSide(int i, t_site t, int j, int i1, coord p_node); + + void FindMostViolatedRecursiveArc(int e, int k0, int i1, int j, int k, + int *n, double *dist); + + int FindMostViolatedNodeArc(int i1, int i2, int j, vr_bool *node_shared); + + void GetPntSiteNormal(int i, t_site site, coord p, coord* v, double* dist); + + void ProjectPntOnSite(int i, t_site site, coord p, coord* w); + + vr_bool PreserveVoronoiCellArc(int i, t_site t, int i0); + + vr_bool BreakLoopArc(int i0); + + void MarkNonRecursiveArc(int e, int n, int i, + std::stack& e_stack, + std::stack& n_stack, + std::stack& i_stack); + + void MarkRecursiveArc(int e, int n, int i); + + void InsertArcIntoVD(int i); + + + /* vd_data.cc: */ + +#ifdef TRACE + unsigned long GetThresholdCounter(void); +#endif + + void SetDebugFlagVD(vr_bool dbg_flag); + + void ResetLoopStackSize(int size); + void ResetLoopStackMin(int size); + void ResetLoopStack(); + void GetLoopStackSize(int& size); + void GetLoopStackMin(int& size); + + int GetLoopStackSizeFunc(void); + + int GetLoopStackMinFunc(void); + + int GetLoopStackElementFunc(int I); + + void FreeVDConstructionData(void); + + void ResetVDConstructionData(void); + + void UpdateRecursive(int i, t_site t, int n, int e, + int *el, int *er, int *nl, int *nr); + + void ResetTreeDeleteStatus(int e, int n); + + void InsertApexDegreeTwoNodeSeg(int e, int i, int i1, t_site t1); + + void InsertApexDegreeTwoNodeArc(int e, int i, int i1, t_site t1); + + void ResetNodeStatus(int e, int n); + + void PurifyLoop(int n1, int n3); + + vr_bool LoopExists(int e, int n, int *m); + + vr_bool ComputeCenter(int e, int i3, t_site t3, coord *w, double *r2, + vr_bool *problematic, int *site); + + + /* vd_pnt.cc: */ + + int FindMostViolatedNodePnt(int i, coord p); + + void UpdateRecursivePnt(int i, int n, int e, + int *el, int *er, int *nl, int *nr); + + void InsertPntIntoVD(int i); + + + /* vd_seg.cc: */ + + void FindMostViolatedRecursiveSeg(int e, /* current VD edge */ + int k0, /* start node of recursive scan */ + int i1, /* pnt that coincides with k0 */ + int j,/* segment to be inserted into VD */ + int k, /* current node */ + int *n, /* closest node found by scan */ + double *dist); /* distance of node n */ + + int FindMostViolatedNodeSeg(int i1, /* start point of seg */ + int i2, /* end point of seg */ + int j, /* segment to be inserted into VD */ + vr_bool *node_shared, + double *diff); + + vr_bool PreserveVoronoiCellSeg(int i, t_site t, int i0); + + vr_bool BreakLoopSeg(int i0); + + void MarkNonRecursiveSeg(int e, int n, int i, + std::stack& e_stack, + std::stack& n_stack, + std::stack& i_stack); + + void MarkRecursiveSeg(int e, int n, int i); + + void InsertSegIntoVD(int i); + + + /* tree.cc: */ + + void FreeTree(void); + + int InitTree(int number, int *first_N_points, int N_Initial, double *min_dist); + + int InsertPntIntoTree(int ind, double *dist_min, vr_bool no_distance); + + vr_bool InTree(int idx); + +#ifdef GRAPHICS + void DrawTree(void); +#endif + + + /* grid.cc: */ + + void DeletePntFromGrid(int index); + + void FreeGrid(void); + + void SetUpGrid(int number); + + void BuildGrid(void); + + void InitGrid(void); + + vr_bool InGrid(int cell); + + void InitRaster(void); + + void InitPntList(int number); + +#ifdef GRAPHICS + void DrawCell(int i, int j); + void DrawGrid(void); +#endif + + int InsertPntIntoGrid(int index, double *min_dist); + + int FindNearestNeighborGrid(int index, int i_min, double *min_dist); + + + /* pnt_pnt_pnt.cc: */ + + vr_bool PntPntPntCntr(int i, int j, int k, coord *ctr, double *radius); + + vr_bool NumericalPntPntPntCntr(const coord & A, const coord & B, const coord & C, + coord *cntr, double *r2); + + /* seg_pnt_pnt.cc: */ + + vr_bool SegPntPntCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic); + + vr_bool SegPntCntr(int i, coord p, coord *cntr, double *r2); + + /* seg_seg_pnt.cc: */ + + vr_bool SegSegPntCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic, int *site); + + /* seg_seg_seg.cc: */ + + vr_bool SegSegSegCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic, int *site); + + /* arc_arc_arc.cc: */ + + vr_bool ArcArcArcCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic, int* site); + + /* arc_arc_pnt.cc: */ + + vr_bool ArcArcPntCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic, int* site); + + /* arc_pnt_pnt.cc: */ + + vr_bool ArcPntPntCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic); + + /* arc_arc_seg.cc: */ + + vr_bool ArcArcSegCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic, int* site); + + /* arc_seg_pnt.cc: */ + + vr_bool ArcSegPntCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic, int* site); + + /* arc_seg_seg.cc: */ + + vr_bool ArcSegSegCntr(int i, int j, int k, int e, coord *cntr, double *r2, + vr_bool *problematic, int* site); + + /* arc_common.cc: */ + + int ArcRoots2abc(double a, double b, double c, double* roots); + + /* misc.cc: */ + + void ResetIntersectionData(void); + +#ifndef API_PARABOLIC + void AddParabolaToBuffer(int i, double t1, double t2, coord u, coord v, + int color); +#endif + +#ifdef GENUINE_ARCS + void AddHyperbolaEllipseToBuffer(int i, double t1, double t2, + coord u, coord v, int color); +#endif + + double NodeRadiiClassificator(int e, coord p); + + double NodeSegClassificator(int i, coord p); + + double NodeSidednessClassificator(int i, t_site ti, /* old site */ + const coord & q, /* old node */ + const coord & p); /* new node */ + + double NodeEdgeClassificator(int e, const coord & p, double eps); + + void SplitAtIntersection(int i1, int i2, t_site t1, t_site t2, coord w); + + vr_bool IsPntOnPnt(int i1, int i2, double eps); + + vr_bool IsPntOnSeg(int i1, int i2, double eps); + +#ifdef GENUINE_ARCS + vr_bool IsPntOnArc(int i1, int i2, double eps); +#endif + + vr_bool IsSegSegIntersection(int i1, int i2, double eps); + +#ifdef GENUINE_ARCS + vr_bool IsSegArcIntersection(int i1, int i2, double eps); + + vr_bool IsArcArcIntersection(int i1, int i2, double eps); +#endif + + void SetStepSize(double_arg delta); + + void InsertDegreeTwoNodes(void); + + vr_bool IsInvalidData(vr_bool critical); + + void CheckDataPnt(int *int_found); + + void CheckDataSeg(int *int_found); + + void CheckDataArc(int *int_found); + + void SubdivideLongEdges(void); + + void SetInvalidSites(int i1, t_site t1, int i2, t_site t2, double eps); + + double ClassifySolPnt(int i, const coord & p, double_arg clear); + + double ClassifySolSeg(int i, const coord & p, double_arg clear); + + double ClassifySolArc(int i, const coord & p, double_arg clear); + + + /* api_parabolic.cc */ + +#ifdef API_PARABOLIC + void ApproxParabolicVDEdge(int i, double t, double apx_eps, + int *num_apx_pnts, coord **apx_pnts); + + void AddParabolaToBuffer(int i, double t1, double t2, coord u, coord v, + int color); + + void SegCircleIntersection(coord p_start, coord p_end, double t_start, + double t_end, coord center, double radius, + int *num_pnts, coord *p1, coord *p2, + double *t1, double *t2); + + void ParCircleIntersection(int i, coord center, double radius, + int *num_pnts, coord *p1, coord *p2, + double *t1, double *t2); + + void VDEdgeCircleIntersection(int i, coord center, double radius, + int *num_pnts, coord *p1, coord *p2, + double *t1, double *t2); + + void DoCircleIntersections(int number); + + void API_ParabolicStatistics(); +#endif + + + /* desperate.cc: */ + + vr_bool DesperatePntPntPntCntr(const coord & A, const coord & B, + const coord & C, coord *cntr, double *r2); + + void DesperateSampleEdge(int e, int i, t_site t, coord *w, double *r2); + + void DesperateComputeCenter(int e, int i, t_site t, coord *w, double *r2); + + int DesperateFindMostViolatedNodeSeg(int i1, int j); + + void DesperatePreserveVoronoiCellSeg(int i, t_site t, int i0); + + void DesperateBreakLoopSeg(int i0); + + int DesperateFindMostViolatedNodeArc(int i1, int j); + + void DesperatePreserveVoronoiCellArc(int i, t_site t, int i0); + + void DesperateBreakLoopArc(int i0); + + + /* data_off.cc: */ + + void RecApxVDEdge(int e, double delta, coord3D **active_pnts, + int *num_active_pnts, int *max_num_active_pnts, + coord p1, coord p2, double t1, double t2); + + void ScanVDCell(int e, int i, t_site type, FILE *fp); + + void ApproximateVDEdge(int e, double delta, coord3D **active_pnts, + int *num_active_pnts, int *max_num_active_pnts); + + void StoreActivePnt(coord3D **active_pnts, int *num_active_pnts, + int *max_num_active_pnts, int i, + vr_bool isPnt); + + void StoreActiveEdge(int e); + + vr_bool InEdgeDataList(int i); + + vr_bool InEdgeFlagList(int i); + + vr_bool InActiveEdgeList(int i); + + vr_bool IsCorrectSide(int i, int type, int n, vr_bool left_offset); + + void ScanVDEdges(int e, int n, vr_bool offset_side, vr_bool compute_mic, + int *max_edge, double *max_rad); + + void InitializeEdgeData(vr_bool unrestricted, vr_bool left_offset, + vr_bool compute_mic, int *mic_edge); + + void FreeEdgeData(void); + + vr_bool ComputeParabolaData(int i, e_formula *coeff); + + void CreateParabolaData(int i); + + vr_bool ComputeHyperbolaData(int i, e_formula *coeff); + + void CreateHyperbolaData(int i); + + void EvaluateDegenerateHyperEll(int i, double t, coord *w); + + vr_bool ComputeHyperbolaEllipseData(int i, e_formula *coeff); + + void CreateHyperbolaEllipseData(int i); + + vr_bool ComputeLineData(int i, e_formula *coeff); + + void CreateLineData(int i); + + void EvaluateDegenerateEdge(int i, double_arg t, coord *w); + + void EvaluateParabolaData(int i, int i1, double_arg t, coord *w); + + void EvaluateHyperbolaData(int i, double t, coord *w); + + void EvaluateLineData(int i, double t, coord *w); + + void EvaluateHyperbolaEllipseData(int i, double_arg t, coord *w); + + void ResetEdgeData(void); + + void OutputMAEdges(FILE *output, int e, int n); + + void OutputMA(char output_file[]); + + void OutputVD(char output_file[], double vd_apx_dist, + vr_bool left_vd, vr_bool right_vd); + + + /* offset.cc */ + + void SetMaxOffset(double_arg t); + + vr_bool InOffsetData(int I); + + vr_bool InOffsetList(int I); + + void ResetOffsetData(void); + + vr_bool ScrutinizeArc(coord start, coord end, coord center, + vr_bool *ori, double eps, vr_bool not_isolated); + + void ComputeOff(int step_size, vr_bool time, char off_file[], + vr_bool write_off, vr_bool dxf_format, double_arg t_offset, + double_arg d_offset, vr_bool *finished, vr_bool left_offset, + vr_bool right_offset); + + void FreeOffsetData(void); + + void WriteOffsets(char off_file[]); + + void WriteOffsetsDXF(char off_file[]); + +#ifdef EXT_APPL_OFF + eao_type GetExtApplOffsetFunc(int O); + + void SetExtApplOffsetFunc(int O, eao_type ext_appl); +#endif + +#ifdef GRAPHICS + void AddOffsetsToBuffer(void); +#endif + + off_list* GetOffsetList(int i); + off_data* GetOffsetData(int i); + + void ComputeIsolatedOffsets(double_arg t0, double_arg d_off); + + void ComputeOffset(int i, double_arg t); + + void StartOffsets(void *output, int num_offset_loops); + + void StartOffsetLoop(void *output, int num_offset_elements); + + void WriteOffsetSeg(void *output, +#ifdef EXT_APPL_OFF + eao_type ext_appl_off, +#endif + double_arg x1, double_arg y1, + double_arg x2, double_arg y2); + + void WriteOffsetArc(void *output, +#ifdef EXT_APPL_OFF + eao_type ext_appl_off, +#endif + double_arg x1, double_arg y1, double_arg, double_arg, + double_arg xc, double_arg yc, vr_bool ccw); + + void EndOffsetLoop(void *, int, int, double_arg, double_arg); + + void EndOffsets(void *, int, int, int); + + void StartOffsetsDXF(void *output, int); + + void StartOffsetLoopDXF(void *output, int); + + void WriteOffsetSegDXF(void *output, +#ifdef EXT_APPL_OFF + eao_type, +#endif + double_arg x1, double_arg y1, + double_arg, double_arg); + void WriteOffsetArcDXF(void *output, +#ifdef EXT_APPL_OFF + eao_type, +#endif + double_arg x1, double_arg y1, + double_arg x2, double_arg y2, + double_arg xc, double_arg yc, vr_bool ccw); + + void EndOffsetLoopDXF(void *output, int, int, double_arg, double_arg); + + void EndOffsetsDXF(void *output, int, int, int); + +#ifdef GRAPHICS + void StartOffsetsBuf(void*, int); + + void StartOffsetLoopBuf(void*, int); + + void WriteOffsetSegBuf(void*, +#ifdef EXT_APPL_OFF + eao_type ext_appl_off, +#endif + double_arg x1, double_arg y1, + double_arg x2, double_arg y2); + void WriteOffsetArcBuf(void*, +#ifdef EXT_APPL_OFF + eao_type ext_appl_off, +#endif + double_arg x1, double_arg y1, + double_arg x2, double_arg y2, + double_arg xc, double_arg yc, vr_bool ccw); + void EndOffsetLoopBuf(void*, int, int, double_arg, double_arg); + + void EndOffsetsBuf(void*, int, int, int); +#endif + + /* wmat.cc */ + + void CheckWMAT(double wmat_dist, double wmat_angle); + + vr_bool GetWMATStatus(void); + + void ResetWMATStatus(void); + + void ComputeWMAT(double wmat_angle, double wmat_dist, + vr_bool time, vr_bool left_wmat, vr_bool right_wmat); + +#ifdef EXT_APPL_WMAT + eam_type GetExtApplWMAT(int E); + + void SetExtApplWMAT(int E, eam_type ext_appl); +#endif + +#ifdef GRAPHICS + void AddWMATToBuffer(void); +#endif + + + /* mic.cc */ + + vr_bool GetMICStatus(void); + + void ResetMICStatus(void); + + void ComputeMIC(vr_bool time, vr_bool left_mic, vr_bool right_mic, + coord *center, double *radius); + + + /* intersections.cc */ + + grid* InitialiseGrid(int num_elements, coord bb_min, coord bb_max); + + void AddPointToGrid(grid* g, int i1, double_arg eps); + + void AddSegToGrid(grid* g, int i1, double_arg eps); + + vr_bool CheckSegIntersectsGridVerSeg(int seg, double_arg x, double_arg y1, + double_arg y2, double_arg eps); + + vr_bool CheckSegIntersectsGridHorSeg(int seg, double_arg x1, double_arg x2, + double_arg y, double_arg eps); + + vr_bool AddSegIntersection(seg_entry* seg, coord intersection); + +#ifdef GENUINE_ARCS + void AddArcToGrid(grid* g, int i1, double_arg eps); + + vr_bool AddArcIntersection(arc_entry* arc, coord intersection); + + vr_bool CheckArcIntersectsGridVerSeg(int arc, double_arg x, double_arg y1, + double_arg y2, double_arg eps); + + vr_bool CheckArcIntersectsGridHorSeg(int arc, double_arg x1, double_arg x2, + double_arg y, double_arg eps); +#endif + void SplitAtIntersections(grid* grid, double_arg eps); + + void FillGrid(grid* g, double_arg eps); + + double GetIntersectionThreshold(void); + + vr_bool ComputeAllIntersections(double_arg eps); + + vr_bool CheckIntersections(void); + + vr_bool IsCheckComplete(void); + + void ResetIntersectionStatus(void); + + vr_bool ThresholdReached(void); + + vr_bool GetSegSegIntersection(int i1, int i2, coord* result, double_arg eps, + vr_bool *ident); + + int GetSegArcIntersection(int seg, int arc, coord* res1, coord* res2, + double_arg eps); + + int GetArcArcIntersection(int i1, int i2, coord* res1, coord* res2, + double_arg eps, vr_bool *ident_arcs); + + vr_bool CheckPntPnt(int i1, int i2, double_arg eps); + + vr_bool CheckPntOnSeg(int seg, int pnt, double_arg eps); + + vr_bool CheckPntOnArc(int arc, int pnt, double_arg eps); + + void DeleteGrid(grid* grid); + + int FindCellX(grid* g, double_arg x); + + int FindCellY(grid* g, double_arg y); + + vr_bool CheckIntersectionsLocally(int i1, t_site t1, int i2, t_site t2, + int i3, t_site t3); + + + /* elapsed.cc */ + + double elapsed(); + + + // + // FRIENDS (allow specific API functions to access/call protected members) + // + + /* in api_functions.cc */ + friend void API_ParseCommandLineArgs(int argc, char *argv[], + vr_bool *graphics, + vr_bool *color_graphics, + vr_bool *full_screen); + friend void API_OutputMA(char vdma_file[]); + friend void API_GetInputData(vr_bool *input_received); + friend void API_ProceedWithoutGraphics(vr_bool new_input); + + /* in graphics_ogl.cc */ +#ifdef GRAPHICS +#ifdef OGL_GRAPHICS + friend void UpdateScaleData(void); + friend void QuickDisplay(); + friend void ResetGraphicsData(void); + friend void UnZoom(void); + friend void HandleMouseButton(int button, int state, + GLint pix_i2, GLint pix_j2); + friend void HandleKeyPress(unsigned char key, GLint pix_i1, GLint pix_j1); + friend void HandleSpecialKeys(int key, GLint pix_i1, GLint pix_j1); + friend void HandleViewMenu(int item); + friend void InitializeGraphics(int argc, char *argv[], + vr_bool color_graphics, + vr_bool full_screen); + friend void ProcessGraphicsEvents(void); +#endif // OGL_GRAPHICS +#endif + + + private: + + // + // PRIVATE VARIABLES + // + + vr_bool troubles; + vr_bool io_troubles; // I/O trouble count used by VD_IO_Warning + + /* api_functions.cc */ + coord bb_min; + coord bb_max; + + vr_bool verbose; + vr_bool quiet; + vr_bool statistics; + vr_bool numerical; + vr_bool scale_data; + vr_bool check_data; + + double LARGE; + + in_pnts *pntd; + in_segs *segd; + in_arcs *arcd; + + /* compute.cc */ + vr_bool incremental; + vr_bool restart; + vr_bool restart_due_to_intersection; + vr_bool pnts_deleted; + vr_bool desperate; + + double cpu_time_pre; + double cpu_time_pnt; + double cpu_time_seg; + double cpu_time_arc; + double cpu_time_off; + double cpu_time_wmat; + double cpu_time_mic; + double cpu_time_cln; + + int removed_pnts; + int removed_segs; + int removed_arcs; + + int max_n_pnts; + int n_pnts; + int n_segs; + + int restart_counter; + int num_critical_segs; + int num_critical_arcs; + + int intersection_counter; + int restart_without_intersection; + vr_bool done_pnts; + vr_bool done_segs; + vr_bool done_arcs; + vr_bool initialized; + + vr_bool written; + vr_bool first_pnts; + vr_bool first_segs; + +#ifdef GENUINE_ARCS + int n_arcs; + vr_bool first_arcs; +#endif +#ifdef INIT_FORCED + FILE *fcd_output; +#endif + + /* data.cc */ + vr_bool data_scaled; + double scale_factor; + coord shift; + + int max_num_pnts; + int max_num_segs; + int max_num_arcs; + + vr_bool bbox_initialized; + vr_bool bbox_added; + + vr_bool support_vtx_added; + + int num_pnts_added; + int num_pnts_deleted; + int num_segs_deleted; + int num_arcs_deleted; + +#ifdef RANDOM + vronivector m_rnd_sites; + int m_num_rnd_sites; + int m_max_num_rnd_sites; + int m_cur_rnd_sites; +#endif + +#ifdef FORCED + vronivector fcd_sites; + int num_fcd_sites; + int max_num_fcd_sites; + int cur_fcd_sites; +#endif + +#ifdef SORTED + vronivector srt_sites; + int num_srt_sites; + int max_num_srt_sites; +#endif + + vr_bool dxf_poly_started; + vr_bool dxf_vertex_added; + int dxf_vertex_index; + int dxf_vertex_first; + +#ifdef ORDERED + int site_counter; + vronivector ord_sites; + int num_ord_sites; + int max_num_ord_sites; +#endif + +#ifndef ORDERED +#ifndef SORTED +#ifndef RANDOM +#ifndef FORCED + int nosr; +#endif +#endif +#endif +#endif + + /* io_basic.cc */ + vr_bool isolated_pnts; + + /* io_dxf.cc */ + int dxf_handle; + + /* vd_basic.cc */ +#ifdef VRONI_INFO + double max_relaxation; + double curr_relaxation; +#endif + + double too_large; + + int num_nodes; + int max_num_nodes; + + int num_edges; + int max_num_edges; + + vronivector free_nodes; + vronivector free_edges; + int num_free_nodes; + int max_num_free_nodes; + int num_free_edges; + int max_num_free_edges; + + typedef struct + { + int e1; + int e2; + int n; + } dummy_node; + + dummy_node *dummies; + int num_dummies; + int max_num_dummies; + + vr_bool VD_computed; + vr_bool deg2_nodes_inserted; + vr_bool VD_nodes_squared; + + int VD_identifier; + + /* prepro.cc */ + double preProZero; + + /* vd_data.cc */ + vr_bool debug_flag_VD; + + typedef struct + { + int ind; + t_site type; + } s_visited; + + s_visited *sites_visited; + int num_visited; + int max_num_visited; + + int *pnt_visited; + int num_pnt_visited; + int max_num_pnt_visited; + + int *nodes_checked; + int num_checked; + int max_num_checked; + + double zero; + + typedef struct + { + int site; + t_site type; + } preserve_buffer; + + preserve_buffer *preserve; + int num_preserve; + int max_num_preserve; + + int *loop_stack; + int num_loop_stack; + int min_loop_stack; + int max_num_loop_stack; + +#ifdef TRACE + unsigned long threshold_counter; + vr_bool dbg_center; +#endif + + /* misc.cc */ +#ifdef GENUINE_ARCS + double misc_step_size; +#else + double misc_step_size; +#endif + int invalid_i1; + int invalid_i2; + t_site invalid_t1; + t_site invalid_t2; + double invalid_eps; + + /* intersections.cc */ + vr_bool check_completed; + double eps_int; + + double comp_eps; + + /* vd_pnt.cc */ + vr_bool grid_used; + + /* clean_data.cc */ + typedef enum + { + ISO_PNT, + SEG_START, SEG_END, + ARC_START, ARC_END + } index_type; + + struct reverse_index + { + int site; + index_type type; + int next; + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + inline reverse_index() {} + }; + + vronivector reverse_ind; + int max_num_reverse_ind; + int num_reverse_ind; + vr_bool reverse_index_exists; + vr_bool data_sorted; + vr_bool clean_initialized; + + /* arg_eval.cc */ +#ifdef TRACE + vr_bool center; + vr_bool write_debug; + vr_bool proto; + int max_cntr; +#endif + +#ifdef OTHER + vr_bool cgal; +#endif + + /* voronoi.cc */ +#ifdef TRACE + int stack_size; + int max_stack_size; +#endif + + /* moved from vddata.h */ + vronivector pnts; + vronivector segs; + vronivector arcs; + int num_pnts; + int num_segs; + int num_arcs; + + vronivector nodes; + vronivector edges; + + /* grid.cc */ + int N_Initial; + + typedef struct + { + int pnt; + int next; + } pnt_node; + + int *the_grid; + int max_num_grid; + int N; + int N_x; + int N_y; + + double grid_x; + double grid_y; + double grid_a; + double grid_b; + double grid_min_x; + double grid_min_y; + double grid_max_x; + double grid_max_y; + vronivector raster_x; + vronivector raster_y; + int max_num_raster_x; + int max_num_raster_y; + + pnt_node *pnt_list; + int num_pnt_list; + int max_num_pnt_list; + + double grid_delta_x; + double grid_delta_y; + + int *first_N_pnts; + int first_counter; + + /* heap.cc */ + struct heap_node + { + double key; + int ref; + //Ensure construction doesn't implicitly initialize elements - done explicitly later anyway + heap_node() {} + }; + + vronivector heap; + int num_heap; + int max_num_heap; + + vr_bool deleted; + vr_bool not_updated; + + /* tree.cc */ + typedef struct tnode + { + int splitter; /* pnts[splitter] defines the splitting point */ + int ch1; /* below and to the left of the splitter */ + int ch2; /* above and to the left of the splitter */ + int ch3; /* below and to the right of the splitter */ + int ch4; /* above and to the right of the splitter */ + } tree_node; + + double tree_min_x; + double tree_min_y; + double tree_max_x; + double tree_max_y; + + double tree_delta_x; + double tree_delta_y; + + tree_node *tree; + int num_tree; + int max_num_tree; + int root_of_tree; + + /* memory.cc */ +#ifdef DEBUG_MEMORY + typedef struct + { + void *array_ptr; + size_t size; + unsigned int high; + } memory_dbg; +#define MAX_MEMORY_CURSOR 32768 + unsigned long curr_memory; + unsigned long max_memory; + memory_dbg memory_history[MAX_MEMORY_CURSOR]; + int memory_dbg_cursor; + typedef enum { mem_freed, mem_allocated, mem_reallocated } memory_status; + void UpdateMemoryStatus(void *ptr, memory_status status, + size_t size, unsigned int high); + int SearchMemoryHistory(void *ptr); +#endif + + /* local.h */ + double martin_h_local; + + double basic_h_local; + double basic_h_local_delta; + double basic_h_local_quot; + long basic_i_local; + + coord numerics_h_p; + coord numerics_h_q; + coord numerics_h_r; + double numerics_h_det; + double numerics_h_x; + double numerics_h_y; + double numerics_h_local; + + /* elapsed.cc */ +#ifndef NO_CPUTIME +#ifdef CPUTIME_BY_CHRONO + std::chrono::high_resolution_clock::time_point start; + vr_bool elapsed_initialized; +#else +#ifdef CPUTIME_IN_MILLISECONDS + unsigned long total_secs; + unsigned long total_usecs; +#else /* ifndef CPUTIME_IN_MILLISECONDS */ +#ifdef CPUTIME_VIA_CLOCK + clock_t total_cpu_time; + vr_bool elapsed_initialized; +#else /* ifndef CPUTIME_IN_MILLISECONDS || CPUTIME_VIA_CLOCK */ + long total; + int HZ; +#endif +#endif +#endif +#endif + + + // + // PRIVATE FUNCTIONS + // + + /* geom.h | geom.cc */ + + /** Compute squared distance between two points */ + double PntPntDistSq(coord pi, coord pj); + + /** Compute distance between two points */ + double PntPntDist(coord pi, coord pj); + + /** Compute mid point on the line (pi,pj) */ + coord MidPoint(coord pi, coord pj); + + /** Compute centroid point of the triangle (pi,pj,pk) */ + coord Centroid(coord pi, coord pj, coord pk); + + /** Build linar combination of vectors p and r by parameter t */ + coord LinearComb(const coord & p, const coord & r, double_arg t); + + /** Get the point q = p + t*v */ + coord RayPnt(const coord & p, const coord & v, double_arg t); + + /** Compute point on circle with center c and radius r + * at angle phi in mathematical sense.*/ + coord CirclePnt(const coord & c, double_arg r, double_arg phi); + + /** Compute (signed) distance of point p to circle (c,r). Positive + * values indicate that p is outside the circle (c,r). */ + double PntCircleDist(const coord & c, double_arg r, const coord & p); + + /** Compute absolute distance of point p tor circle (c,r) */ + double AbsPntCircleDist(const coord & c, double_arg r, + const coord & p); + + /** Test if point p is on circle (c,r) */ + int IsPntOnCircle(const coord & c, double_arg r, const coord & p); + + /** Compute the signed distance of the point p to the line given by + * the equation a*x + b*y + c = 0. A positive result means that + * p lies in the positive half-plane defined by the line. */ + double PntLineDist(double_arg a, double_arg b, double_arg c, + const coord & p); + + /** Compute the absolute distance of the point p to the line given by + * the equation a*x + b*y + c = 0 */ + double AbsPntLineDist(double_arg a, double_arg b, double_arg c, + const coord & p); + + /** Compute a uniform distributed random point */ + coord UniformRandomPoint(); + + vr_bool IsBetweenVoronoiNodes(int e, const coord & p, double eps); + + + /* arc_common.h | arc_common.cc */ + + /* Given three circles with centers c1, c2, and c3 and radii r1, r2, + and r3 this function calculates all points p which are equidistant to + the given circles and saves them in centers. The corresponding + distances are saved in radii. The number of points found is returned. + */ + int CircCircCircCenters(const coord & c1, const coord & c2, + const coord & c3, + double_arg r1, double_arg r2, double_arg r3, + coord* centers, double* radii, double eps); + + /* Given a circle with center c1 and two points c2 and c3, this function + calculates all points p which are equidistant to the given circle and + points and saves them in centers. The corresponding distances are saved + in radii. The number of points found is returned. + */ + int CircPntPntCenters(const coord & c1, const coord & c2, + const coord & c3, double_arg r1, + double_arg l, + coord* centers, double* radii); + + /* Given two circles with centers c1, c2 and radii r1, r2 and a segment in + Hessian normal form s1a.x + s1b.y = s1c this function calculates all + points p which are equidistant to the given sites and saves them in + centers. The corresponding distances are saved in radii. The number of + points found is returned. + */ + int CircCircSegCenters(const coord & c1, const coord & c2, + double_arg r1, double_arg r2, + double_arg s1a, double_arg s1b, double_arg s1c, + coord* centers, double* radii, double eps); + + /* Given a circle with center c1 and radius r1 and two segments in Hessian + normal form s1a.x + s1b.y = s1c, s2a.x + s2b.y = s2c this function + calculates all points p which are equidistant to the given sites and + saves them in centers. The corresponding distances are saved in radii. + The number of points found is returned. + */ + int CircSegSegCenters(const coord & c1, double_arg r1, + double_arg s1a, double_arg s1b, double_arg s1c, + double_arg s2a, double_arg s2b, double_arg s2c, + coord* centers, double* radii, double eps); + + /* + Determine the set of all points which are equidistant to two arcs which + are centered at c1 and share a common endpoint ep and a circle which is + centered at c2 and has a radius r2. The centers and radii found are saved + in centers and radii, respectively. This function returns the number of + found points. + */ + int ConcentricArcsCircleCenter(coord c1, coord ep, coord c2, double r2, + coord* centers, double* radii); + + /* + Determine the set of all points which are equidistant to two arcs which + are centered at c1 and share a common endpoint ep and a segment which has + Hessian normal form a2.x + b2.y = c2. The centers and radii found are + saved in centers and radii, respectively. This function returns the + number of found points. + */ + int ConcentricArcsSegCenter(coord c1, coord ep, + double a2, double b2, double c2, + coord* centers, double* radii); + + /** Test whether pnt is in arc-cone. */ + vr_bool IsPntInArcConeEps(int arc, const coord & pnt, double_arg eps); + + /** Test whether pnt is in arc-cone. */ + vr_bool IsPntInArcCone(int arc, coord pnt); + + /** Test whether pnt is in arc-cone. */ + vr_bool IsPntInArcConeStrict(int arc, coord pnt); + + /** Intersect two Circles */ + int IntersectTwoCircles(const coord & c1, const coord & c2, + double_arg r1, double_arg r2, + coord* left, coord* right); + + /** Intersect Circle with segment*/ + int IntersectCircleSeg(const coord & c, double_arg r, + double_arg a, double_arg b, double_arg d, + coord* left, coord* right); + + /** Do arc and pnt intersect in inner of arc? (Higher eps --> less likely an intersection) */ + vr_bool DoArcPntIntersect(int arc, const coord & pnt, double_arg eps); + + /** + * The circle centered at c1 with radius r1 and the circle c2 with the radius r2 are placed + * side-by-side and a hyperbola is defined as bisector. This bisector has two asymptotes which + * are determined. The directions of those are saved in dir1 and dir2. The start points of + * these rays are at (a,b) resp. (a,-b) modulo rotation and offset from the crossing point. + * These is useful to get an approximation to min. distance to both circles. + */ + void GetAsymptotes(const coord & c1, double_arg r1, + const coord & c2, double_arg r2, + coord *start1, coord *dir1, coord* start2, coord *dir2); + + /* + * We shoot a ray starting at p in direction v and intersect this ray with + * the offset circles of the point c. Hence, the intersection lies on the ray + * and is equidistant to p and to c. Effectively, this means intersecting + * the bisector between p and c with the ray. + * + * returns the number of solutions + * + */ + int IntersectRayPoint(const coord & p, coord v, const coord & c, + coord* centers, double* radii, double eps); + + /* + * We shoot a ray starting at p in direction v and intersect this ray with the + * offset-circles of the circle centered at c and with radius r. So the + * intersection lies on the ray and is equidistant to p and to the circle (c,r) + * + * returns the number of solutions + * + */ + int IntersectRayCircle(const coord & p, coord v, + const coord & c, double_arg r, + coord* centers, double* radii, double eps); + + /** We shoot a ray starting at p in direction v and intersect this ray with the offset-segments + * of the segment with normal vector (a,b) and hesse form a.x+b.y=c. So the intersection lies on the + * ray and is equidistant to p and to the segment. + * + * returns the number of solutions + * */ + int IntersectRaySegment(const coord & p, coord v, + double_arg a, double_arg b, double_arg c, + coord* centers, double* radii, double eps); + + + /* wmat.cc */ + +#ifdef WMAT + void ComputeWMATParabola(int i, int i1, int i2, double_arg wmat_cosine, + double_arg wmat_dist_sq); + void ComputeWMATHyperbola(int i, int i1, int i2, double_arg wmat_cosine, + double_arg wmat_dist_sq); + void ComputeWMATLine(int i, int i1, int i2, double wmat_cosine, + double wmat_dist_sq); + void ComputeWMATEdge(int e, double_arg wmat_cosine, + double_arg wmat_dist_sq); +#else + void ComputeWMATParabola(int i, int i1, int i2); + void ComputeWMATHyperbola(int i); + void ComputeWMATLine(int i); + void ComputeWMATEdge(int e); + #endif + + + /* clean_data.cc: */ + + vr_bool InReverseIndList(int i); + void InsertReverseIndex(const int ipnt, const int isite, + const index_type tsite); + void SetUpReverseIndex(int number_of_segs, int number_of_arcs, + vr_bool set_idx); + + /* heap.cc */ + + void StoreHeapData(int idx, double s_key, int s_ref); + void GetHeapData(int idx, double *s_key, int *s_ref); + void FreeHeap(void); + vr_bool InHeap(int idx); + vr_bool InHeapInsert(int idx); + void DumpOnHeap(double_arg key, int ref); + void UpdateHeap(double_arg key, int ref); + void ExtendHeap(double_arg key, int ref); + void InsertIntoHeap(double_arg key, int ref); + vr_bool DeleteFromHeap(double *key, int *ref); + void InitHeap(void); + void ResetHeap(void); + + + /* tree.cc */ + + void RecursiveInitTree(double x_min, double y_min, + double x_max, double y_max, + int *first_N_points, int *m, int level); + +#ifdef GRAPHICS + void RecursiveDrawTree(double x_min, double y_min, double_arg x_max, + double_arg y_max, int root); +#endif + + + + + /****************************************************************************/ + /* funioni aggiunte per integrazione con nostre librerie */ + /****************************************************************************/ + +public : + void GetPointFromCoord( coord ptCoord, double p[3]) ; + + // offset + int GetOffsetCount() { return num_offset_list ; } ; + int GetOffsetCurveCount( int i) ; + vr_bool GetOffsetCurve( int nOffs, int nCrv, int& nType, double ptS[3], double ptE[3], double ptC[3], + int& nOrigLoop, int& nOrigCrv, int& nOrigPnt) ; + + // voronoi + void ResetVoronoiDiagram(void) ; + void GetVDBisectorPoints( int i, double ptS[3], double ptE[3]) ; + void GetVDBisectorParams( int i, double& dParS, double& dParE) ; + BisectorType GetVDBisectorType( int i) ; + void GetVDBisectorPointAtParam( int nEdge, double dPar, double pt[3]) ; + + // media axis + vr_bool IsWMATEdge( int nEdge) ; + + // debug + void MyWriteVoronoiRegion( FILE *output) ; + + }; + + + +/* inline function includes */ +#include "geom.h" +#ifdef GENUINE_ARCS +#include "arc_common.h" +#endif +#include "vd_data.h" +#include "numerics.h" + +#endif diff --git a/vroni/Include/vronivector.h b/vroni/Include/vronivector.h new file mode 100644 index 0000000..9b1678a --- /dev/null +++ b/vroni/Include/vronivector.h @@ -0,0 +1,109 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 1999-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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_VECTOR_H +#define VRONI_VECTOR_H + +#include +#include +#include +#include + +template +class vronivector { + + private: + unsigned int arraysize; + T * array; + + public: + inline vronivector() : arraysize(0), array(NULL) {} + + inline ~vronivector() { + free(array); + } + + T * begin() { + return array; + } + + T * end() { + return array + arraysize; + } + + unsigned int size() { + return arraysize; + } + + void inline reserve(unsigned int ) {} + + void resize(unsigned int newsize) { + + /* */ + /* Call destructor of elements no longer needed if the size of the */ + /* array is reduced */ + /* */ + for(unsigned int i = newsize; i < arraysize; ++i) { + array[i].~T(); + } + + // Reallocate + T * newarray = (T*) realloc(array, newsize * sizeof(T)); + if (newarray == NULL) throw std::bad_alloc(); + + //Initialize new elements of array + for(unsigned int i = arraysize; i < newsize; ++i) { + new (&newarray[i]) T(); + } + array = newarray; + arraysize = newsize; + } + + void clear() { + free(array); + array = NULL; + arraysize = 0; + } + + + inline T & operator[](unsigned int ind) { + return array[ind]; + } + +}; + +template +inline void gentlyResizeSTLVector(vtype & v, unsigned int newsize, + const char * vname) { + try { + v.reserve(newsize); + v.resize(newsize); + } + catch (std::bad_alloc& c) { + std::cerr << "\n" << "VRONI exception while trying to resize vector " + << vname << " (" << c.what() << ")" << std::endl; + throw std::runtime_error("VRONI error: gentlyResizeSTLVector() - memory reallocation failed!"); + } +} + + +#endif diff --git a/vroni/Include/wmat.h b/vroni/Include/wmat.h new file mode 100644 index 0000000..1172709 --- /dev/null +++ b/vroni/Include/wmat.h @@ -0,0 +1,150 @@ +/*****************************************************************************/ +/* */ +/* Copyright (C) 2001-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 */ +/* */ +/*****************************************************************************/ + +#ifndef VRONI_WMAT_H +#define VRONI_WMAT_H + +#include "types.h" + + +#ifdef WMAT + #ifndef MAT + #define MAT + #endif +#endif + + +#ifdef MAT + + +typedef struct { + vr_bool in_w_mat; /* true if a portion of this VD edge belongs also to */ + /* WMAT or MAT */ +#ifdef WMAT + double r_min; /* minimum contour clearance of this edge */ + double r_max; /* maximum contour clearance of this edge */ + coord lft_mn_pnt; /* left contact point for disk with radius r_min */ + coord lft_mx_pnt; /* left contact point for disk with radius r_max */ + coord rgt_mn_pnt; /* right contact point for disk with radius r_min */ + coord rgt_mx_pnt; /* right contact point for disk with radius r_max */ +#endif +#ifdef EXT_APPL_WMAT + eam_type ext_appl;/* this field can be set by an application program to */ + /* refer to a user-defined entity. */ +#endif +} w_mat_data; /*********** (weighted) medial axis *********************/ + + + +#define IsWmatEdge(E) \ +(\ + assert(InEdgesList(E)), \ + (edges[E].w_mat.in_w_mat)) + + +#define SetWmatEdge(E, B) \ +{\ + assert(InEdgesList(E)); \ + edges[E].w_mat.in_w_mat = B; \ +} +#endif + + +#ifdef WMAT +#define GetWmatRMin(E) \ +(\ + assert(InEdgesList(E)), \ + (edges[E].w_mat.r_min)) + + +#define SetWmatRMin(E, R) \ +{\ + assert(InEdgesList(E)); \ + edges[E].w_mat.r_min = R; \ +} + + +#define GetWmatRMax(E) \ +(\ + assert(InEdgesList(E)), \ + (edges[E].w_mat.r_max)) + + +#define SetWmatRMax(E, R) \ +{\ + assert(InEdgesList(E)); \ + edges[E].w_mat.r_max = R; \ +} + + +#define GetWmatLftMnPnt(E) \ +(\ + assert(InEdgesList(E)), \ + (edges[E].w_mat.lft_mn_pnt)) + + +#define SetWmatLftMnPnt(E, P) \ +{\ + assert(InEdgesList(E)); \ + edges[E].w_mat.lft_mn_pnt = P; \ +} + + +#define GetWmatRgtMnPnt(E) \ +(\ + assert(InEdgesList(E)), \ + (edges[E].w_mat.rgt_mn_pnt)) + + +#define SetWmatRgtMnPnt(E, P) \ +{\ + assert(InEdgesList(E)); \ + edges[E].w_mat.rgt_mn_pnt = P; \ +} + + +#define GetWmatLftMxPnt(E) \ +(\ + assert(InEdgesList(E)), \ + (edges[E].w_mat.lft_mx_pnt)) + + +#define SetWmatLftMxPnt(E, P) \ +{\ + assert(InEdgesList(E)); \ + edges[E].w_mat.lft_mx_pnt = P; \ +} + + +#define GetWmatRgtMxPnt(E) \ +(\ + assert(InEdgesList(E)), \ + (edges[E].w_mat.rgt_mx_pnt)) + + +#define SetWmatRgtMxPnt(E, P) \ +{\ + assert(InEdgesList(E)); \ + edges[E].w_mat.rgt_mx_pnt = P; \ +} +#endif +#endif diff --git a/vroni/Lib/vroniD32.lib b/vroni/Lib/vroniD32.lib new file mode 100644 index 0000000..de3f284 Binary files /dev/null and b/vroni/Lib/vroniD32.lib differ diff --git a/vroni/Lib/vroniD64.lib b/vroni/Lib/vroniD64.lib new file mode 100644 index 0000000..dc07309 Binary files /dev/null and b/vroni/Lib/vroniD64.lib differ diff --git a/vroni/Lib/vroniR32.lib b/vroni/Lib/vroniR32.lib new file mode 100644 index 0000000..5bb2802 Binary files /dev/null and b/vroni/Lib/vroniR32.lib differ diff --git a/vroni/Lib/vroniR64.lib b/vroni/Lib/vroniR64.lib new file mode 100644 index 0000000..55aeeec Binary files /dev/null and b/vroni/Lib/vroniR64.lib differ