fltk/src/fl_arc.cxx
Albrecht Schlosser f09e17c3c5 Remove $Id$ tags, update URL's, and more
- remove obsolete svn '$Id$' tags from all source files
- update .fl files and generated files accordingly
- replace 'http://www.fltk.org' URL's with 'https://...'
- replace bug report URL 'str.php' with 'bugs.php'
- remove trailing whitespace
- fix other whitespace errors flagged by Git
- add and/or fix missing or wrong standard headers
- convert tabs to spaces in all source files

The only relevant code changes are in the fluid/ folder where
some .fl files and other source files were used to generate
the '$Id' headers and footers.
2020-07-06 20:28:20 +02:00

91 lines
2.6 KiB
C++

//
// Arc functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2016 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
/**
\file fl_arc.cxx
\brief Utility functions for drawing arcs and circles.
*/
// Utility for drawing arcs and circles. They are added to
// the current fl_begin/fl_vertex/fl_end path.
// Incremental math implementation:
#include <FL/fl_draw.H>
#include <FL/math.h>
// avoid problems with some platforms that don't
// implement hypot.
static double _fl_hypot(double x, double y) {
return sqrt(x*x + y*y);
}
/**
\cond DriverDev
\addtogroup DriverDeveloper
\{
*/
/**
Draw an arc.
The default implementation draws an arc using other calls into the graphics
driver. There is no need to override the method unless the target platform
supports drawing arcs directly.
\see fl_arc(double x, double y, double r, double start, double end)
*/
void Fl_Graphics_Driver::arc(double x, double y, double r, double start, double end) {
// draw start point accurately:
double A = start*(M_PI/180); // Initial angle (radians)
double X = r*cos(A); // Initial displacement, (X,Y)
double Y = -r*sin(A); // from center to initial point
fl_vertex(x+X,y+Y); // Insert initial point
// Maximum arc length to approximate with chord with error <= 0.125
double epsilon; {
double r1 = _fl_hypot(fl_transform_dx(r,0), // Horizontal "radius"
fl_transform_dy(r,0));
double r2 = _fl_hypot(fl_transform_dx(0,r), // Vertical "radius"
fl_transform_dy(0,r));
if (r1 > r2) r1 = r2; // r1 = minimum "radius"
if (r1 < 2.) r1 = 2.; // radius for circa 9 chords/circle
epsilon = 2*acos(1.0 - 0.125/r1); // Maximum arc angle
}
A = end*(M_PI/180) - A; // Displacement angle (radians)
int i = int(ceil(fabs(A)/epsilon)); // Segments in approximation
if (i) {
epsilon = A/i; // Arc length for equal-size steps
double cos_e = cos(epsilon); // Rotation coefficients
double sin_e = sin(epsilon);
do {
double Xnew = cos_e*X + sin_e*Y;
Y = -sin_e*X + cos_e*Y;
fl_vertex(x + (X=Xnew), y + Y);
} while (--i);
}
}
/**
\}
\endcond
*/