46#include <gsl/gsl_errno.h>
47#include <gsl/gsl_math.h>
48#include <gsl/gsl_min.h>
60 LFMEllipseArea(
double coeff)
61 : m_coeff(coeff*coeff)
66 coeff[0] = p[
X] * p[
Y];
70 fixed_term = p[
X] * p[
X] + m_coeff * p[
Y] * p[
Y];
96 size_t sz = points.size();
99 THROW_RANGEERROR(
"fitting error: too few points passed");
101 LFMEllipseArea model(coeff);
104 for (
size_t i = 0; i < sz; ++i)
106 fitter.append(points[i]);
112 model.instance(e, fitter.result(z));
120 typedef std::vector<Point> point_set_t;
121 const point_set_t & points = *
static_cast<point_set_t*
>(params);
139 typedef std::vector<Point> point_set_t;
140 const point_set_t & points = *
static_cast<point_set_t*
>(params);
159 if (gsl_errno == GSL_EINVAL)
161 std::cerr <<
"gsl: " << file <<
":" << line <<
" ERROR: " << reason << std::endl;
165 gsl_error(reason, file, line, gsl_errno);
174 int iter = 0, max_iter = 1000;
175 const gsl_min_fminimizer_type *T;
176 gsl_min_fminimizer *s;
178 double a = 1e-2, b = 1e2;
182 F.params =
static_cast<void*
>(&points);
185 T = gsl_min_fminimizer_brent;
186 s = gsl_min_fminimizer_alloc (T);
187 gsl_min_fminimizer_set (s, &F, m, a, b);
203 status = gsl_min_fminimizer_iterate (s);
205 m = gsl_min_fminimizer_x_minimum (s);
206 a = gsl_min_fminimizer_x_lower (s);
207 b = gsl_min_fminimizer_x_upper (s);
210 = gsl_min_test_interval (a, b, 1e-3, 0.0);
220 while (status == GSL_CONTINUE && iter < max_iter);
222 gsl_min_fminimizer_free (s);
224 if (status != GSL_SUCCESS)
return 0;
231class EllipseAreaMinimizer :
public Toy
234 void draw(
cairo_t *cr, std::ostringstream *notify,
235 int width,
int height,
bool save, std::ostringstream *timer_stream)
override
238 toggles[0].bounds =
Rect( toggle_sp, toggle_sp +
Point(135,25) );
240 bool non_convex =
false;
241 for(
auto & pt : psh.pts) {
248 std::vector<Point> boundary(ch.begin(), ch.end());
262 std::cerr << exc.
what() << std::endl;
268 cairo_set_line_width (cr, 0.3);
269 draw_elliptical_arc_with_cairo( cr,
270 e.center(
X), e.center(
Y),
275 *notify <<
"Area: " << e.ray(
X)*e.ray(
Y);
277 *notify <<
"Perimeter: " << 2* (e.ray(
X) + e.ray(
Y));
283 void draw_elliptical_arc_with_cairo(
285 double _cx,
double _cy,
286 double _rx,
double _ry,
287 double _sa,
double _ea,
291 double cos_rot_angle = std::cos(_ra);
292 double sin_rot_angle = std::sin(_ra);
293 cairo_matrix_t transform_matrix;
294 cairo_matrix_init( &transform_matrix,
295 _rx * cos_rot_angle, _rx * sin_rot_angle,
296 -_ry * sin_rot_angle, _ry * cos_rot_angle,
300 cairo_transform(cr, &transform_matrix);
301 cairo_arc(cr, 0, 0, 1, _sa, _ea);
306 EllipseAreaMinimizer()
313 psh.pts[0] =
Point(450, 250);
314 psh.pts[1] =
Point(250, 100);
315 psh.pts[2] =
Point(250, 400);
316 psh.pts[3] =
Point(400, 320);
320 toggles.emplace_back(
"Area/Perimeter",
true);
321 handles.push_back(&(toggles[0]));
328 std::vector<Toggle> toggles;
336 init( argc, argv,
new EllipseAreaMinimizer(), 600, 600 );
Various utility functions.
Set of all points at a fixed distance from the center.
void fit(std::vector< Point > const &points)
Fit the circle to the passed points using the least squares method.
Convex hull based on the Andrew's monotone chain algorithm.
Set of points with a constant sum of distances from two foci.
Coord ray(Dim2 d) const
Get one ray of the ellipse.
void setCoefficients(double A, double B, double C, double D, double E, double F)
Set an ellipse by solving its implicit equation.
const char * what() const noexcept override
Two-dimensional point that doubles as a vector.
Axis aligned, non-empty rectangle.
virtual void first_time(int, char **)
vector< Handle * > handles
virtual void save(FILE *f)
virtual void draw(cairo_t *cr, std::ostringstream *notify, int w, int h, bool save, std::ostringstream *timing_stream)
void no_minimum_error_handler(const char *reason, const char *file, int line, int gsl_errno)
double perimeter_goal(double coeff, void *params)
double area_goal(double coeff, void *params)
Ellipse fitting(std::vector< Point > const &points, double coeff)
double minimizer(std::vector< Point > &points, goal_function_type *gf)
double goal_function_type(double coeff, void *params)
Various utility functions.
void cairo_set_source_rgba(cairo_t *cr, colour c)
void init(int argc, char **argv, Toy *t, int width=600, int height=600)