739088af9f
- aggiornamento versione.
1562 lines
38 KiB
C++
1562 lines
38 KiB
C++
/*****************************************************************************/
|
|
/* */
|
|
/* Copyright (C) 1999-2025 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 */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
/* */
|
|
/* get standard libraries */
|
|
/* */
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <float.h>
|
|
#include <math.h>
|
|
|
|
/* */
|
|
/* get my header files */
|
|
/* */
|
|
#include "fpkernel.h"
|
|
#include "vronivector.h"
|
|
#include "vroni_object.h"
|
|
#include "defs.h"
|
|
#include "numerics.h"
|
|
#include "random.h"
|
|
|
|
|
|
#define BLOCK_SIZE 1024
|
|
#define PAGE_SIZE 32768
|
|
|
|
|
|
void vroniObject::SetSupportVtxFlag(vr_bool flag)
|
|
{
|
|
support_vtx_added = flag;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
vr_bool vroniObject::GetSupportVtxFlag()
|
|
{
|
|
return support_vtx_added;
|
|
}
|
|
|
|
|
|
/* */
|
|
/* the functions */
|
|
/* GetNumberOfPoints(), */
|
|
/* GetNumberOfSegments(), */
|
|
/* GetNumberOfArcs() */
|
|
/* report the current numbers of points, segments and circular arcs! */
|
|
/* please note that these numbers may change during the execution of VRONI, */
|
|
/* e.g., when VRONI encounters an intersection. */
|
|
/* */
|
|
|
|
int vroniObject::GetNumberOfPoints(void)
|
|
{
|
|
return num_pnts; /* note that this number increases by four during */
|
|
/* the construction of the VD due to the insertion */
|
|
/* of four dummy corner points around the input */
|
|
/* data; recall the use of the run-time option */
|
|
/* "--bound". */
|
|
}
|
|
|
|
|
|
int vroniObject::GetNumberOfSegments(void)
|
|
{
|
|
return num_segs;
|
|
}
|
|
|
|
|
|
int vroniObject::GetNumberOfArcs(void)
|
|
{
|
|
return num_arcs;
|
|
}
|
|
|
|
|
|
void vroniObject::ExtendPnts(int number)
|
|
{
|
|
int mnp;
|
|
|
|
mnp = num_pnts + number;
|
|
|
|
if (max_num_pnts < mnp) {
|
|
max_num_pnts = mnp;
|
|
gentlyResizeSTLVector(pnts, max_num_pnts, "data:pnts");
|
|
}
|
|
|
|
assert(mnp > 4);
|
|
assert(num_pnts > 4);
|
|
|
|
pnts[mnp-1] = pnts[num_pnts-1];
|
|
pnts[mnp-2] = pnts[num_pnts-2];
|
|
num_pnts -= 2;
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
AddPntToBuffer(mnp-1, PntColor);
|
|
AddPntToBuffer(mnp-2, PntColor);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::ResizePnts(int number)
|
|
{
|
|
number += 5;
|
|
if (max_num_pnts < number) {
|
|
max_num_pnts = number;
|
|
gentlyResizeSTLVector(pnts, max_num_pnts, "data:pnts");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
void vroniObject::InitPntSite(pnt *pointer, double_arg x, double_arg y, eap_type ext_appl)
|
|
#else
|
|
void vroniObject::InitPntSite(pnt *pointer, double_arg x, double_arg y)
|
|
#endif
|
|
{
|
|
pointer->p.x = x;
|
|
pointer->p.y = y;
|
|
pointer->vd = NIL;
|
|
pointer->node = NIL;
|
|
pointer->s = false;
|
|
pointer->del = false;
|
|
pointer->vis = false;
|
|
#ifdef EXT_APPL_PNTS
|
|
pointer->ext_appl = ext_appl;
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
pointer->draw = false;
|
|
#endif
|
|
#ifdef ORDERED
|
|
++site_counter;
|
|
pointer->key = site_counter;
|
|
#endif
|
|
#ifdef WRITE_VD
|
|
pointer->idx = NIL;
|
|
pointer->vd_edge = NIL;
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
int vroniObject::StorePnt(double_arg x, double_arg y, eap_type ext_appl)
|
|
#else
|
|
int vroniObject::StorePnt(double_arg x, double_arg y)
|
|
#endif
|
|
{
|
|
int i;
|
|
|
|
if (num_pnts <= 1) num_pnts = 2;
|
|
|
|
if (num_pnts >= max_num_pnts) {
|
|
// MODIF modifico quantità di memoria richiesta dall'allocazione in analogia con std::vector
|
|
// max_num_pnts += PAGE_SIZE;
|
|
max_num_pnts = num_pnts * 2 ;
|
|
gentlyResizeSTLVector(pnts, max_num_pnts, "data:pnts");
|
|
}
|
|
|
|
if ((i = num_pnts) == 2) {
|
|
#ifdef EXT_APPL_PNTS
|
|
InitPntSite(&(pnts[0]), -DBL_MAX, -DBL_MAX, ext_appl);
|
|
InitPntSite(&(pnts[1]), -DBL_MAX, DBL_MAX, ext_appl);
|
|
#else
|
|
InitPntSite(&(pnts[0]), -DBL_MAX, -DBL_MAX);
|
|
InitPntSite(&(pnts[1]), -DBL_MAX, DBL_MAX);
|
|
#endif
|
|
}
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
InitPntSite(&(pnts[i]), x, y, ext_appl);
|
|
#else
|
|
InitPntSite(&(pnts[i]), x, y);
|
|
#endif
|
|
++num_pnts;
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
int vroniObject::StoreSeg(int i1, int i2, eas_type ext_appl)
|
|
#else
|
|
int vroniObject::StoreSeg(int i1, int i2)
|
|
#endif
|
|
{
|
|
int i;
|
|
seg *pointer;
|
|
|
|
assert(InPntsList(i1));
|
|
assert(InPntsList(i2));
|
|
if (num_segs >= max_num_segs) {
|
|
// MODIF modifico quantità di memoria richiesta dall'allocazione in analogia con std::vector
|
|
// max_num_segs += PAGE_SIZE;
|
|
max_num_segs = ( num_segs + 1) * 2 ;
|
|
gentlyResizeSTLVector(segs, max_num_segs, "data:segs");
|
|
}
|
|
pointer = &(segs[num_segs]);
|
|
pointer->i1 = i1;
|
|
pointer->i2 = i2;
|
|
pointer->vd = NIL;
|
|
#ifdef EXT_APPL_SITES
|
|
pointer->ext_appl = ext_appl;
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
pointer->draw = false;
|
|
#endif
|
|
#ifdef ORDERED
|
|
++site_counter;
|
|
pointer->key = site_counter;
|
|
#endif
|
|
#ifdef WRITE_VD
|
|
pointer->vd_edge = NIL;
|
|
#endif
|
|
|
|
i = num_segs;
|
|
++num_segs;
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
int vroniObject::StoreArc(int i1, int i2, double_arg xc, double_arg yc,
|
|
vr_bool ccw, eas_type ext_appl)
|
|
#else
|
|
int vroniObject::StoreArc(int i1, int i2, double_arg xc, double_arg yc,
|
|
vr_bool ccw)
|
|
#endif
|
|
{
|
|
int i;
|
|
double r1, r2;
|
|
arc *pointer;
|
|
|
|
assert(InPntsList(i1));
|
|
assert(InPntsList(i2));
|
|
if (num_arcs >= max_num_arcs) {
|
|
// MODIF modifico quantità di memoria richiesta dall'allocazione in analogia con std::vector
|
|
// max_num_arcs += PAGE_SIZE;
|
|
max_num_arcs = ( num_arcs + 1) * 2 ;
|
|
gentlyResizeSTLVector(arcs, max_num_arcs, "data:arcs");
|
|
}
|
|
pointer = &(arcs[num_arcs]);
|
|
pointer->i1 = i1;
|
|
pointer->i2 = i2;
|
|
pointer->c.x = xc;
|
|
pointer->c.y = yc;
|
|
pointer->ccw = ccw;
|
|
r1 = PntPntDist(pnts[i1].p, pointer->c);
|
|
r2 = PntPntDist(pnts[i2].p, pointer->c);
|
|
pointer->r = (r1 + r2) / 2.0;
|
|
pointer->vd = NIL;
|
|
#ifdef EXT_APPL_SITES
|
|
pointer->ext_appl = ext_appl;
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
pointer->draw = false;
|
|
#endif
|
|
#ifdef ORDERED
|
|
++site_counter;
|
|
pointer->key = site_counter;
|
|
#endif
|
|
i = num_arcs;
|
|
++num_arcs;
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
|
|
#ifdef GRAPHICS
|
|
void vroniObject::MarkDrawSite(int i, t_site type)
|
|
{
|
|
switch(type) {
|
|
case(PNT):
|
|
assert(InPntsList(i));
|
|
pnts[i].draw = true;
|
|
break;
|
|
case(SEG):
|
|
assert(InSegsList(i));
|
|
segs[i].draw = true;
|
|
break;
|
|
case(ARC):
|
|
assert(InArcsList(i));
|
|
arcs[i].draw = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::ResetDrawSite(int i, t_site type)
|
|
{
|
|
switch(type) {
|
|
case(PNT):
|
|
assert(InPntsList(i));
|
|
pnts[i].draw = false;
|
|
break;
|
|
case(SEG):
|
|
assert(InSegsList(i));
|
|
segs[i].draw = false;
|
|
break;
|
|
case(ARC):
|
|
assert(InArcsList(i));
|
|
arcs[i].draw = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
void vroniObject::InitPnts(int number)
|
|
{
|
|
if (max_num_pnts < number) {
|
|
max_num_pnts = number;
|
|
gentlyResizeSTLVector(pnts, max_num_pnts, "data:pnts");
|
|
}
|
|
num_pnts = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
void vroniObject::InitStoragePnts(int number)
|
|
{
|
|
if (max_num_pnts < number) {
|
|
max_num_pnts = number;
|
|
gentlyResizeSTLVector(pnts, max_num_pnts, "data:pnts");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void vroniObject::FreeInputData()
|
|
{
|
|
pnts.clear();
|
|
segs.clear();
|
|
arcs.clear();
|
|
#ifdef RANDOM
|
|
m_rnd_sites.clear();
|
|
#endif
|
|
#ifdef FORCED
|
|
fcd_sites.clear();
|
|
#endif
|
|
#ifdef SORTED
|
|
srt_sites.clear();
|
|
#endif
|
|
#ifdef ORDERED
|
|
ord_sites.clear();
|
|
#endif
|
|
|
|
max_num_arcs = 0;
|
|
num_arcs = 0;
|
|
max_num_segs = 0;
|
|
num_segs = 0;
|
|
max_num_pnts = 0;
|
|
num_pnts = 0;
|
|
#ifdef RANDOM
|
|
m_max_num_rnd_sites = 0;
|
|
m_num_rnd_sites = 0;
|
|
#endif
|
|
#ifdef FORCED
|
|
max_num_fcd_sites = 0;
|
|
num_fcd_sites = 0;
|
|
#endif
|
|
#ifdef SORTED
|
|
max_num_srt_sites = 0;
|
|
num_srt_sites = 0;
|
|
#endif
|
|
#ifdef ORDERED
|
|
max_num_ord_sites = 0;
|
|
num_ord_sites = 0;
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void vroniObject::InitSegs(int number)
|
|
{
|
|
if (max_num_segs < number) {
|
|
max_num_segs = number;
|
|
gentlyResizeSTLVector(segs, max_num_segs, "data:segs");
|
|
}
|
|
num_segs = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::InitStorageSegs(int number)
|
|
{
|
|
if (max_num_segs < number) {
|
|
max_num_segs = number;
|
|
gentlyResizeSTLVector(segs, max_num_segs, "data:segs");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void vroniObject::InitArcs(int number)
|
|
{
|
|
if (max_num_arcs < number) {
|
|
max_num_arcs = number;
|
|
gentlyResizeSTLVector(arcs, max_num_arcs, "data:arcs");
|
|
}
|
|
num_arcs = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::InitStorageArcs(int number)
|
|
{
|
|
if (max_num_arcs < number) {
|
|
max_num_arcs = number;
|
|
gentlyResizeSTLVector(arcs, max_num_arcs, "data:arcs");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/* */
|
|
/* this routine returns the bounding box of the entries of */
|
|
/* "pnts[2,...,num_pnts-1]". */
|
|
/* */
|
|
void vroniObject::SetBoundingBox(void)
|
|
{
|
|
int i;
|
|
|
|
if (num_pnts <= 2) return;
|
|
assert(!bbox_initialized);
|
|
|
|
bb_min.x = GetPntCoords(2).x;
|
|
bb_max.x = bb_min.x;
|
|
bb_min.y = GetPntCoords(2).y;
|
|
bb_max.y = bb_min.y;
|
|
|
|
for (i = 3; i < num_pnts; ++i) {
|
|
if (GetPntCoords(i).x < bb_min.x) bb_min.x = GetPntCoords(i).x;
|
|
else if (GetPntCoords(i).x > bb_max.x) bb_max.x = GetPntCoords(i).x;
|
|
if (GetPntCoords(i).y < bb_min.y) bb_min.y = GetPntCoords(i).y;
|
|
else if (GetPntCoords(i).y > bb_max.y) bb_max.y = GetPntCoords(i).y;
|
|
}
|
|
|
|
/* */
|
|
/* add two dummy corner points. later on, after the bounding box is */
|
|
/* known, they will be replaced by the true corners. see the meaning */
|
|
/* of the run-time option "--bound". */
|
|
/* */
|
|
#ifdef EXT_APPL_PNTS
|
|
pnts[0].ext_appl = pnts[1].ext_appl = eap_NIL;
|
|
(void) StorePnt( DBL_MAX, -DBL_MAX, eap_NIL);
|
|
(void) StorePnt( DBL_MAX, DBL_MAX, eap_NIL);
|
|
#else
|
|
(void) StorePnt( DBL_MAX, -DBL_MAX);
|
|
(void) StorePnt( DBL_MAX, DBL_MAX);
|
|
#endif
|
|
|
|
bbox_initialized = true;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::CheckBoundingBox(void)
|
|
{
|
|
int i, k;
|
|
|
|
assert(bbox_added);
|
|
|
|
k = num_pnts - 2;
|
|
for (i = 2; i < k; ++i) {
|
|
assert(GetPntCoords(i).x >= bb_min.x);
|
|
assert(GetPntCoords(i).x <= bb_max.x);
|
|
assert(GetPntCoords(i).y >= bb_min.y);
|
|
assert(GetPntCoords(i).y <= bb_max.y);
|
|
}
|
|
i = num_pnts - 1;
|
|
assert(pnts[0].p.x == pnts[1].p.x);
|
|
assert(pnts[0].p.y < pnts[1].p.y);
|
|
assert(pnts[k].p.x == pnts[i].p.x);
|
|
assert(pnts[k].p.y < pnts[i].p.y);
|
|
assert(pnts[0].p.x < pnts[k].p.x);
|
|
assert(pnts[0].p.y == pnts[k].p.y);
|
|
assert(pnts[1].p.x < pnts[i].p.x);
|
|
assert(pnts[1].p.y == pnts[i].p.y);
|
|
assert(pnts[0].p.x < pnts[2].p.x);
|
|
assert(pnts[i].p.x > pnts[2].p.x);
|
|
assert(pnts[0].p.y < pnts[2].p.y);
|
|
assert(pnts[i].p.y > pnts[2].p.y);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
vr_bool vroniObject::InPntsList(int index)
|
|
{
|
|
return ((index >= 0) && (index < num_pnts) &&
|
|
(num_pnts <= max_num_pnts));
|
|
}
|
|
|
|
|
|
vr_bool vroniObject::InSegsList(int index)
|
|
{
|
|
return ((index >= 0) && (index < num_segs) &&
|
|
(num_segs <= max_num_segs));
|
|
}
|
|
|
|
|
|
vr_bool vroniObject::InArcsList(int index)
|
|
{
|
|
return ((index >= 0) && (index < num_arcs) &&
|
|
(num_arcs <= max_num_arcs));
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
int vroniObject::HandlePnt(double_arg xc1, double_arg yc1, eap_type ext_appl)
|
|
#else
|
|
int vroniObject::HandlePnt(double_arg xc1, double_arg yc1)
|
|
#endif
|
|
{
|
|
int i1;
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
i1 = StorePnt(xc1, yc1, ext_appl);
|
|
#else
|
|
i1 = StorePnt(xc1, yc1);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) AddPntToBuffer(i1, PntColor);
|
|
#endif
|
|
|
|
return i1;
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
void vroniObject::HandleSeg(double_arg xc1, double_arg yc1, double_arg xc2, double_arg yc2,
|
|
eas_type ext_appl)
|
|
#else
|
|
void vroniObject::HandleSeg(double_arg xc1, double_arg yc1, double_arg xc2, double_arg yc2)
|
|
#endif
|
|
{
|
|
int i1, i2, i3;
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
i1 = StorePnt(xc1, yc1, ext_appl);
|
|
i2 = StorePnt(xc2, yc2, ext_appl);
|
|
#else
|
|
i1 = StorePnt(xc1, yc1);
|
|
i2 = StorePnt(xc2, yc2);
|
|
#endif
|
|
ExtApplHandleSeg; /* external-application */
|
|
#ifdef EXT_APPL_SITES
|
|
i3 = StoreSeg(i1, i2, ext_appl);
|
|
#else
|
|
i3 = StoreSeg(i1, i2);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
AddPntToBuffer(i1, PntColor);
|
|
AddPntToBuffer(i2, PntColor);
|
|
AddSegToBuffer(i3, SegColor);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
void vroniObject::AddSeg(int *i1, double_arg xc2, double_arg yc2, eas_type ext_appl)
|
|
#else
|
|
void vroniObject::AddSeg(int *i1, double_arg xc2, double_arg yc2)
|
|
#endif
|
|
{
|
|
int i2, i3;
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
i2 = StorePnt(xc2, yc2, {ext_appl.first, ext_appl.second + 1});
|
|
#else
|
|
i2 = StorePnt(xc2, yc2);
|
|
#endif
|
|
#ifdef EXT_APPL_SITES
|
|
i3 = StoreSeg(*i1, i2, ext_appl);
|
|
#else
|
|
i3 = StoreSeg(*i1, i2);
|
|
#endif
|
|
*i1 = i2;
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
AddSegToBuffer(i3, SegColor);
|
|
AddPntToBuffer(i2, PntColor);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
void vroniObject::AddArc(int *i1, double_arg xc3, double_arg yc3, double_arg xc2, double_arg yc2,
|
|
int attr, eas_type ext_appl)
|
|
#else
|
|
void vroniObject::AddArc(int *i1, double_arg xc3, double_arg yc3, double_arg xc2, double_arg yc2,
|
|
int attr)
|
|
#endif
|
|
{
|
|
int i2, i3;
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
i2 = StorePnt(xc3, yc3, {ext_appl.first, ext_appl.second + 1});
|
|
#else
|
|
i2 = StorePnt(xc3, yc3);
|
|
#endif
|
|
assert((attr == ARC) || (attr == -ARC));
|
|
#ifdef EXT_APPL_SITES
|
|
if (attr == ARC) i3 = StoreArc(*i1, i2, xc2, yc2, true, ext_appl);
|
|
else i3 = StoreArc(i2, *i1, xc2, yc2, false, ext_appl);
|
|
#else
|
|
if (attr == ARC) i3 = StoreArc(*i1, i2, xc2, yc2, true);
|
|
else i3 = StoreArc(i2, *i1, xc2, yc2, false);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
AddPntToBuffer(i2, PntColor);
|
|
AddArcToBuffer(i3, SegColor);
|
|
}
|
|
#endif
|
|
*i1 = i2;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
void vroniObject::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)
|
|
#else
|
|
void vroniObject::HandleArc(double_arg xc1, double_arg yc1, double_arg xc2, double_arg yc2,
|
|
double_arg xc3, double_arg yc3, int attr)
|
|
#endif
|
|
{
|
|
int i1, i2, i3;
|
|
|
|
#ifdef EXT_APPL_PNTS
|
|
i1 = StorePnt(xc1, yc1, ext_appl);
|
|
i2 = StorePnt(xc2, yc2, ext_appl);
|
|
#else
|
|
i1 = StorePnt(xc1, yc1);
|
|
i2 = StorePnt(xc2, yc2);
|
|
#endif
|
|
ExtApplHandleArc;
|
|
|
|
assert((attr == ARC) || (attr == -ARC));
|
|
#ifdef EXT_APPL_SITES
|
|
if (attr == ARC) i3 = StoreArc(i1, i2, xc3, yc3, true, ext_appl);
|
|
else i3 = StoreArc(i2, i1, xc3, yc3, false, ext_appl);
|
|
#else
|
|
if (attr == ARC) i3 = StoreArc(i1, i2, xc3, yc3, true);
|
|
else i3 = StoreArc(i2, i1, xc3, yc3, false);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
AddPntToBuffer(i1, PntColor);
|
|
AddPntToBuffer(i2, PntColor);
|
|
AddArcToBuffer(i3, SegColor);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
void vroniObject::CloseSeg(int i1, int i2, eas_type ext_appl)
|
|
#else
|
|
void vroniObject::CloseSeg(int i1, int i2)
|
|
#endif
|
|
{
|
|
int i3;
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
i3 = StoreSeg(i1, i2, ext_appl);
|
|
#else
|
|
i3 = StoreSeg(i1, i2);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) AddSegToBuffer(i3, SegColor);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef EXT_APPL_SITES
|
|
void vroniObject::CloseArc(int i1, int i2, double_arg xc2, double_arg yc2, int attr,
|
|
eas_type ext_appl)
|
|
#else
|
|
void vroniObject::CloseArc(int i1, int i2, double_arg xc2, double_arg yc2, int attr)
|
|
#endif
|
|
{
|
|
int i3;
|
|
|
|
assert((attr == ARC) || (attr == -ARC));
|
|
#ifdef EXT_APPL_SITES
|
|
if (attr == ARC) i3 = StoreArc(i1, i2, xc2, yc2, true, ext_appl);
|
|
else i3 = StoreArc(i2, i1, xc2, yc2, false, ext_appl);
|
|
#else
|
|
if (attr == ARC) i3 = StoreArc(i1, i2, xc2, yc2, true);
|
|
else i3 = StoreArc(i2, i1, xc2, yc2, false);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
AddPntToBuffer(i2, PntColor);
|
|
AddArcToBuffer(i3, SegColor);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
void vroniObject::ResetInputData(void)
|
|
{
|
|
num_pnts = 0;
|
|
num_segs = 0;
|
|
num_arcs = 0;
|
|
#ifdef RANDOM
|
|
m_num_rnd_sites = 0;
|
|
#endif
|
|
#ifdef FORCED
|
|
num_fcd_sites = 0;
|
|
#endif
|
|
#ifdef SORTED
|
|
num_srt_sites = 0;
|
|
#endif
|
|
#ifdef ORDERED
|
|
site_counter = 0;
|
|
num_ord_sites = 0;
|
|
#endif
|
|
|
|
support_vtx_added = false;
|
|
data_scaled = false;
|
|
scale_factor = 1.0;
|
|
shift.x = 0.0;
|
|
shift.y = 0.0;
|
|
|
|
dxf_poly_started = false;
|
|
dxf_vertex_added = false;
|
|
dxf_vertex_index = NIL;
|
|
dxf_vertex_first = NIL;
|
|
|
|
bbox_added = false;
|
|
bbox_initialized = false;
|
|
|
|
num_pnts_added = 0;
|
|
num_pnts_deleted = 0;
|
|
num_segs_deleted = 0;
|
|
num_arcs_deleted = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::AddDummyCorners(int bound)
|
|
{
|
|
int i;
|
|
double delta_x, delta_y;
|
|
|
|
assert(!bbox_added);
|
|
assert(bbox_initialized);
|
|
|
|
delta_x = (bb_max.x - bb_min.x);
|
|
if (eq(delta_x, ZERO)) delta_x = (bound + 0.01);
|
|
else delta_x *= (bound + 0.01);
|
|
delta_y = (bb_max.y - bb_min.y);
|
|
if (eq(delta_y, ZERO)) delta_y = (bound + 0.01);
|
|
else delta_y *= (bound + 0.01);
|
|
if (delta_x < (0.5 * delta_y)) delta_x = 0.5 * delta_y;
|
|
else if (delta_y < (0.5 * delta_x)) delta_y = 0.5 * delta_x;
|
|
|
|
/* */
|
|
/* let the user assign coordinates to the four dummy corners by setting */
|
|
/* delta_x and delta_y. Please make sure to use only positive values that */
|
|
/* are at least as large as the x- and y-lengths of the old bounding box! */
|
|
/* */
|
|
ExtApplAddDummyCorners;
|
|
|
|
/* */
|
|
/* assign coordinates */
|
|
/* */
|
|
assert(GetPntCoords(0).x == -DBL_MAX);
|
|
assert(GetPntCoords(0).y == -DBL_MAX);
|
|
SetXCoord(0, bb_min.x - delta_x);
|
|
SetYCoord(0, bb_min.y - delta_y);
|
|
assert(GetPntCoords(1).x == -DBL_MAX);
|
|
assert(GetPntCoords(1).y == DBL_MAX);
|
|
SetXCoord(1, bb_min.x - delta_x);
|
|
SetYCoord(1, bb_max.y + delta_y);
|
|
i = num_pnts - 2;
|
|
assert(GetPntCoords(i).x == DBL_MAX);
|
|
assert(GetPntCoords(i).y == -DBL_MAX);
|
|
SetXCoord(i, bb_max.x + delta_x);
|
|
SetYCoord(i, bb_min.y - delta_y);
|
|
i = num_pnts - 1;
|
|
assert(GetPntCoords(i).x == DBL_MAX);
|
|
assert(GetPntCoords(i).y == DBL_MAX);
|
|
SetXCoord(i, bb_max.x + delta_x);
|
|
SetYCoord(i, bb_max.y + delta_y);
|
|
|
|
SetMaxOffset(0.49 * sqrt(delta_x * delta_x + delta_y * delta_y));
|
|
|
|
delta_x = bb_max.x - bb_min.x + 2.0 * delta_x;
|
|
delta_y = bb_max.y - bb_min.y + 2.0 * delta_y;
|
|
|
|
SetRootTooLarge(sqrt(delta_x * delta_x + delta_y * delta_y));
|
|
|
|
bbox_added = true;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/* */
|
|
/* scale the data if necessary. */
|
|
/* */
|
|
void vroniObject::ScaleData(void)
|
|
{
|
|
int i, k;
|
|
double xy, x_ext, y_ext;
|
|
|
|
x_ext = bb_max.x - bb_min.x;
|
|
y_ext = bb_max.y - bb_min.y;
|
|
xy = VroniMax(x_ext, y_ext);
|
|
xy = VroniMax(xy, ZERO);
|
|
scale_factor = 1.0;
|
|
|
|
shift.x = (bb_min.x + bb_max.x)/2.0;
|
|
shift.y = (bb_min.y + bb_max.y)/2.0;
|
|
|
|
if (xy > (2.0 + ZERO)) {
|
|
do {
|
|
scale_factor /= 2.0;
|
|
} while ((xy * scale_factor) > (2.0 + ZERO));
|
|
data_scaled = true;
|
|
}
|
|
else if (xy < 0.5) {
|
|
do {
|
|
scale_factor *= 2.0;
|
|
} while ((xy * scale_factor) < 0.5);
|
|
data_scaled = true;
|
|
}
|
|
else if ((bb_max.x > ( 1.0 + ZERO)) || (bb_max.y > ( 1.0 + ZERO)) ||
|
|
(bb_min.x < ( 0.0 - ZERO)) || (bb_min.y < ( 0.0 - ZERO))) {
|
|
data_scaled = true;
|
|
}
|
|
|
|
if (data_scaled) {
|
|
k = num_pnts - 2;
|
|
for (i = 2; i < k; ++i) {
|
|
SetXCoord(i, (GetPntCoords(i).x - shift.x) * scale_factor);
|
|
SetYCoord(i, (GetPntCoords(i).y - shift.y) * scale_factor);
|
|
}
|
|
|
|
for (i = 0; i < num_arcs; ++i) {
|
|
arcs[i].c.x = (GetArcCenter(i).x - shift.x) * scale_factor;
|
|
arcs[i].c.y = (GetArcCenter(i).y - shift.y) * scale_factor;
|
|
arcs[i].r *= scale_factor;
|
|
}
|
|
|
|
bb_min.x = (bb_min.x - shift.x) * scale_factor;
|
|
bb_min.y = (bb_min.y - shift.y) * scale_factor;
|
|
bb_max.x = (bb_max.x - shift.x) * scale_factor;
|
|
bb_max.y = (bb_max.y - shift.y) * scale_factor;
|
|
}
|
|
else {
|
|
shift.x = 0.0;
|
|
shift.y = 0.0;
|
|
scale_factor = 1.0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
int vroniObject::SplitSeg(int i1, int i2)
|
|
{
|
|
int i3, i4;
|
|
|
|
assert(InSegsList(i1));
|
|
assert(InPntsList(i2));
|
|
|
|
i4 = Get2ndVtx(i1, SEG);
|
|
#ifdef EXT_APPL_SITES
|
|
i3 = StoreSeg(i2, i4, GetExtApplSeg(i1));
|
|
#else
|
|
i3 = StoreSeg(i2, i4);
|
|
#endif
|
|
Set2ndVtx(i1, SEG, i2);
|
|
|
|
restart = true;
|
|
|
|
return i3;
|
|
}
|
|
|
|
|
|
|
|
int vroniObject::SplitArc(int i1, int i2)
|
|
{
|
|
int i3, i4;
|
|
coord p3;
|
|
double radius;
|
|
|
|
assert(InArcsList(i1));
|
|
assert(InPntsList(i2));
|
|
|
|
#ifdef TRACE
|
|
if (center) {
|
|
printf("splitting arc %d at the point \n pnts[%d]=(%24.20f,%24.20f)\n",
|
|
i1, i2, pnts[i2].p.x, pnts[i2].p.y);
|
|
PrintSiteData(i1, ARC, "before split");
|
|
}
|
|
#endif
|
|
|
|
i4 = Get2ndVtx(i1, ARC);
|
|
p3 = GetArcCenter(i1);
|
|
#ifdef EXT_APPL_SITES
|
|
i3 = StoreArc(i2, i4, p3.x, p3.y, GetArcOrientation(i1), GetExtApplArc(i1));
|
|
#else
|
|
i3 = StoreArc(i2, i4, p3.x, p3.y, GetArcOrientation(i1));
|
|
#endif
|
|
Set2ndVtx(i1, ARC, i2);
|
|
|
|
radius = GetArcRadius(i1);
|
|
SetArcRadius(i3, radius);
|
|
|
|
#ifdef TRACE
|
|
if (center) {
|
|
PrintSiteData(i1, ARC, "old after split");
|
|
PrintSiteData(i3, ARC, "new after split");
|
|
}
|
|
#endif
|
|
|
|
restart = true;
|
|
|
|
return i3;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::MergePoints(int i1, int i2)
|
|
{
|
|
coord p, q, w;
|
|
|
|
p = GetPntCoords(i1);
|
|
q = GetPntCoords(i2);
|
|
w = MidPoint(p, q);
|
|
SetXCoord(i1, w.x);
|
|
SetYCoord(i1, w.y);
|
|
SetXCoord(i2, w.x);
|
|
SetYCoord(i2, w.y);
|
|
|
|
// MODIF visto che uno dei due punti viene cancellato, uniformo anche le ext_appl. Serve nel caso in cui
|
|
// uno dei due punti deriva da intersezione ( quindi non ha punto originario di riferimento)
|
|
if ( pnts[i1].ext_appl.second == -1)
|
|
pnts[i1].ext_appl = pnts[i2].ext_appl ;
|
|
else if ( pnts[i2].ext_appl.second == -1)
|
|
pnts[i2].ext_appl = pnts[i1].ext_appl ;
|
|
|
|
restart = true;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::ResetFlags(void)
|
|
{
|
|
int i, number;
|
|
|
|
for (i = 0; i < num_pnts; ++i) {
|
|
pnts[i].vd = NIL;
|
|
pnts[i].node = NIL;
|
|
pnts[i].vis = false;
|
|
pnts[i].s = false;
|
|
#ifdef GRAPHICS
|
|
pnts[i].draw = false;
|
|
#endif
|
|
}
|
|
|
|
for (i = 0; i < num_segs; ++i) {
|
|
segs[i].vd = NIL;
|
|
#ifdef GRAPHICS
|
|
segs[i].draw = false;
|
|
#endif
|
|
}
|
|
|
|
number = num_arcs;
|
|
|
|
for (i = 0; i < number; ++i) {
|
|
arcs[i].vd = NIL;
|
|
#ifdef GRAPHICS
|
|
arcs[i].draw = false;
|
|
#endif
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::RemoveSegment(int i)
|
|
{
|
|
int j;
|
|
|
|
ExtApplRemoveSeg;
|
|
|
|
j = num_segs - 1;
|
|
CopySegData(i, j);
|
|
#ifdef GRAPHICS
|
|
if (graphics) ResetDrawSite(j, SEG);
|
|
#endif
|
|
num_segs = j;
|
|
#ifdef GRAPHICS
|
|
if (graphics) UpdateBuffer();
|
|
#endif
|
|
|
|
restart = true;
|
|
|
|
++num_segs_deleted;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::RemoveArc(int i)
|
|
{
|
|
int j;
|
|
|
|
ExtApplRemoveArc;
|
|
|
|
j = num_arcs - 1;
|
|
CopyArcData(i, j);
|
|
#ifdef GRAPHICS
|
|
if (graphics) ResetDrawSite(j, ARC);
|
|
#endif
|
|
num_arcs = j;
|
|
|
|
restart = true;
|
|
++num_arcs_deleted;
|
|
|
|
return;
|
|
}
|
|
|
|
#ifdef ORDERED
|
|
int key_comp(const void *a, const void *b)
|
|
{
|
|
if (((ordered_sites*)a)->key > ((ordered_sites*)b)->key) return -1;
|
|
else if (((ordered_sites*)a)->key < ((ordered_sites*)b)->key) return 1;
|
|
else return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef SORTED
|
|
int key_comp(const void *a, const void *b)
|
|
{
|
|
#ifdef INVERSE
|
|
if (((sorted_sites*)a)->lgth < ((sorted_sites*)b)->lgth) return -1;
|
|
else if (((sorted_sites*)a)->lgth > ((sorted_sites*)b)->lgth) return 1;
|
|
else return 0;
|
|
#else
|
|
if (((sorted_sites*)a)->lgth > ((sorted_sites*)b)->lgth) return -1;
|
|
else if (((sorted_sites*)a)->lgth < ((sorted_sites*)b)->lgth) return 1;
|
|
else return 0;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
void vroniObject::InitSiteOrder(t_site type)
|
|
{
|
|
int i, number;
|
|
int start;
|
|
#ifdef FORCED
|
|
FILE *input;
|
|
#endif
|
|
|
|
if (type == PNT) {
|
|
number = num_pnts - 2;
|
|
start = 3;
|
|
}
|
|
else if (type == SEG) {
|
|
number = num_segs;
|
|
start = 0;
|
|
}
|
|
else if (type == ARC) {
|
|
number = num_arcs;
|
|
start = 0;
|
|
}
|
|
else {
|
|
VD_Warning("InitSiteOrder - unknown site type!");
|
|
return;
|
|
}
|
|
|
|
#ifdef ORDERED /* ORDERED sites */
|
|
|
|
if (max_num_ord_sites < number) {
|
|
max_num_ord_sites = number;
|
|
gentlyResizeSTLVector(ord_sites, max_num_ord_sites, "data:ord_sites");
|
|
}
|
|
|
|
if (type == PNT) {
|
|
assert(start == 3);
|
|
for (i = 3; i < number; ++i) {
|
|
ord_sites[i-3].ind = i;
|
|
ord_sites[i-3].key = pnts[i].key;
|
|
}
|
|
}
|
|
else if (type == SEG) {
|
|
for (i = 0; i < number; ++i) {
|
|
ord_sites[i].ind = i;
|
|
ord_sites[i].key = segs[i].key;
|
|
}
|
|
}
|
|
else if (type == ARC) {
|
|
for (i = 0; i < number; ++i) {
|
|
ord_sites[i].ind = i;
|
|
ord_sites[i].key = arcs[i].key;
|
|
}
|
|
}
|
|
num_ord_sites = number - start;
|
|
|
|
/* */
|
|
/* sort segs according to their original keys */
|
|
/* */
|
|
qsort(&ord_sites[0], num_ord_sites, sizeof(ordered_sites), key_comp);
|
|
|
|
#else
|
|
#ifdef SORTED /* SORTED sites */
|
|
|
|
if (max_num_srt_sites < number) {
|
|
max_num_srt_sites = number;
|
|
gentlyResizeSTLVector(srt_sites, max_num_srt_sites, "data:srt_sites");
|
|
}
|
|
|
|
if (type == SEG) {
|
|
for (i = start; i < number; ++i) {
|
|
srt_sites[i].ind = i;
|
|
srt_sites[i].lgth = GetSegLgth(i);
|
|
}
|
|
/* */
|
|
/* sort segs according to their length, either in increasing or in */
|
|
/* decreasing (-DINVERSE) order. */
|
|
/* */
|
|
num_srt_sites = number - start;
|
|
qsort(&srt_sites[0], num_srt_sites, sizeof(sorted_sites), key_comp);
|
|
}
|
|
else {
|
|
num_srt_sites = 0;
|
|
for (i = start; i < number; ++i) {
|
|
srt_sites[num_srt_sites].ind = i;
|
|
++num_srt_sites;
|
|
}
|
|
}
|
|
|
|
#else
|
|
#ifdef RANDOM /* RANDOM sites */
|
|
|
|
if (m_max_num_rnd_sites < number) {
|
|
m_max_num_rnd_sites = number;
|
|
gentlyResizeSTLVector(m_rnd_sites, m_max_num_rnd_sites,
|
|
"data:rnd_sites");
|
|
}
|
|
|
|
m_num_rnd_sites = 0;
|
|
for (i = start; i < number; ++i) {
|
|
m_rnd_sites[m_num_rnd_sites] = i;
|
|
++m_num_rnd_sites;
|
|
}
|
|
m_cur_rnd_sites = m_num_rnd_sites;
|
|
|
|
#else
|
|
#ifdef FORCED /* FORCED site order */
|
|
|
|
if (max_num_fcd_sites < number) {
|
|
max_num_fcd_sites = number;
|
|
gentlyResizeSTLVector(fcd_sites, max_num_fcd_sites, "data:fcd_sites");
|
|
}
|
|
|
|
if (type == PNT) input = OpenFileVD("forced_order_pnts.txt", "r");
|
|
else if (type == SEG) input = OpenFileVD("forced_order_segs.txt", "r");
|
|
else input = OpenFileVD("forced_order_arcs.txt", "r");
|
|
|
|
number -= start;
|
|
|
|
for (i = 0; i < number; ++i) {
|
|
if (EOF == fscanf(input, "%d", &(fcd_sites[i])))
|
|
throw std::runtime_error("VRONI error: InitSiteOrder() - premature end of file!");
|
|
}
|
|
num_fcd_sites = number;
|
|
cur_fcd_sites = 0;
|
|
|
|
#else /* no specific site order */
|
|
|
|
if (type == PNT) nosr = 3;
|
|
else nosr = 0;
|
|
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
int vroniObject::GetNextSite(void)
|
|
{
|
|
#ifdef ORDERED /* ORDERED sites */
|
|
assert(num_ord_sites > 0);
|
|
--num_ord_sites;
|
|
return (ord_sites[num_ord_sites].ind);
|
|
#else
|
|
#ifdef SORTED /* SORTED sites */
|
|
assert(num_srt_sites > 0);
|
|
--num_srt_sites;
|
|
return (srt_sites[num_srt_sites].ind);
|
|
#else
|
|
#ifdef RANDOM /* RANDOM sites */
|
|
int i, j;
|
|
assert(m_cur_rnd_sites > 0);
|
|
assert(m_cur_rnd_sites <= m_num_rnd_sites);
|
|
RandomInteger(m_cur_rnd_sites, i);
|
|
assert((i >= 0) && (i < m_cur_rnd_sites));
|
|
j = m_rnd_sites[i];
|
|
--m_cur_rnd_sites;
|
|
m_rnd_sites[i] = m_rnd_sites[m_cur_rnd_sites];
|
|
return j;
|
|
#else
|
|
#ifdef FORCED /* FORCED sites */
|
|
assert(cur_fcd_sites < num_fcd_sites);
|
|
return (fcd_sites[cur_fcd_sites++]);
|
|
#else /* no specific order */
|
|
int j;
|
|
j = nosr;
|
|
++nosr;
|
|
return j;;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::DXFStartPoly(void)
|
|
{
|
|
dxf_poly_started = true;
|
|
dxf_vertex_added = false;
|
|
dxf_vertex_index = NIL;
|
|
dxf_vertex_first = NIL;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void vroniObject::DXFClosePoly(double bulge)
|
|
{
|
|
int i3;
|
|
coord center;
|
|
double radius;
|
|
int attr;
|
|
|
|
assert(dxf_vertex_added);
|
|
attr = SEG;
|
|
HandleBulge(GetPntCoords(dxf_vertex_index), GetPntCoords(dxf_vertex_first),
|
|
&bulge, ¢er, &radius, &attr);
|
|
|
|
if (attr == SEG) {
|
|
#ifdef EXT_APPL_SITES
|
|
i3 = StoreSeg(dxf_vertex_index, dxf_vertex_first, eas_NIL);
|
|
#else
|
|
i3 = StoreSeg(dxf_vertex_index, dxf_vertex_first);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) AddSegToBuffer(i3, SegColor);
|
|
#endif
|
|
}
|
|
else {
|
|
#ifdef EXT_APPL_SITES
|
|
if (attr == ARC)
|
|
i3 = StoreArc(dxf_vertex_index, dxf_vertex_first, center.x, center.y,
|
|
true, eas_NIL);
|
|
else
|
|
i3 = StoreArc(dxf_vertex_first, dxf_vertex_index, center.x, center.y,
|
|
false, eas_NIL);
|
|
#else
|
|
if (attr == ARC)
|
|
i3 = StoreArc(dxf_vertex_index, dxf_vertex_first, center.x, center.y,
|
|
true);
|
|
else
|
|
i3 = StoreArc(dxf_vertex_first, dxf_vertex_index, center.x, center.y,
|
|
false);
|
|
#endif
|
|
#ifdef GRAPHICS
|
|
if (graphics) AddArcToBuffer(i3, SegColor);
|
|
#endif
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::DXFAddPolyVertex(double_arg xc1, double_arg yc1, double bulge)
|
|
{
|
|
int attr;
|
|
coord center, p2;
|
|
double radius;
|
|
|
|
if (!dxf_poly_started) {
|
|
DXFStartPoly();
|
|
}
|
|
if (dxf_vertex_added) {
|
|
assert(InPntsList(dxf_vertex_index));
|
|
attr = SEG;
|
|
p2 = MakeVec( xc1, yc1);
|
|
HandleBulge(GetPntCoords(dxf_vertex_index), p2,
|
|
&bulge, ¢er, &radius, &attr);
|
|
if (attr == SEG) {
|
|
#ifdef EXT_APPL_SITES
|
|
AddSeg(&dxf_vertex_index, xc1, yc1, eas_NIL);
|
|
#else
|
|
AddSeg(&dxf_vertex_index, xc1, yc1);
|
|
#endif
|
|
}
|
|
else {
|
|
#ifdef EXT_APPL_SITES
|
|
AddArc(&dxf_vertex_index, xc1, yc1, center.x, center.y,
|
|
attr, eas_NIL);
|
|
#else
|
|
AddArc(&dxf_vertex_index, xc1, yc1, center.x, center.y,
|
|
attr);
|
|
#endif
|
|
}
|
|
}
|
|
else {
|
|
#ifdef EXT_APPL_PNTS
|
|
dxf_vertex_index = HandlePnt(xc1, yc1, eap_NIL);
|
|
#else
|
|
dxf_vertex_index = HandlePnt(xc1, yc1);
|
|
#endif
|
|
dxf_vertex_added = true;
|
|
dxf_vertex_first = dxf_vertex_index;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::CheckIsolatedPnts(void)
|
|
{
|
|
int i;
|
|
|
|
assert(bbox_added);
|
|
|
|
i = 2;
|
|
|
|
while (HasIncidentSite(i) || IsDeletedPnt(i)) ++i;
|
|
|
|
isolated_pnts = (i < (num_pnts - 2));
|
|
|
|
#ifdef TRACE
|
|
printf("i = %d, num_pnts = %d\n", i, num_pnts);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::PrintSiteData(int s, t_site t, const char *string)
|
|
{
|
|
if (t == PNT) {
|
|
assert(InPntsList(s));
|
|
FP_printf("%s, pnt %d: (%24.20f %24.20f), vd: %d, node: %d\n",
|
|
string, s, FP_PRNTARG(pnts[s].p.x), FP_PRNTARG(pnts[s].p.y),
|
|
FP_PRNTARG(pnts[s].vd), FP_PRNTARG(pnts[s].node));
|
|
if (pnts[s].s) printf(" incident site, ");
|
|
else printf(" no incident site, ");
|
|
if (pnts[s].vis) printf("visited, ");
|
|
else printf("not visited, ");
|
|
if (pnts[s].del) printf("to be deleted.\n");
|
|
else printf("to be kept.\n");
|
|
}
|
|
else if (t == SEG) {
|
|
assert(InSegsList(s));
|
|
printf("%s, seg %d: start = %d, end = %d, vd = %d\n",
|
|
string, s, segs[s].i1, segs[s].i2, segs[s].vd);
|
|
}
|
|
else if (t == ARC) {
|
|
assert(InArcsList(s));
|
|
FP_printf("%s, arc %3d: start = %3d, end = %3d, vd = %3d, r = %24.20f\n",
|
|
string, s, arcs[s].i1, arcs[s].i2, arcs[s].vd,
|
|
FP_PRNTARG(arcs[s].r));
|
|
FP_printf(" start pnts[%3d]: (%24.20f %24.20f)\n", arcs[s].i1,
|
|
FP_PRNTARG(pnts[arcs[s].i1].p.x),
|
|
FP_PRNTARG(pnts[arcs[s].i1].p.y));
|
|
FP_printf(" end pnts[%3d]: (%24.20f %24.20f)\n", arcs[s].i2,
|
|
FP_PRNTARG(pnts[arcs[s].i2].p.x),
|
|
FP_PRNTARG(pnts[arcs[s].i2].p.y));
|
|
FP_printf(" center: (%24.20f %24.20f)\n",
|
|
FP_PRNTARG(arcs[s].c.x), FP_PRNTARG(arcs[s].c.y));
|
|
FP_printf(" start normal: (%24.20f %24.20f)\n",
|
|
FP_PRNTARG(arcs[s].ns.x), FP_PRNTARG(arcs[s].ns.y));
|
|
FP_printf(" end normal: (%24.20f %24.20f)\n",
|
|
FP_PRNTARG(arcs[s].ne.x), FP_PRNTARG(arcs[s].ne.y));
|
|
FP_printf(" chord: (%24.20f %24.20f\n",
|
|
FP_PRNTARG(arcs[s].a), FP_PRNTARG(arcs[s].b));
|
|
FP_printf(" %24.20f)\n",
|
|
FP_PRNTARG(arcs[s].d));
|
|
}
|
|
else {
|
|
printf("information for site %3d of type %3d is not available\n", s, t);
|
|
}
|
|
return;
|
|
}
|
|
#ifdef TRACE
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef GRAPHICS
|
|
void vroniObject::FindClosestPnt(double_arg x1, double_arg y1)
|
|
{
|
|
double dist, dist_min, x, y;
|
|
int i, i_min;
|
|
|
|
i = 2;
|
|
i_min = 2;
|
|
x = x1 - pnts[i].p.x;
|
|
y = y1 - pnts[i].p.y;
|
|
dist_min = x * x + y * y;
|
|
|
|
for (i = 3; i < num_pnts-2; ++i) {
|
|
if (pnts[i].draw) {
|
|
x = x1 - pnts[i].p.x;
|
|
y = y1 - pnts[i].p.y;
|
|
dist = x * x + y * y;
|
|
if (dist < dist_min) {
|
|
dist_min = dist;
|
|
i_min = i;
|
|
}
|
|
}
|
|
}
|
|
AddToCurBuffer(i_min, PNT, AlertColor);
|
|
#ifdef TRACE
|
|
PrintSiteData(i_min, PNT, "closest");
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void vroniObject::FindClosestSeg(double_arg x1, double_arg y1)
|
|
{
|
|
double dist, dist_min, lgth, a, b, c;
|
|
int i, i_min;
|
|
coord p, q;
|
|
|
|
i = 0;
|
|
i_min = 0;
|
|
p.x = x1;
|
|
p.y = y1;
|
|
lgth = GetSegLgth(i);
|
|
assert(!(eq(lgth, ZERO)));
|
|
GetSegEqnData(i, &a, &b, &c);
|
|
dist_min = AbsPntLineDist(a, b, c, p);
|
|
|
|
for (i = 1; i < num_segs; ++i) {
|
|
if (segs[i].draw) {
|
|
lgth = GetSegLgth(i);
|
|
assert(!(eq(lgth, ZERO)));
|
|
GetSegEqnData(i, &a, &b, &c);
|
|
q = GetSegStartCoord(i);
|
|
dist = AbsPntSegDist(q, p, a, b, c, lgth, TINY);
|
|
if (dist < dist_min) {
|
|
dist_min = dist;
|
|
i_min = i;
|
|
}
|
|
}
|
|
}
|
|
AddToCurBuffer(i_min, SEG, AlertColor);
|
|
#ifdef TRACE
|
|
PrintSiteData(i_min, SEG, "closest");
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
#include "ext_appl_data.cc"
|