/*****************************************************************************/ /* */ /* 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 = VroniMin(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