1## Copyright (C) 2021 David Legland
2## All rights reserved.
3##
4## Redistribution and use in source and binary forms, with or without
5## modification, are permitted provided that the following conditions are met:
6##
7##     1 Redistributions of source code must retain the above copyright notice,
8##       this list of conditions and the following disclaimer.
9##     2 Redistributions in binary form must reproduce the above copyright
10##       notice, this list of conditions and the following disclaimer in the
11##       documentation and/or other materials provided with the distribution.
12##
13## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
14## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
17## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23##
24## The views and conclusions contained in the software and documentation are
25## those of the authors and should not be interpreted as representing official
26## policies, either expressed or implied, of the copyright holders.
27
28function perim = ellipsePerimeter(ellipse, varargin)
29%ELLIPSEPERIMETER Perimeter of an ellipse.
30%
31%   P = ellipsePerimeter(ELLI)
32%   Computes the perimeter of an ellipse, using numerical integration.
33%   ELLI is an ellipse, given using one of the following formats:
34%   * a 1-by-5 row vector containing coordinates of center, length of
35%       semi-axes, and orientation in degrees
36%   * a 1-by-2 row vector containing only the lengths of the semi-axes.
37%   The result
38%
39%   P = ellipsePerimeter(ELLI, TOL)
40%   Specify the relative tolerance for numerical integration.
41%
42%
43%   Example
44%   P = ellipsePerimeter([30 40 30 10 15])
45%   P =
46%       133.6489
47%
48%   See also
49%     ellipses2d, drawEllipse
50%
51%
52
53% ------
54% Author: David Legland
55% e-mail: david.legland@grignon.inra.fr
56% Created: 2012-02-20,    using Matlab 7.9.0.529 (R2009b)
57% Copyright 2012 INRA - Cepia Software Platform.
58
59%% Parse input argument
60
61if size(ellipse, 2) == 5
62    ra = ellipse(:, 3);
63    rb = ellipse(:, 4);
64
65elseif size(ellipse, 2) == 2
66    ra = ellipse(:, 1);
67    rb = ellipse(:, 2);
68
69elseif size(ellipse, 2) == 1
70    ra = ellipse;
71    rb = varargin{1};
72    varargin(1) = [];
73
74end
75
76% relative tolerance
77tol = 1e-10;
78if ~isempty(varargin)
79    tol = varargin{1};
80end
81
82
83%% Numerical integration
84
85n = length(ra);
86
87perim = zeros(n, 1);
88
89for i = 1:n
90    % function to integrate
91    f = @(t) sqrt(ra(i) .^ 2 .* cos(t) .^ 2 + rb(i) .^ 2 .* sin(t) .^ 2) ;
92
93    % absolute tolerance from relative tolerance
94    eps = tol * max(ra(i), rb(i));
95
96    % integrate on first quadrant
97    if verLessThan('matlab', '7.14')
98        perim(i) = 4 * quad(f, 0, pi/2, eps); %#ok<DQUAD>
99    else
100        perim(i) = 4 * integral(f, 0, pi/2, 'AbsTol', eps);
101    end
102end
103
104