739088af9f
- aggiornamento versione.
203 lines
7.9 KiB
C++
203 lines
7.9 KiB
C++
/*****************************************************************************/
|
|
/* */
|
|
/* Copyright (C) 2001-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 <stdio.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <float.h>
|
|
|
|
/* */
|
|
/* get my header files */
|
|
/* */
|
|
#include "fpkernel.h"
|
|
#include "vronivector.h"
|
|
#include "vroni_object.h"
|
|
#include "defs.h"
|
|
#include "numerics.h"
|
|
#include "offset.h"
|
|
|
|
#ifdef MIC
|
|
|
|
|
|
|
|
vr_bool vroniObject::GetMICStatus(void)
|
|
{
|
|
return MIC_computed;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::ResetMICStatus(void)
|
|
{
|
|
MIC_computed = false;
|
|
}
|
|
|
|
|
|
|
|
/* */
|
|
/* this function computes the maximum inscribed/empty circle (MIC). */
|
|
/* */
|
|
/* for closed contours, a one-sided computation of the MIC may be requested */
|
|
/* by specifying the run-time options "--left_offset" or "--right_offset". */
|
|
/* note that this function won't compute the MIC if no restriction to a */
|
|
/* particular side is specified. */
|
|
/* */
|
|
void vroniObject::ComputeMIC(vr_bool time, vr_bool left_mic, vr_bool right_mic,
|
|
coord *center, double *radius)
|
|
{
|
|
int e, n;
|
|
double t1, t2, t;
|
|
vr_bool unrestricted;
|
|
coord p;
|
|
|
|
assert(GetVDStatus());
|
|
assert(gt(scale_factor, ZERO));
|
|
|
|
if (GetNodesSqdFlag()) TakeSquareOfNodes();
|
|
if (!GetDeg2Flag()) InsertDegreeTwoNodes();
|
|
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
ResetCurBuffer();
|
|
}
|
|
#endif
|
|
|
|
if (left_mic && right_mic) {
|
|
left_mic = right_mic = false;
|
|
}
|
|
|
|
/* */
|
|
/* first call to this function. allocate memory and initialize the */
|
|
/* flags for the edge data. */
|
|
/* */
|
|
VD_Info("...computing maximum inscribed circle -- ");
|
|
if (time) cpu_time_mic = elapsed();
|
|
|
|
unrestricted = !(left_mic || right_mic);
|
|
if (unrestricted) {
|
|
if (time) cpu_time_mic = 0.0;
|
|
VD_Warning("ComputeMIC() - no interior region specified!");
|
|
MIC_computed = false;
|
|
return;
|
|
}
|
|
|
|
/* */
|
|
/* let the user call some application-specific function */
|
|
/* */
|
|
ExtApplFuncMICInit;
|
|
|
|
/* */
|
|
/* allocate memory and initialize the flags for the edge data, and find */
|
|
/* the center of the MIC on the fly. */
|
|
/* */
|
|
InitializeEdgeData(unrestricted, left_mic, true, &e);
|
|
|
|
/* */
|
|
/* the center of the MIC coincides with one node, n, of the VD edge e. */
|
|
/* */
|
|
if (e != NIL) {
|
|
GetEdgeParam(e, &t1, &t2);
|
|
if (t1 >= t2) {
|
|
t = t1;
|
|
n = GetStartNode(e);
|
|
}
|
|
else {
|
|
t = t2;
|
|
n = GetEndNode(e);
|
|
}
|
|
p = GetNodeCoord(n);
|
|
|
|
if (time) cpu_time_mic = elapsed();
|
|
VD_Info("done!\n");
|
|
MIC_computed = true;
|
|
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
AddCirToBuffer(p, t);
|
|
AddToCurBuffer(n, VDN, MICColor);
|
|
}
|
|
#endif
|
|
|
|
/* */
|
|
/* the MIC has radius t and coordinates (p.x, p.y). note that VRONI */
|
|
/* transforms the input data. thus, the MIC data has to be transformed */
|
|
/* back to the original ccordinate system as follows: */
|
|
/* */
|
|
center->x = UnscaleX(p.x);
|
|
center->y = UnscaleY(p.y);
|
|
*radius = UnscaleV(t);
|
|
/*
|
|
printf("center: %20.16f %20.16f\n", center->x, center->y);
|
|
printf("radius: %20.16f\n", *radius);
|
|
printf("1\n%20.16f %20.16f %20.16f %20.16f %20.16f %20.16f\n",
|
|
center->x - *radius, center->y, center->x + *radius, center->y, center->x, center->y);
|
|
printf("1\n%20.16f %20.16f %20.16f %20.16f %20.16f %20.16f\n",
|
|
center->x + *radius, center->y, center->x - *radius, center->y, center->x, center->y);
|
|
*/
|
|
|
|
|
|
/* */
|
|
/* let the user call some application-specific function */
|
|
/* */
|
|
ExtApplFuncMICDone;
|
|
}
|
|
else {
|
|
/* */
|
|
/* no valid MIC could be found. since every clearance disk of a VD */
|
|
/* node is a valid candidate for the MIC >>if<< the node lies on the */
|
|
/* appropriate side of the input sites, as requested by the user, this */
|
|
/* can only happen if the input sites do not form closed contours! */
|
|
/* (i.e., if no VD node lies on the appropriate side!) */
|
|
/* */
|
|
if (time) cpu_time_mic = elapsed();
|
|
MIC_computed = false;
|
|
|
|
VD_Info("done!\n");
|
|
VD_Warning("ComputeMIC() - MIC not found!");
|
|
|
|
/* */
|
|
/* let the user call some application-specific function */
|
|
/* */
|
|
ExtApplFuncMICNotFound;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
#ifdef GRAPHICS
|
|
void AddMICToBuffer(void)
|
|
{
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#include "ext_appl_mic.cc"
|
|
|
|
#endif
|