f3e15b8c8d
- aggiunti file della libreria e progetto visual studio.
102 lines
4.7 KiB
C
102 lines
4.7 KiB
C
/*****************************************************************************/
|
|
/* */
|
|
/* 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<coord> & 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
|