./PaxHeaders/matgeom-1.2.40000644000000000000000000000013214576357161012324 xustar0030 mtime=1710874225.202193284 30 atime=1710874225.222193264 30 ctime=1710874225.222193264 matgeom-1.2.4/0000755000175000017500000000000014576357161014024 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/PaxHeaders/inst0000644000000000000000000000013214576357161013144 xustar0030 mtime=1710874225.178193307 30 atime=1710874225.222193264 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/0000755000175000017500000000000014576357161015001 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/PaxHeaders/geom3d0000644000000000000000000000013214576357160014321 xustar0030 mtime=1710874224.418194033 30 atime=1710874225.222193264 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/0000755000175000017500000000000014576357160016156 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/geom3d/PaxHeaders/transforms3d.m0000644000000000000000000000013214576357161017202 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/transforms3d.m0000644000175000017500000000546714576357161020776 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function transforms3d(varargin) %TRANSFORMS3D Conventions for manipulating 3D affine transforms. % % By 'transform' we mean an affine transform. A 3D affine transform % is represented by a 4*4 matrix. The last row of the matrix is equal to % [0 0 0 1]. % % % % Example: % % create a translation by the vector [10 20 30]: % T = createTranslation3d([10 20 30]); % % Transform a basic point: % PT1 = [4 5 6]; % PT2 = transformPoint3d(PT1, T) % % returns: % PT2 = % 14 25 36 % % See also % composeTransforms3d, createBasisTransform3d, createRotation3dLineAngle, % createRotationAboutPoint3d, createRotationOx, createRotationOy, % createRotationOz, createRotationVector3d, createRotationVectorPoint3d, % createScaling3d, createTranslation3d, eulerAnglesToRotation3d, % fitAffineTransform3d, isTransform3d, recenterTransform3d, % rotation3dAxisAndAngle, rotation3dToEulerAngles % transformCircle3d, transformLine3d, transformPlane3d, transformPoint3d, % transformPolygon3d, transformVector3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/geom3d/PaxHeaders/drawPlane3d.m0000644000000000000000000000013214576357161016721 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawPlane3d.m0000644000175000017500000001030314576357161020476 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function h = drawPlane3d(plane, varargin) %DRAWPLANE3D Draw a plane clipped by the current axes. % % drawPlane3d(PLANE) draws a plane of the format: % [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % % drawPlane3d(..., 'PropertyName', PropertyValue,...) % Sets the value of the specified patch property. Multiple property % values can be set with a single statement. See the function "patch" for % details. % % drawPlane3d(AX,...) % plots into AX instead of GCA. % % H = drawPlane3d(...) % returns a handle H to the patch object. % % Example % % Draw a plane, its main axes, and its normal vector % p0 = [1 2 3]; % v1 = [1 0 1]; % v2 = [0 -1 1]; % plane = [p0 v1 v2]; % figure; axis([-10 10 -10 10 -10 10]); hold on; view(3); % drawPlane3d(plane); % drawLine3d([p0 v1]); % drawLine3d([p0 v2]); % set(gcf, 'renderer', 'zbuffer'); % vn = crossProduct3d(v1, v2); % drawVector3d(p0, vn); % % See also % planes3d, createPlane, clipPlane, patch % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % add support for drawing multiple planes at once if size(plane, 1) > 1 nPlanes = size(plane, 1); hp = zeros(nPlanes, 1); for iPlane = 1:nPlanes hp(iPlane) = drawPlane3d(plane(iPlane, :), varargin{:}); end if nargout > 0 h = hp; end return; end % Parse and check inputs valFun = @(x) size(x,1)==1 && isPlane(x); defOpts.FaceColor = 'm'; [hAx, plane, varargin] = ... parseDrawInput(plane, valFun, 'patch', defOpts, varargin{:}); % extract axis bounds to crop plane lim = get(hAx, 'xlim'); xmin = lim(1); xmax = lim(2); lim = get(hAx, 'ylim'); ymin = lim(1); ymax = lim(2); lim = get(hAx, 'zlim'); zmin = lim(1); zmax = lim(2); % allocate array of handles nPlanes = size(plane, 1); hp = gobjects(1, nPlanes); % save hold state holdState = ishold(hAx); hold(hAx, 'on'); % iterate over planes for iPlane = 1:nPlanes % clip plane with current axis bounds poly = clipPlane(plane(iPlane,:), [xmin xmax ymin ymax zmin zmax]); % draw only non-empty intersections if ~isempty(poly) hp(iPlane) = patch( ... 'XData', poly(:, 1), ... 'YData', poly(:, 2), ... 'ZData', poly(:, 3), ... 'Parent', hAx, varargin{:}); end end % restore hold state if ~holdState hold(hAx, 'off'); end % Do not return axis if not requested % avoids output when called without semicolon if nargout > 0 h = hp; end matgeom-1.2.4/inst/geom3d/PaxHeaders/createRotationAboutPoint3d.m0000644000000000000000000000013214576357161021774 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createRotationAboutPoint3d.m0000644000175000017500000000452214576357161023557 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function TFM = createRotationAboutPoint3d(ROT, point) %CREATEROTATIONABOUTPOINT3D Rotate about a point using a rotation matrix. % % TFM = createRotationAboutPoint3d(ROT, POINT) Returns the transformation % matrix corresponding to a translation(-POINT), rotation with ROT and % translation(POINT). Ignores a possible translation in ROT(1:3,4). % % See also % transforms3d, transformPoint3d, createRotationOx, createRotationOy, % createRotationOz, createRotation3dLineAngle, createRotationVector3d, % createRotationVectorPoint3d % ------ % Author: oqilipo % E-mail: N/A % Created: 2021-01-31 % Copyright 2021-2023 % Extract only the rotation ROT = [ROT(1:3,1:3), [0 0 0]'; [0 0 0 1]]; TFM = createTranslation3d(point) * ROT * createTranslation3d(-point); end matgeom-1.2.4/inst/geom3d/PaxHeaders/boxes3d.m0000644000000000000000000000013214576357161016124 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/boxes3d.m0000644000175000017500000000433314576357161017707 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function boxes3d(varargin) %BOXES3D Description of functions operating on 3D boxes. % % A box defined by its coordinate extents: % BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. % % Example % % Draw a polyhedron together with its bounding box % [n e f]= createIcosahedron; % drawPolyhedron(n, f); % hold on; % drawBox3d(point3dBounds(n)) % % % See also % boundingBox3d, box3dVolume, drawBox3d % intersectBoxes3d, mergeBoxes3d, randomPointInBox3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform matgeom-1.2.4/inst/geom3d/PaxHeaders/reversePlane.m0000644000000000000000000000013214576357161017210 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/reversePlane.m0000644000175000017500000000432014576357161020767 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function plane = reversePlane(plane) %REVERSEPLANE Return same 3D plane but with opposite orientation. % % IP = reversePlane(PLANE); % Returns a plane contining the same ppints but with normal opposite to % that of PLANE. % If PLANE has the format [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2], then IP % will have following parameters: [x0 y0 z0 dx1 dy1 dz1 -dx2 -dy2 -dz2]. % % See also % createPlane, reverseLine3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-05-24, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform plane(:, 7:9) = -plane(:, 7:9); matgeom-1.2.4/inst/geom3d/PaxHeaders/createTranslation3d.m0000644000000000000000000000013214576357161020466 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createTranslation3d.m0000644000175000017500000000541514576357161022253 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createTranslation3d(varargin) %CREATETRANSLATION3D Create the 4x4 matrix of a 3D translation. % % usage: % TRANS = createTranslation3d(DX, DY, DZ); % return the translation corresponding to DX and DY. % The returned matrix has the form : % [1 0 0 DX] % [0 1 0 DY] % [0 0 1 DZ] % [0 0 0 1] % % TRANS = createTranslation3d(VECT); % return the translation corresponding to the given vector [x y z]. % % % See also % transforms3d, transformPoint3d, transformVector3d, % createRotationOx, createRotationOy, createRotationOz, createScaling3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if isempty(varargin) % assert translation with null vector dx = 0; dy = 0; dz = 0; elseif length(varargin)==1 % translation vector given in a single argument var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); else % translation vector given in 3 arguments dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; end % create the translation matrix trans = [1 0 0 dx ; 0 1 0 dy ; 0 0 1 dz; 0 0 0 1]; matgeom-1.2.4/inst/geom3d/PaxHeaders/randomAngle3d.m0000644000000000000000000000013214576357161017233 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/randomAngle3d.m0000644000175000017500000000541014576357161021013 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = randomAngle3d(varargin) %RANDOMANGLE3D Return a 3D angle uniformly distributed on unit sphere. % % usage % [THETA PHI] = randomAngle3d % Generate an angle unformly distributed on the surface of the unit % sphere. % % "Mathematical" convention is used: theta is the colatitude (angle with % vertical axis, 0 for north pole, +pi for south pole, pi/2 for points at % equator) with z=0. % phi is the same as matlab cart2sph: angle from Ox axis, counted % positively counter-clockwise. % % [THETA PHI] = randomAngle3d(N) % generates N random angles (N is a scalar). The result is a N-by-2 % array. % % Example: % % Draw some points on the surface of a sphere % figure; % drawSphere; hold on; % drawPoint3d(pts, '.'); % axis equal; % % See also % angles3d, sph2cart2, cart2sph2 % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - Cepia Software platform N = 1; if ~isempty(varargin) N = varargin{1}; end phi = 2*pi*rand(N, 1); theta = asin(2*rand(N, 1)-1) + pi/2; if nargout<2 var = [theta phi]; varargout{1} = var; else varargout{1} = theta; varargout{2} = phi; end matgeom-1.2.4/inst/geom3d/PaxHeaders/cyl2cart.m0000644000000000000000000000013214576357161016300 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/cyl2cart.m0000644000175000017500000000566414576357161020073 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cyl2cart(varargin) %CYL2CART Convert cylindrical to cartesian coordinates. % % CART = cyl2cart(CYL) % convert the 3D cylindrical coordinates of points CYL (given by % [THETA R Z] where THETA, R, and Z have the same size) into cartesian % coordinates CART, given by [X Y Z]. % The transforms is the following : % X = R*cos(THETA); % Y = R*sin(THETA); % Z remains inchanged. % % CART = cyl2cart(THETA, R, Z) % provides coordinates as 3 different parameters % % Example % cyl2cart([-1 0 2]) % gives : 4.7124 1.0000 2.0000 % % See also angles3d, cart2pol, cart2sph2, cart2cyl % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-03-23 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % process input parameters if length(varargin)==1 var = varargin{1}; theta = var(:,1); r = var(:,2); z = var(:,3); elseif length(varargin)==3 theta = varargin{1}; r = varargin{2}; z = varargin{3}; end % convert coordinates dim = size(theta); x = reshape(r(:).*cos(theta(:)), dim); y = reshape(r(:).*sin(theta(:)), dim); % process output parameters if nargout==0 ||nargout==1 if length(dim)>2 || dim(2)>1 varargout{1} = {x y z}; else varargout{1} = [x y z]; end elseif nargout==3 varargout{1} = x; varargout{2} = y; varargout{3} = z; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawCylinder.m0000644000000000000000000000013214576357161017204 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawCylinder.m0000644000175000017500000001601014576357161020762 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCylinder(varargin) %DRAWCYLINDER Draw a cylinder. % % drawCylinder(CYL) % Draws the cylinder CYL on the current axis. % CYL is a 1-by-7 row vector in the form [x1 y1 z1 x2 y2 z2 r] where: % * [x1 y1 z1] are the coordinates of starting point, % * [x2 y2 z2] are the coordinates of ending point, % * R is the radius of the cylinder % % drawCylinder(CYL, N) % Uses N points for discretizating the circles of the cylinder. Default % value is 32. % % drawCylinder(..., OPT) % with OPT = 'open' (default) or 'closed', specify if the bases of the % cylinder should be drawn. % % drawCylinder(..., 'FaceColor', COLOR) % Specifies the color of the cylinder. Any couple of parameters name and % value can be given as argument, and will be transfered to the 'surf' % matlab function % % drawCylinder(..., 'FaceAlpha', ALPHA) % Specifies the transparency of the cylinder and of the optionnal caps. % % drawCylinder(AX, ...) % Specifies the axis to draw on. AX should be a valid axis handle. % % H = drawCylinder(...) % Returns a handle to the patch representing the cylinder. % % % Examples: % % basic example % figure; drawCylinder([0 0 0 10 20 30 5]); % % % draw hollow cylinders % figure; drawCylinder([0 0 0 10 20 30 5], 'open'); % % % change cylinder color % figure; drawCylinder([0 0 0 10 20 30 5], 'FaceColor', 'r'); % % % change cylinder color using graphical handle % figure; % h = drawCylinder([0 0 0 10 20 30 5]); % set(h, 'facecolor', 'b'); % % % Draw three mutually intersecting cylinders % p0 = [10 10 10]; % p1 = p0 + 80 * [1 0 0]; % p2 = p0 + 80 * [0 1 0]; % p3 = p0 + 80 * [0 0 1]; % figure; axis equal; axis([0 100 0 100 0 100]); hold on % drawCylinder([p0 p1 10], 'FaceColor', 'r'); % drawCylinder([p0 p2 10], 'FaceColor', 'g'); % drawCylinder([p0 p3 10], 'FaceColor', 'b'); % axis equal % set(gcf, 'renderer', 'opengl') % view([60 30]); light; % % % draw cube skeleton % [v, e, f] = createCube; % figure; axis equal; axis([-0.2 1.2 -0.2 1.2 -0.2 1.2]); hold on; view(3); % cyls = [v(e(:,1), :) v(e(:,2),:) repmat(0.1, size(e, 1), 1)]; % drawCylinder(cyls); % light % % See also % cylinderMesh, drawEllipseCylinder, drawSphere, drawLine3d, surf % intersectLineCylinder, cylinderSurfaceArea % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-09-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% Input argument processing % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % input argument representing cylinders cyl = varargin{1}; varargin(1) = []; % process the case of multiple cylinders if iscell(cyl) hCyls = gobjects(length(cyl), 1); for i = 1:length(cyl) hCyls(i) = drawCylinder(hAx, cyl{i}, varargin{:}); end if nargout > 0 varargout{1} = hCyls; end return; elseif size(cyl, 1) > 1 hCyls = gobjects(size(cyl, 1), 1); for i = 1:size(cyl, 1) hCyls(i) = drawCylinder(hAx, cyl(i, :), varargin{:}); end if nargout > 0 varargout{1} = hCyls; end return; end % default values N = 32; closed = true; % check number of discretization steps if ~isempty(varargin) var = varargin{1}; if isnumeric(var) N = var; varargin = varargin(2:end); end end % check if cylinder must be closed or open if ~isempty(varargin) var = varargin{1}; if ischar(var) if strncmpi(var, 'open', 4) closed = false; varargin = varargin(2:end); elseif strncmpi(var, 'closed', 5) closed = true; varargin = varargin(2:end); end end end faceColor = 'g'; ind = find(strcmpi(varargin, 'FaceColor'), 1, 'last'); if ~isempty(ind) faceColor = varargin{ind+1}; varargin(ind:ind+1) = []; end % extract transparency alpha = 1; ind = find(strcmpi(varargin, 'FaceAlpha'), 1, 'last'); if ~isempty(ind) alpha = varargin{ind+1}; varargin(ind:ind+1) = []; end % add default drawing options varargin = [{'FaceColor', faceColor, 'edgeColor', 'none', 'FaceAlpha', alpha} varargin]; %% Computation of mesh coordinates % extreme points of cylinder p1 = cyl(1:3); p2 = cyl(4:6); % radius of cylinder r = cyl(7); % compute orientation angle of cylinder [theta, phi, rho] = cart2sph2d(p2 - p1); dphi = linspace(0, 2*pi, N+1); % generate a cylinder oriented upwards x = repmat(cos(dphi) * r, [2 1]); y = repmat(sin(dphi) * r, [2 1]); z = repmat([0 ; rho], [1 length(dphi)]); % transform points trans = localToGlobal3d(p1, theta, phi, 0); pts = transformPoint3d([x(:) y(:) z(:)], trans); % reshape transformed points x2 = reshape(pts(:,1), size(x)); y2 = reshape(pts(:,2), size(x)); z2 = reshape(pts(:,3), size(x)); %% Display cylinder mesh % plot the cylinder as a surface hCyl(1) = surf(hAx, x2, y2, z2, varargin{:}); % eventually plot the ends of the cylinder if closed hCyl(2)=patch(hAx, x2(1,:)', y2(1,:)', z2(1,:)', faceColor, 'edgeColor', 'none', 'FaceAlpha', alpha); hCyl(3)=patch(hAx, x2(2,:)', y2(2,:)', z2(2,:)', faceColor, 'edgeColor', 'none', 'FaceAlpha', alpha); gh = hggroup(hAx); set(hCyl,'Parent',gh) hCyl = gh; end % format ouptut if nargout == 1 varargout{1} = hCyl; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawCuboid.m0000644000000000000000000000013214576357161016640 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawCuboid.m0000644000175000017500000001062514576357161020424 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCuboid(varargin) %DRAWCUBOID Draw a 3D cuboid, eventually rotated. % % drawCuboid(CUBOID) % Displays a 3D cuboid on current axis. CUBOID is given by: % [XC YC ZC L W D YAW PITCH ROLL], % where (XC, YC, ZC) is the cuboid center, L, W and H are the lengths of % the cuboid main axes, and YAW PITCH ROLL are Euler angles representing % the cuboid orientation, in degrees. % % If cuboid is axis-aligned, it can be specified using only center and % side lengths: % CUBOID = [XC YC ZC L W H] % % Example % % Draw a basic rotated cuboid % figure; hold on; % drawCuboid([10 20 30 90 40 10 10 20 30], 'FaceColor', 'g'); % axis equal; % view(3); % % % Draw three "borromean" cuboids % figure; hold on; % drawCuboid([10 20 30 90 50 10], 'FaceColor', 'r'); % drawCuboid([10 20 30 50 10 90], 'FaceColor', 'g'); % drawCuboid([10 20 30 10 90 50], 'FaceColor', 'b'); % view(3); axis equal; % set(gcf, 'renderer', 'opengl') % % See also % meshes3d, polyhedra, createCube, drawEllipsoid, drawCube % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); cuboid = varargin{1}; varargin(1) = []; % default orientation phi = 0; theta = 0; psi = 0; %% Parses the input if nargin == 0 % no input: assumes cuboid with default shape xc = 0; yc = 0; zc = 0; a = 5; b = 4; c = 3; else % one argument: parses elements xc = cuboid(:,1); yc = cuboid(:,2); zc = cuboid(:,3); a = cuboid(:,4); b = cuboid(:,5); c = cuboid(:,6); if size(cuboid, 2) >= 9 k = pi / 180; phi = cuboid(:,7) * k; theta = cuboid(:,8) * k; psi = cuboid(:,9) * k; end end %% Compute cuboid coordinates % create unit centered cube [v, f] = createCube; v = bsxfun(@minus, v, mean(v, 1)); % convert unit basis to ellipsoid basis sca = createScaling3d(a, b, c); rotZ = createRotationOz(phi); rotY = createRotationOy(theta); rotX = createRotationOx(psi); tra = createTranslation3d([xc yc zc]); % concatenate transforms trans = tra * rotZ * rotY * rotX * sca; % transform mesh vertices [x, y, z] = transformPoint3d(v, trans); %% Process output if nargout == 0 % no output: draw the cuboid drawMesh(hAx, [x y z], f, varargin{:}); elseif nargout == 1 % one output: draw the cuboid and return handle varargout{1} = drawMesh(hAx, [x y z], f, varargin{:}); elseif nargout == 3 % 3 outputs: return computed coordinates varargout{1} = x; varargout{2} = y; varargout{3} = z; end matgeom-1.2.4/inst/geom3d/PaxHeaders/registerPoints3dAffine.m0000644000000000000000000000013214576357161021136 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/registerPoints3dAffine.m0000644000175000017500000000606314576357161022723 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [trans, points] = registerPoints3dAffine(points, target, varargin) %REGISTERPOINTS3DAFFINE Fit 3D affine transform using iterative algorithm. % % TRANS = registerPoints3dAffine(POINTS, TARGET) % Computes the affine transform that maps the shape defines by POINTS % onto the shape defined by the points TARGET. Both POINTS and TARGET are % N-by-3 array of point coordinates, not necessarily the same size. % The result TRANS is a 4-by-4 affine transform. % % TRANS = registerPoints3dAffine(POINTS, TARGET, NITER) % Specifies the number of iterations for the algorithm. % % [TRANS, POINTS2] = registerPoints3dAffine(...) % Also returns the set of transformed points. % % Example % registerPoints3dAffine % % See also % transforms3d, fitAffineTransform3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-02-24, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform nIters = 10; if ~isempty(varargin) nIters = varargin{1}; end % keep original points to transform them at each trans = [1 0 0 0;0 1 0 0;0 0 1 0;0 0 0 1]; for i = 1:nIters % identify target points for each source point inds = findClosestPoint(points, target); corrPoints = target(inds, :); % compute transform for current iteration trans_i = fitAffineTransform3d(points, corrPoints); % apply transform, and update cumulated transform points = transformPoint3d(points, trans_i); trans = trans_i * trans; end matgeom-1.2.4/inst/geom3d/PaxHeaders/polygon3dNormalAngle.m0000644000000000000000000000013214576357161020613 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/polygon3dNormalAngle.m0000644000175000017500000000563614576357161022405 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = polygon3dNormalAngle(points, ind) %POLYGON3DNORMALANGLE Normal angle at a vertex of the 3D polygon. % % THETA = polygon3DNormalAngle(POLYGON, IND) % where POLYGON is a set of points, and IND is index of a point in % polygon. The function compute the angle of the normal cone localized at % this vertex. % If IND is a vector of indices, normal angle is computed for each vertex % specified by IND. % % Example % % create an equilateral triangle in space % poly3d = [1 1 0;-1 0 1;0 -1 -1]; % % compute each normal angle % theta = polygon3dNormalAngle(poly3d, 1:size(poly3d, 1)); % % sum of normal angles must be equal to 2*PI for simple polygons % sum(theta) % % IMPORTANT NOTE: works only for convex angles ! ! ! ! % % See also % polygons3d, faceNormalAngle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-30 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % number of points np = size(points, 1); % number of angles to compute nv = length(ind); theta = zeros(nv, 1); for i=1:nv p0 = points(ind(i), :); if ind(i)==1 p1 = points(np, :); else p1 = points(ind(i)-1, :); end if ind(i)==np p2 = points(1, :); else p2 = points(ind(i)+1, :); end theta(i) = pi - anglePoints3d(p1, p0, p2); end matgeom-1.2.4/inst/geom3d/PaxHeaders/cylinderSurfaceArea.m0000644000000000000000000000013214576357161020470 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/cylinderSurfaceArea.m0000644000175000017500000000474714576357161022264 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function S = cylinderSurfaceArea(cyl) %CYLINDERSURFACEAREA Surface area of a cylinder. % % S = cylinderSurfaceArea(CYL) % Computes the surface area of the cylinder defined by: % CYL = [X1 Y1 Z1 X2 Y2 Z2 R], % where [X1 Y1 Z1] and [X2 Y2 Z2] are the coordinates of the cylinder % extremities, and R is the cylinder radius. % The surface area of the cylinder comprises the surface area of the two % disk-shape end caps. % % Example % cyl = [0 0 0 1 0 0 1]; % cylinderSurfaceArea(cyl) % ans = % 12.5664 % % equals to 4*pi % % See also % geom3d, ellipsoidSurfaceArea, intersectLineCylinder % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-11-02, using Matlab 9.3.0.713579 (R2017b) % Copyright 2017-2023 INRA - Cepia Software Platform H = distancePoints3d(cyl(:, 1:3), cyl(:, 4:6)); R = cyl(:,7); S1 = 2*pi*R .* H; S2 = 2 * (pi * R.^2); S = S1 + S2; matgeom-1.2.4/inst/geom3d/PaxHeaders/projLineOnPlane.m0000644000000000000000000000013214576357161017614 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/projLineOnPlane.m0000644000175000017500000000524314576357161021400 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [newLine, isOrthogonal] = projLineOnPlane(line, plane) %PROJLINEONPLANE Return the orthogonal projection of a line on a plane. % % NEWLINE = PROJLINEONPLANE(LINE, PLANE) Returns the orthogonal % projection of LINE or multiple lines on the PLANE. % % [..., ISORTHOGONAL] = PROJLINEONPLANE(LINE, PLANE) Also returns if the % LINE is orthogonal to the PLANE. % % Example % plane = [.1 .2 .3 .4 .5 .6 .7 .8 .9]; % lines = [0 .3 0 1 0 0;0 .5 .5 0 0 1;... % .4 .1 .5 1 0 2;.2 .7 .1 0 1 0;... % plane(1:3) planeNormal(plane)]; % [newLines, isOrthogonal] = projLineOnPlane(lines, plane); % figure('color','w'); axis equal; view(3) % drawLine3d(lines,'b') % drawPlane3d(plane) % drawLine3d(newLines(~isOrthogonal,:), 'r') % % See also % planes3d, lines3d, intersectLinePlane, projPointOnPlane % ------ % Author: oqilipo % E-mail: N/A % Created: 2017-08-06 % Copyright 2017-2023 p1 = projPointOnPlane(line(:,1:3), plane); p2 = projPointOnPlane(line(:,1:3)+line(:,4:6), plane); newLine=createLine3d(p1, p2); isOrthogonal = ismembertol(p1,p2,'ByRows',true); matgeom-1.2.4/inst/geom3d/PaxHeaders/createSphere.m0000644000000000000000000000013214576357161017167 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createSphere.m0000644000175000017500000000510114576357161020744 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function sphere = createSphere(varargin) %CREATESPHERE Create a sphere containing 4 points. % % s = createSphere(p1, p2, p3, p4); % return in s the sphere common to the 4 pointsp1, p2, p3 and p4. % % Ref: P. Bourke % http://astronomy.swin.edu.au/~pbourke/geometry/spherefrom4/ % % See also % spheres, circles3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-03-22 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE if length(varargin)==4 pts = [varargin{1};varargin{2};varargin{3};varargin{4}]; elseif length(varargin)==1 pts = varargin{1}; else error('wrong number of arguments in createSphere'); end m1 = det([pts ones(4,1)]); s2 = sum(pts.*pts, 2); m2 = det([s2 pts(:,2) pts(:,3) ones(4,1)]); m3 = det([pts(:,1) s2 pts(:,3) ones(4,1)]); m4 = det([pts(:,1) pts(:,2) s2 ones(4,1)]); m5 = det([s2 pts]); x0 = m2*.5/m1; y0 = m3*.5/m1; z0 = m4*.5/m1; r = sqrt(x0*x0 + y0*y0 + z0*z0 - m5/m1); sphere = [x0 y0 z0 r]; matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectLineSphere.m0000644000000000000000000000013214576357161020534 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectLineSphere.m0000644000175000017500000001102214576357161022310 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = intersectLineSphere(line, sphere, varargin) %INTERSECTLINESPHERE Return intersection points between a line and a sphere. % % PTS = intersectLineSphere(LINE, SPHERE); % Returns the two points which are the intersection of the given line and % sphere. % LINE : [x0 y0 z0 dx dy dz] % SPHERE : [xc yc zc R] % PTS : [x1 y1 z1 ; x2 y2 z2] % If there is no intersection between the line and the sphere, return a % 2-by-3 array containing only NaN. % % Example % % draw the intersection between a sphere and a collection of parallel % % lines % sphere = [50.12 50.23 50.34 40]; % [x, y] = meshgrid(10:10:90, 10:10:90); % n = numel(x); % lines = [x(:) y(:) zeros(n,1) zeros(n,2) ones(n,1)]; % figure; hold on; axis equal; % axis([0 100 0 100 0 100]); view(3); % drawSphere(sphere); % drawLine3d(lines); % pts = intersectLineSphere(lines, sphere); % drawPoint3d(pts, 'rx'); % % % apply rotation on set of lines to check with non vertical lines % rot = eulerAnglesToRotation3d(20, 30, 10); % rot2 = recenterTransform3d(rot, [50 50 50]); % lines2 = transformLine3d(lines, rot2); % figure; hold on; axis equal; % axis([0 100 0 100 0 100]); view(3); % drawSphere(sphere); % drawLine3d(lines2); % pts2 = intersectLineSphere(lines2, sphere); % drawPoint3d(pts, 'rx'); % % See also % spheres, circles3d, intersectPlaneSphere % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% Process input arguments % check if user-defined tolerance is given tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % difference between centers dc = bsxfun(@minus, line(:, 1:3), sphere(:, 1:3)); % equation coefficients a = sum(line(:, 4:6) .* line(:, 4:6), 2); b = 2 * sum(bsxfun(@times, dc, line(:, 4:6)), 2); c = sum(dc.*dc, 2) - sphere(:,4).*sphere(:,4); % solve equation delta = b.*b - 4*a.*c; % initialize empty results points = NaN * ones(2 * size(delta, 1), 3); %% process couples with two intersection points % process couples with two intersection points inds = find(delta > tol); if ~isempty(inds) % delta positive: find two roots of second order equation u1 = (-b(inds) -sqrt(delta(inds))) / 2 ./ a(inds); u2 = (-b(inds) +sqrt(delta(inds))) / 2 ./ a(inds); % convert into 3D coordinate points(inds, :) = line(inds, 1:3) + bsxfun(@times, u1, line(inds, 4:6)); points(inds+length(delta),:) = line(inds, 1:3) + bsxfun(@times, u2, line(inds, 4:6)); end %% process couples with one intersection point % proces couples with two intersection points inds = find(abs(delta) < tol); if ~isempty(inds) % delta around zero: find unique root, and convert to 3D coord. u = -b(inds) / 2 ./ a(inds); % convert into 3D coordinate pts = line(inds, 1:3) + bsxfun(@times, u, line(inds, 4:6)); points(inds, :) = pts; points(inds+length(delta),:) = pts; end matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectRayPolygon3d.m0000644000000000000000000000013214576357161021030 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectRayPolygon3d.m0000644000175000017500000000763014576357161022616 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [inter, inside]= intersectRayPolygon3d(ray, poly) %INTERSECTRAYPOLYGON3D Intersection point of a 3D ray and a 3D polygon. % % INTER = intersectRayPolygon3d(RAY, POLY) % Compute coordinates of intersection point between the 3D ray RAY and % the 3D polygon POLY. RAY is a 1-by-6 row vector containing origin and % direction vector of the ray, POLY is a Np-by-3 array containing % coordinates of 3D polygon vertices. % INTER is a 1-by-3 row vector containing coordinates of intersection % point, or [NaN NaN NaN] if ray and polygon do not intersect. % % INTERS = intersectRayPolygon3d(RAYS, POLY) % If RAYS is a N-by-6 array representing several rays, the result % INTERS is a N-by-3 array containing coordinates of intersection of each % ray with the polygon. % % [INTER INSIDE] = intersectRayPolygon3d(RAY, POLY) % Also return a N-by-1 boolean array containing TRUE if both the polygon % and the corresponding ray contain the intersection point. % % Example % % Compute intersection between a 3D ray and a 3D triangle % pts3d = [3 0 0; 0 6 0;0 0 9]; % ray1 = [0 0 0 3 6 9]; % inter = intersectRayPolygon3d(ray1, pts3d) % inter = % 1 2 3 % % % keep only valid intersections with several rays % pts3d = [3 0 0; 0 6 0;0 0 9]; % rays = [0 0 0 3 6 9;10 0 0 1 2 3;3 6 9 3 6 9]; % [inter inside] = intersectRayPolygon3d(rays, pts3d); % inter(inside, :) % ans = % 1 2 3 % % See also % intersectRayPolygon, intersectLinePolygon3d, intersectLineTriangle3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % supporting plane of polygon vertices plane = createPlane(poly(1:3, :)); % intersection of 3D ray with the plane inter = intersectLinePlane(ray, plane); % project all points on reference plane pts2d = planePosition(projPointOnPlane(poly, plane), plane); pInt2d = planePosition(projPointOnPlane(inter, plane), plane); % need to check polygon orientation inPoly = xor(isPointInPolygon(pInt2d, pts2d), polygonArea(pts2d) < 0); onRay = linePosition3d(inter, ray) >= 0; inside = inPoly & onRay; % intersection points outside the polygon are set to NaN inter(~inside, :) = NaN; matgeom-1.2.4/inst/geom3d/PaxHeaders/clipPolygonByPlane3d.m0000644000000000000000000000013214576357161020556 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/clipPolygonByPlane3d.m0000644000175000017500000001200414576357161022333 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = clipPolygonByPlane3d(poly, plane, varargin) %CLIPPOLYGONBYPLANE3D clip a 3d polygon by a plane. % % POLY2 = clipPolygonByPlane3d(POLY, PLANE) % The 3d polygon POLY is clipped by the PLANE. The result POLY2: % - Represents the part of the polygon below the plane if the plane % intersects the polygon. % - Is the same as POLY if the polygon is below the plane and the plane % does not intersect the polygon. % - Is an empty 3d polygon [0x3] if the polygon is above the plane and % the plane does not intersect the polygon. % % Example % % 2d poly % pol = [6 7 6 6 5 4 3 2 2 1 2 2 6 ... % NaN 3 3 4 5 5 3 NaN 4 5 5; % 4 4 5 6 6 7 6 6 4 2 2 2 1 ... % NaN 4 5 5 4 4 3 NaN 3 2 3]'; % % Transform into 3d polygon % phi=-360+720*rand; % theta=-360+720*rand; % psi=-360+720*rand; % pol3d = transformPolygon3d(pol,eulerAnglesToRotation3d(phi, theta, psi)); % plane = [polygonCentroid3d(pol3d) rand(1,6)]; % % Clip polygon % pol3d2 = clipPolygonByPlane3d(pol3d, plane); % % Draw results % figure; hold on; axis equal; view(3) % drawPolygon3d(pol3d, 'linewidth', 2, 'color', 'y'); % drawPlane3d(plane) % drawPolygon3d(pol3d2, 'linewidth', 2, 'color', 'b'); % drawArrow3d(polygonCentroid3d(pol3d), ... % normalizeVector3d(planeNormal(plane))*3,'g') % % See also % poygons3d, intersectLinePolygon3d % ------ % Author: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2005-08-02 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE parser = inputParser; addRequired(parser, 'poly', @isPolygon3d) addRequired(parser, 'plane', @isPlane) addOptional(parser,'tolerance',1e-14, ... @(x) validateattributes(x,{'numeric'},{'scalar','>',0,'<',1})) parse(parser, poly, plane, varargin{:}); TOL = parser.Results.tolerance; [pol, inputFormat] = parsePolygon(poly, 'repetition'); % Check if the polygon's plane is the same as the clipping plane [~, dist] = planePosition(unique(pol,'rows'), plane); if all(dist 1) = 1; % difference of coordinates between projected point and base point p0 = bsxfun(@plus, edge(:,1:3), [t .* vl(:,1) t .* vl(:,2) t .* vl(:,3)]); p0 = bsxfun(@minus, point, p0); % compute distance between point and its projection on the edge dist = sqrt(sum(p0 .* p0, 2)); matgeom-1.2.4/inst/geom3d/PaxHeaders/clipRay3d.m0000644000000000000000000000013214576357161016407 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/clipRay3d.m0000644000175000017500000001156414576357161020176 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = clipRay3d(ray, box) %CLIPRAY3D Clip a 3D ray with a box and return a 3D edge. % % EDGE = clipRay3d(RAY, BOX) % Clips the ray RAY with the bounds given in BOX, and returns the % corresponding edge. % RAY is given as origin + direction vector: [X0 Y0 Z0 DX DY DZ] % BOX is given as [XMIN XMAX YMIN YMAX ZMIN ZMAX]. % The result EDGE is given as [X1 Y1 Z1 X2 Y2 Z2]. % % Example % % generate 50 random 3D rays % origin = [29 28 27]; % v = rand(50, 3); % v = v - centroid(v); % ray = [repmat(origin, size(v,1),1) v]; % % clip the rays with a 3D box % box = [10 40 10 40 10 40]; % edges = clipRay3d(ray, box); % % draw the resulting 3D edges % figure; axis equal; axis([0 50 0 50 0 50]); hold on; view(3); % drawBox3d(box); % drawEdge3d(edges, 'g'); % % See also % clipLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-05-25, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % get box limits xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); zmin = box(5); zmax = box(6); % extreme corners of the box p000 = [xmin ymin zmin]; p111 = [xmax ymax zmax]; % main vectors ex = [1 0 0]; ey = [0 1 0]; ez = [0 0 1]; % box faces parallel to Oxy planeZ0 = [p000 ex ey]; planeZ1 = [p111 ex ey]; % box faces parallel to Oxz planeY0 = [p000 ex ez]; planeY1 = [p111 ex ez]; % box faces parallel to Oyz planeX0 = [p000 ey ez]; planeX1 = [p111 ey ez]; % number of rays nRays = size(ray, 1); % allocate memory for result edge = NaN * ones(nRays, 6); % iterate over rays to clip for i = 1:nRays % compute intersection point of supporting line with each clipping plane ipZ0 = intersectLinePlane(ray(i,:), planeZ0); ipZ1 = intersectLinePlane(ray(i,:), planeZ1); ipY0 = intersectLinePlane(ray(i,:), planeY0); ipY1 = intersectLinePlane(ray(i,:), planeY1); ipX1 = intersectLinePlane(ray(i,:), planeX1); ipX0 = intersectLinePlane(ray(i,:), planeX0); % concatenate resulting points points = [ipX0;ipX1;ipY0;ipY1;ipZ0;ipZ1]; % compute position of each point on the ray pos = linePosition3d(points, ray(i,:)); % keep only defined points ind = find(~isnan(pos)); pos = pos(ind); points = points(ind,:); if isempty(pos) continue; end % sort points with respect to their position [pos, ind] = sort(pos); points = points(ind, :); % keep median points wrt to position. These points define the limit of % the clipped edge. nv = length(ind)/2; pos = pos([nv, nv+1]); points = points([nv nv+1], :); % case of second edge extremity before ray origin if pos(2) < 0 continue; end % case of first edge extremity before ray origin if pos(1) < 0 points(1,1:3) = ray(i,1:3); end % create resulting edge. edge(i,:) = [points(1, :) points(2, :)]; end % check that middle point of the edge is contained in the box midX = mean(edge(:, [1 4]), 2); xOk = xmin <= midX & midX <= xmax; midY = mean(edge(:, [2 5]), 2); yOk = ymin <= midY & midY <= ymax; midZ = mean(edge(:, [3 6]), 2); zOk = zmin <= midZ & midZ <= zmax; % if one of the bounding condition is not met, set edge to NaN edge (~(xOk & yOk & zOk), :) = NaN; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawCapsule.m0000644000000000000000000000013214576357161017027 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawCapsule.m0000644000175000017500000001463514576357161020620 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCapsule(varargin) %DRAWCAPSULE Draw a capsule. % % drawCapsule(CAP) % Draws the capsule CAP on the current axis. % CAP is a 1-by-7 row vector in the form [x1 y1 z1 x2 y2 z2 r] where: % * [x1 y1 z1] are the coordinates of starting point, % * [x2 y2 z2] are the coordinates of ending point, % * R is the radius of the cylinder and the two semi-spheres at the ends % % drawCapsule(CAP, N) % Uses N points for discretizating the circles of the cylinder and the % semi-spheres (domes). Default value is 32. % % drawCapsule(..., 'FaceColor', COLOR) % Specifies the color of the capsule. Any couple of parameters name and % value can be given as argument, and will be transfered to the 'surf' % matlab function % % drawCapsule(..., 'FaceAlpha', ALPHA) % Specifies the transparency of the capsule and of the semi-spheres. % % drawCapsule(..., NAME, VALUE); % Specifies one or several options using parameter name-value pairs. % Available options are usual drawing options, as well as: % 'nPhi' the number of arcs used for drawing the meridians % (for the semi-spheres and the cylinder) % 'nTheta' the number of circles used for drawing the parallels % (only for the semi-spheres at the ends of the capsule) % % drawCapsule(AX, ...) % Specifies the axis to draw on. AX should be a valid axis handle. % % H = drawCapsule(...) % Returns a handle to the patch representing the capsule. % % % Examples: % % basic example % figure; drawCapsule([0 0 0 10 20 30 5]); % % % change capsule color % figure; drawCapsule([0 0 0 10 20 30 5], 'FaceColor', 'r'); % % % change capsule color using graphical handle % figure; % h = drawCapsule([0 0 0 10 20 30 5]); % set(h, 'facecolor', 'b'); % % % Draw three mutually intersecting capsules % p0 = [10 10 10]; % p1 = p0 + 80 * [1 0 0]; % p2 = p0 + 80 * [0 1 0]; % p3 = p0 + 80 * [0 0 1]; % figure; axis equal; axis([0 100 0 100 0 100]); hold on % drawCapsule([p0 p1 10], 'FaceColor', 'r'); % drawCapsule([p0 p2 10], 'FaceColor', 'g'); % drawCapsule([p0 p3 10], 'FaceColor', 'b'); % axis equal % set(gcf, 'renderer', 'opengl') % view([60 30]); light; % % % draw cube skeleton % [v, e, f] = createCube; % figure; axis equal; axis([-0.2 1.2 -0.2 1.2 -0.2 1.2]); hold on; view(3); % caps = [v(e(:,1), :) v(e(:,2),:) repmat(0.1, size(e, 1), 1)]; % drawCapsule(caps); % light % % % Draw a capsule with high resolution % figure; % h = drawCapsule([10,20,10,50,70,40,6], 'nPhi', 360, 'nTheta', 180); % l = light; view(3); % % % See also % crawCylinder, drawDome, drawSphere % % ------ % Author: Moritz Schappler % E-mail: N/A % Created: 2013-07-27 % Copyright 2013-2023 %% Input argument processing % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % input argument representing capsules cap = varargin{1}; varargin(1) = []; % process the case of multiple capsules if iscell(cap) hCaps = gobjects(length(cap), 1); for i = 1:length(cap) hCaps(i) = drawCapsule(hAx, cap{i}, varargin{:}); end if nargout > 0 varargout{1} = hCaps; end return; elseif size(cap, 1) > 1 hCaps = gobjects(size(cap, 1), 3); for i = 1:size(cap, 1) hCaps(i,:) = drawCapsule(hAx, cap(i, :), varargin{:}); end if nargout > 0 varargout{1} = hCaps; end return; end faceColor = 'g'; ind = find(strcmpi(varargin, 'FaceColor'), 1, 'last'); if ~isempty(ind) faceColor = varargin{ind+1}; varargin(ind:ind+1) = []; end % extract transparency alpha = 1; ind = find(strcmpi(varargin, 'FaceAlpha'), 1, 'last'); if ~isempty(ind) alpha = varargin{ind+1}; varargin(ind:ind+1) = []; end % add default drawing options varargin = [{'FaceColor', faceColor, 'edgeColor', 'none', 'FaceAlpha', alpha} varargin]; % adjust drawing options for the cylinder. Options nPhi and nTheta may only % be given to the function drawDome, not drawCylinder options_cyl = ['open', varargin]; ind = find(strcmpi(options_cyl, 'nPhi'), 1, 'last'); if ~isempty(ind) ind = ind(1); nPhi = options_cyl{ind+1}; options_cyl(ind:ind+1) = []; options_cyl = [nPhi, options_cyl]; end ind = find(strcmpi(options_cyl, 'nTheta'), 1, 'last'); if ~isempty(ind) options_cyl(ind:ind+1) = []; end % save hold state holdState = ishold(hAx); hold(hAx, 'on'); if all(cap(1:3) == cap(4:6)) % the capsule is only a sphere. take arbitrary axis to be able to plot cap(4:6) = cap(1:3)+eps*([0 0 1]); h1 = 0; else h1 = drawCylinder(cap, options_cyl{:}); end h2 = drawDome(cap([1:3,7]), (cap(1:3)-cap(4:6)), varargin{:}); h3 = drawDome(cap([4:6,7]), -(cap(1:3)-cap(4:6)), varargin{:}); % restore hold state if ~holdState hold(hAx, 'off'); end % return handles if nargout == 1 varargout{1} = [h1, h2, h3]; end matgeom-1.2.4/inst/geom3d/PaxHeaders/box3dVolume.m0000644000000000000000000000013214576357161016764 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/box3dVolume.m0000644000175000017500000000424114576357161020545 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vol = box3dVolume(box) %BOX3DVOLUME Volume of a 3-dimensional box. % % V = box3dVolume(BOX) % % A box is represented as a set of limits in each direction: % BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. % % Example % [n e f] = createCubeOctahedron; % box = boundingBox3d(n); % vol = box3dVolume(box) % % See also % boxes3d, boundingBox3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform vol = prod(box(:, 2:2:end) - box(:, 1:2:end), 2); matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectLineCylinder.m0000644000000000000000000000013214576357161021057 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectLineCylinder.m0000644000175000017500000001402014576357161022634 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = intersectLineCylinder(line, cylinder, varargin) %INTERSECTLINECYLINDER Compute intersection points between a line and a cylinder. % % POINTS = intersectLineCylinder(LINE, CYLINDER) % Returns intersection points between a line and a cylinder. % % Input parameters: % LINE = [x0 y0 z0 dx dy dz] % CYLINDER = [x1 y1 z1 x2 y2 z2 R] % % Output: % POINTS = [x1 y1 z1 ; x2 y2 z2] % % POINTS = intersectLineCylinder(LINE, CYLINDER, 'checkBounds', B) % Where B is a boolean (TRUE by default), check if the points are within % the bounds defined by the two extreme points. If B is false, the % cylinder is considered to be infinite. % % Example % % Compute intersection between simple vertical cylinder and line % line = [60 60 60 1 2 3]; % cylinder = [20 50 50 80 50 50 30]; % points = intersectLineCylinder(line, cylinder); % % Display the different shapes % figure; % drawCylinder(cylinder); % hold on; light; % axis([0 100 0 100 0 100]); % drawLine3d(line); % drawPoint3d(points, 'ko'); % % % % Compute intersections when one of the points is outside the % % cylinder % line = [80 60 60 1 2 3]; % cylinder = [20 50 50 80 50 50 30]; % intersectLineCylinder(line, cylinder) % ans = % 67.8690 35.7380 23.6069 % % % See also % lines3d, intersectLinePlane, drawCylinder, cylinderSurfaceArea % % References % See the link: % http://www.gamedev.net/community/forums/topic.asp?topic_id=467789 % % ------ % Author: David Legland, from a file written by Daniel Trauth (RWTH) % E-mail: david.legland@inrae.fr % Created: 2007-01-27 % Copyright 2007-2023 %% Parse input arguments % default arguments checkBounds = true; % type of cylinder, one of {'closed', 'open', 'infinite'} type = 'closed'; % parse inputs while length(varargin)>1 var = varargin{1}; if strcmpi(var, 'checkbounds') checkBounds = varargin{2}; elseif strcmpi(var, 'type') type = varargin{2}; else error(['Unkown argument: ' var]); end varargin(1:2) = []; end %% Parse cylinder parameters % Starting point of the line l0 = line(1:3); % Direction vector of the line dl = line(4:6); % position of cylinder extremities c1 = cylinder(1:3); c2 = cylinder(4:6); % Direction vector of the cylinder dc = c2 - c1; % Radius of the cylinder r = cylinder(7); %% Resolution of a quadratic equation to find the increment % normalisation coefficient corresponding to direction of vector coef = dc / dot(dc, dc); % Substitution of parameters e = dl - dot(dl,dc) * coef; f = (l0-c1) - dot(l0-c1, dc) * coef; % Coefficients of 2-nd order equation A = dot(e, e); B = 2 * dot(e,f); C = dot(f,f) - r^2; % compute discriminant delta = B^2 - 4*A*C; % check existence of solution(s) if delta < 0 points = zeros(0, 3); return; end % extract roots pos1 = (-B + sqrt(delta)) / (2*A); pos2 = (-B - sqrt(delta)) / (2*A); posList = [pos1;pos2]; %% Estimation of point positions % process the smallest position pos1 = min(posList); % Point on the line: l0 + x*dl = p point1 = l0 + pos1 * dl; % process the greatest position pos2 = max(posList); % Point on the line: l0 + x*dl = p point2 = l0 + pos2 * dl; % Format result points = [point1 ; point2]; %% Check if points are located between bounds % if checkBounds option is not set, we can simply skip the rest if ~checkBounds || strncmpi(type, 'infinite', 1) return; end % compute cylinder axis axis = [c1 dc]; % compute position on axis ts = linePosition3d(points, axis); % check bounds for open cylinder % (keep only intersection points whose projection is between the two % cylinder extremities) if strncmpi(type, 'open', 1) ind = ts>=0 & ts<=1; points = points(ind, :); return; end % which intersection fall before and after bounds ind1 = find(ts < 0); ind2 = find(ts > 1); % case of both intersection on the same side -> no intersection if length(ind1) == 2 || length(ind2) == 2 points = zeros(0, 3); return; end % Process the remaining case of closed cylinder % -> compute eventual intersection(s) with end faces if ~isempty(ind1) plane = createPlane(c1, dc); points(ind1, :) = intersectLinePlane(line, plane); end if ~isempty(ind2) plane = createPlane(c2, dc); points(ind2, :) = intersectLinePlane(line, plane); end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawRay3d.m0000644000000000000000000000013214576357161016415 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawRay3d.m0000644000175000017500000000606514576357161020204 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function h = drawRay3d(varargin) %DRAWRAY3D Draw a 3D ray on the current axis. % % drawRay3d(RAY) % With RAY having the syntax: [x0 y0 z0 dx dy dz], draws the ray starting % from point (x0 y0 z0) and going to direction (dx dy dz), clipped with % the current window axis. % % drawRay3d(RAY, PARAMS, VALUE) % Can specify parameter name-value pairs to change draw style. % % H = drawRay3d(...) % Returns the handle of the line object. % % Example % % generate 50 random 3D rays % origin = [29 28 27]; % v = rand(50, 3); % v = v - centroid(v); % ray = [repmat(origin, size(v,1),1) v]; % % draw the rays in the current axis % figure; axis equal; axis([0 50 0 50 0 50]); hold on; view(3); % drawRay3d(ray); % % See also % drawLine3d, clipRay3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-05-25, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); ray = varargin{1}; varargin(1) = []; % get bounding box limits box = axis(hAx); % clip the ray(s) with the limits of the current axis edge = clipLine3d(ray, box); % identify valid edges inds = sum(isnan(edge), 2) == 0; % draw the clipped line hh = []; if any(inds) edge = edge(inds, :); hh = drawEdge3d(hAx, edge); if ~isempty(varargin) set(hh, varargin{:}); end end % process output if nargout > 0 h = hh; end matgeom-1.2.4/inst/geom3d/PaxHeaders/triangleArea3d.m0000644000000000000000000000013214576357161017402 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/triangleArea3d.m0000644000175000017500000000574714576357161021177 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function area = triangleArea3d(pt1, pt2, pt3) %TRIANGLEAREA3D Area of a 3D triangle. % % AREA = triangleArea3d(P1, P2, P3) % Computes area of the 3D triangle whose vertices are given by P1, P2 and % P3. Each vertex is either a 1-by-3 row vector, or an array with 3 % columns, each column representing coordinate of a vertex. % The result AREA has as many rows as the number of rows of the largest % input array. % Compared to polygonArea3d, this function is assumed to be faster, as it % does not requires iteration over vertices. Moreover, it can be used to % computes the area of several triangles simultaneously. % % AREA = triangleArea3d(PTS) % Concatenates vertex coordinates in a 3-by-3 array. Each row of the % array contains coordinates of one vertex. % % % Example % triangleArea3d([10 10 10], [30 10 10], [10 40 10]) % ans = % 300 % % See also % polygons3d, polygonArea3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-08-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % if data is given as one array, split vertices if nargin == 1 pt2 = pt1(2,:); pt3 = pt1(3,:); pt1 = pt1(1,:); end % compute individual vectors v12 = bsxfun(@minus, pt2, pt1); v13 = bsxfun(@minus, pt3, pt1); % compute area from cross product area = vectorNorm3d(cross(v12, v13, 2)) / 2; matgeom-1.2.4/inst/geom3d/PaxHeaders/isPerpendicular3d.m0000644000000000000000000000013214576357161020135 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/isPerpendicular3d.m0000644000175000017500000000527714576357161021730 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPerpendicular3d(v1, v2, varargin) %ISPERPENDICULAR3D Check orthogonality of two 3D vectors. % % B = isPerpendicular3d(V1, V2) % where V1 and V2 are 2 [1x3] arrays, returns 1 if the vectors are % orthogonal, and 0 otherwise. % % Also works when V1 and V2 are two [Nx3] arrays with same number of % rows. In this case, return a [Nx1] array containing 1 at the positions % of parallel vectors. % % Also works when one of V1 or V2 is scalar and the other one is [Nx3] % array, in this case return [Nx1] results. % % B = isPerpendicular3d(V1, V2, TOL) % Specifies the absolute tolerance (default is 1e-14). % % % Example % isPerpendicular3d([1 0 0], [0 1 0]) % ans = % 1 % % isPerpendicular3d([1 0 1], [1 0 0]) % ans = % 0 % % See also % vectors3d, isParallel3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-04-25 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % check if tolerance is specified tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % compute perpendicularity test b = abs(sum(bsxfun(@times, v1, v2), 2)) < tol; matgeom-1.2.4/inst/geom3d/PaxHeaders/planes3d.m0000644000000000000000000000013214576357161016266 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/planes3d.m0000644000175000017500000000465014576357161020053 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function planes3d(varargin) %PLANES3D Description of functions operating on 3D planes. % % Planes are represented by a 3D point (the plane origin) and 2 direction % vectors, which should not be colinear. % PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2]; % % See also % createPlane, normalizePlane, medianPlane, planeNormal, parallelPlane % distancePointPlane, projPointOnPlane, planePosition, isBelowPlane % intersectPlanes, intersectLinePlane, intersectEdgePlane % dihedralAngle, planesBisector, polyhedronSlice, fitPlane, drawPlane3d % clipConvexPolyhedronByPlane, clipPlane, transformPlane3d, isPlane % clipMeshByPlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('planes3d'); matgeom-1.2.4/inst/geom3d/PaxHeaders/fitSphere.m0000644000000000000000000000013214576357161016506 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/fitSphere.m0000644000175000017500000001000514576357161020262 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [sphere, residuals] = fitSphere(x,y,z) %FITSPHERE Fit a sphere to 3D points using the least squares approach. % % SPHERE = fitSphere(PTS) % Fits the equation of a sphere in Cartesian coordinates to the N-by-3 % array PTS using the least squares approach. The sphere is represented % by its center [xc yc zc] and its radius r: SPHERE = [xc yc zc r]. % % SPHERE = fitSphere(X, Y, Z) % Use three vectors X, Y and Z with the length N instead of a the % N-by-3 array PTS. % % [SPHERE, RESIDUALS] = fitSphere(...) % Additionally outputs the residuals in the radial direction. % % Example: % center=-100 + 200*rand(1,3); % radius = randi([10 100]); % [x,y,z]=drawSphere(center, radius); % x=x+rand(size(x)); y=y+rand(size(y)); z=z+rand(size(z)); % sampleIdx = randi(numel(x),[1,randi([4, numel(x)])]); % x=x(sampleIdx); y=y(sampleIdx); z=z(sampleIdx); % sphere = fitSphere(x,y,z); % figure('color','w'); hold on; axis equal tight; view(3) % drawPoint3d(x,y,z) % drawSphere(sphere,'FaceAlpha',0.5) % % See also % createSphere, drawSphere, intersectLineSphere, intersectPlaneSphere % % Source: % Levente Hunyadi - Fitting quadratic curves and surfaces: % https://de.mathworks.com/matlabcentral/fileexchange/45356 % ------ % Author: Levente Hunyadi, oqilipo (minor adaptions for matGeom) % E-mail: N/A % Created: 2010 % Copyright 2010-2023 Levente Hunyadi narginchk(1,3); switch nargin % n x 3 matrix case 1 n = size(x,1); validateattributes(x, {'numeric'}, {'2d','real','size',[n,3]}); z = x(:,3); y = x(:,2); x = x(:,1); otherwise % three x,y,z vectors n = length(x(:)); x = x(:); % force into columns y = y(:); z = z(:); validateattributes(x, {'numeric'}, {'real','size',[n,1]}); validateattributes(y, {'numeric'}, {'real','size',[n,1]}); validateattributes(z, {'numeric'}, {'real','size',[n,1]}); end % need four or more data points if n < 4 error('spherefit:InsufficientData', ... 'At least four points are required to fit a unique sphere.'); end % solve linear system of normal equations A = [x, y, z, ones(size(x))]; b = -(x.^2 + y.^2 + z.^2); a = A \ b; % return center coordinates and sphere radius center = -a(1:3)./2; radius = realsqrt(sum(center.^2)-a(4)); sphere = [center' radius]; % calculate residuals residuals = radius - sqrt(sum(bsxfun(@minus,[x y z],center.').^2,2)); end matgeom-1.2.4/inst/geom3d/PaxHeaders/sphericalAngle.m0000644000000000000000000000013214576357161017476 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/sphericalAngle.m0000644000175000017500000000756514576357161021273 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function alpha = sphericalAngle(p1, p2, p3) %SPHERICALANGLE Compute angle between points on the sphere. % % ALPHA = sphericalAngle(P1, P2, P3) % Computes angle (P1, P2, P3), i.e. the angle, measured at point P2, % between the direction (P2, P1) and the direction (P2, P3). % The result is given in radians, between 0 and 2*PI. % % Points are given either as [x y z] (there will be normalized to lie on % the unit sphere), or as [phi theta], with phi being the longitude in [0 % 2*PI] and theta being the elevation on horizontal [-pi/2 pi/2]. % % % NOTE: % this is an 'oriented' version of the angle computation, that is, the % result of sphericalAngle(P1, P2, P3) equals % 2*pi-sphericalAngle(P3,P2,P1). To have the more classical relation % (with results given betwen 0 and PI), it suffices to take the minimum % of angle and 2*pi-angle. % % Examples % % Use inputs as cartesian coordinates % p1 = [0 1 0]; % p2 = [1 0 0]; % p3 = [0 0 1]; % alpha = sphericalAngle(p1, p2, p3) % alpha = % 1.5708 % % % Use inputs as spherical coordinates % sph1 = [.1 0]; % sph2 = [0 0]; % sph3 = [0 .1]; % alphas = sphericalAngle(sph1, sph2, sph3) % alphas = % 1.5708 % % % See also % geom3d, angles3d, spheres, sph2cart % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % test if points are given as matlab spherical coordinates if size(p1, 2) == 2 [x, y, z] = sph2cart(p1(:,1), p1(:,2), ones(size(p1,1), 1)); p1 = [x y z]; [x, y, z] = sph2cart(p2(:,1), p2(:,2), ones(size(p2,1), 1)); p2 = [x y z]; [x, y, z] = sph2cart(p3(:,1), p3(:,2), ones(size(p3,1), 1)); p3 = [x y z]; end % normalize points p1 = normalizeVector3d(p1); p2 = normalizeVector3d(p2); p3 = normalizeVector3d(p3); % create the plane tangent to the unit sphere and containing central point plane = createPlane(p2, p2); % project the two other points on the plane pp1 = planePosition(projPointOnPlane(p1, plane), plane); pp3 = planePosition(projPointOnPlane(p3, plane), plane); % compute angle on the tangent plane pp2 = zeros(max(size(pp1, 1), size(pp3,1)), 2); alpha = angle3Points(pp1, pp2, pp3); matgeom-1.2.4/inst/geom3d/PaxHeaders/sph2cart2.m0000644000000000000000000000013214576357161016365 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/sph2cart2.m0000644000175000017500000000664314576357161020156 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = sph2cart2(theta, phi, rho) %SPH2CART2 Convert spherical coordinates to cartesian coordinates. % % C = SPH2CART2(S) % C = SPH2CART2(THETA, PHI) (assuming rho = 1) % C = SPH2CART2(THETA, PHI, RHO) % [X, Y, Z] = SPH2CART2(THETA, PHI, RHO); % % S = [theta phi rho] (spherical coordinate). % C = [X Y Z] (cartesian coordinate) % % The following convention is used: % THETA is the colatitude, in radians, 0 for north pole, +pi for south % pole, pi/2 for points with z=0. % PHI is the azimuth, in radians, defined as matlab cart2sph: angle from % Ox axis, counted counter-clockwise. % RHO is the distance of the point to the origin. % Discussion on choice for convention can be found at: % http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf % % Example % xyz = sph2cart2(pi/2, 0, 10) % xyz = % 10.0000 0 0.0000 % % xyz = sph2cart2(pi/2, pi/2, 10) % xyz = % 0.0000 10.0000 0.0000 % % % check consistency with cart2sph2 % sph2cart2(cart2sph2(0.7, 0.8, 5)) % ans = % 0.7000 0.8000 5.0000 % % See also % angles3d, cart2sph2, sph2cart, sph2cart2d, eulerAnglesToRotation3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % Process input arguments if nargin == 1 phi = theta(:, 2); if size(theta, 2) > 2 rho = theta(:, 3); else rho = ones(size(phi)); end theta = theta(:, 1); elseif nargin == 2 rho = ones(size(theta)); end % conversion rz = rho .* sin(theta); x = rz .* cos(phi); y = rz .* sin(phi); z = rho .* cos(theta); % format output if nargout <= 1 varargout{1} = [x, y, z]; else varargout{1} = x; varargout{2} = y; varargout{3} = z; end matgeom-1.2.4/inst/geom3d/PaxHeaders/createRotationOx.m0000644000000000000000000000013214576357161020047 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createRotationOx.m0000644000175000017500000000656614576357161021644 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createRotationOx(varargin) %CREATEROTATIONOX Create the 4x4 matrix of a 3D rotation around x-axis. % % TRANS = createRotationOx(THETA); % Returns the transform matrix corresponding to a rotation by the angle % THETA (in radians) around the Ox axis. A rotation by an angle of PI/2 % would transform the vector [0 1 0] into the vector [0 0 1]. % % The returned matrix has the form: % [1 0 0 0] % [0 cos(THETA) -sin(THETA) 0] % [0 sin(THETA) cos(THETA) 0] % [0 0 0 1] % % TRANS = createRotationOx(ORIGIN, THETA); % TRANS = createRotationOx(X0, Y0, Z0, THETA); % Also specifies origin of rotation. The result is similar as performing % translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). % % See also % transforms3d, transformPoint3d, createRotationOy, createRotationOz % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % default values dx = 0; dy = 0; dz = 0; theta = 0; % get input values if length(varargin) == 1 % only one argument -> rotation angle theta = varargin{1}; elseif length(varargin) == 2 % origin point (as array) and angle var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); theta = varargin{2}; elseif length(varargin) == 4 % origin (x and y) and angle dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; theta = varargin{4}; end % compute coefs cot = cos(theta); sit = sin(theta); % create transformation trans = [... 1 0 0 0;... 0 cot -sit 0;... 0 sit cot 0;... 0 0 0 1]; % add the translation part t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; trans = t * trans / t; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawVector3d.m0000644000000000000000000000013214576357161017124 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawVector3d.m0000644000175000017500000000531614576357161020711 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawVector3d(varargin) %DRAWVECTOR3D Draw vector at a given position. % % drawVector3d(POS, VECT) % Draws the vector VECT starting at the position POS. Both VECT and POS % are N-by-3 arrays. % % drawVector3d(..., PNAME, PVALUE) % Specifies additional optional parameters that will be given to the % quiver3 function. % % Example % figure; hold on; % drawVector3d([2 3 4], [1 0 0]); % drawVector3d([2 3 4], [0 1 0]); % drawVector3d([2 3 4], [0 0 1]); % view(3); % % See also % vectors3d, quiver3 % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-19, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % retrieve geometric data pos = varargin{1}; vect = varargin{2}; varargin(1:2) = []; % draw the vectors using the quiver3 function h = quiver3(hAx, pos(:, 1), pos(:, 2), pos(:, 3), ... vect(:, 1), vect(:, 2), vect(:, 3), 0, varargin{:}); % format output if nargout > 0 varargout{1} = h; end matgeom-1.2.4/inst/geom3d/PaxHeaders/midPoint3d.m0000644000000000000000000000013214576357161016567 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/midPoint3d.m0000644000175000017500000000707414576357161020357 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = midPoint3d(varargin) %MIDPOINT3D Middle point of two 3D points or of a 3D edge. % % MID = midPoint3d(P1, P2) % Compute the middle point of the two points P1 and P2. % % MID = midPoint3d(EDGE) % Compute the middle point of the edge given by EDGE. % EDGE has the format: [X1 Y1 Z1 X2 Y2 Z2], and MID has the format % [XMID YMID ZMID], % with XMID = (X1+X2)/2, YMID = (Y1+Y2)/2 and ZMID = (Z1+Z2)/2. % % [MIDX MIDY] = midPoint3d(...) % Return the result as two separate variables or arrays. % % Works also when EDGE is a N-by-6 array, in this case the result is a % N-by-3 array containing the midPoint3d of each edge. % % % Example % P1 = [10 20 30]; % P2 = [30 40 50]; % % edge input % midPoint3d([P1 P2]) % ans = % 20 30 40 % % % two points input % midPoint3d(P1, P2) % ans = % 20 30 40 % % % three outputs % [xm ym zm] = midPoint3d(P1, P2) % xm = % 20 % ym = % 30 % zm = % 40 % % See also % edges3d, points3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-08-08, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform if nargin == 1 % input is a 3D edge edge = varargin{1}; mid = [mean(edge(:, [1 4]), 2) mean(edge(:, [2 5]), 2) mean(edge(:, [3 6]), 2)]; elseif nargin == 2 % input are two points p1 = varargin{1}; p2 = varargin{2}; % assert inputs are equal n1 = size(p1, 1); n2 = size(p2, 1); if n1>1 && n2==1 p2 = repmat(p2, n1, 1); elseif n2>1 && n1==1 p1 = repmat(p1, n2, 1); elseif n1~=n2 error('geom3d:midPoint3d', ... 'Inputs must have same size, or one must have length 1'); end % compute middle point mid = (p1 + p2) / 2; end % process output arguments if nargout<=1 varargout{1} = mid; else varargout = {mid(:,1), mid(:,2), mid(:,3)}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/vectorAngle3d.m0000644000000000000000000000013214576357161017255 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/vectorAngle3d.m0000644000175000017500000000524414576357161021042 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = vectorAngle3d(v1, v2) %VECTORANGLE3D Angle between two 3D vectors. % % THETA = vectorAngle3d(V1, V2) % Computes the angle between the 2 3D vectors V1 and V2. The result THETA % is given in radians, between 0 and PI. % % % Example % % angle between 2 orthogonal vectors % vectorAngle3d([1 0 0], [0 1 0]) % ans = % 1.5708 % % % angle between 2 parallel vectors % v0 = [3 4 5]; % vectorAngle3d(3*v0, 5*v0) % ans = % 0 % % See also % vectors3d, vectorNorm3d, crossProduct3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % compute angle using arc-tangent to get better precision for angles near % zero, see the discussion in: % http://www.mathworks.com/matlabcentral/newsreader/view_thread/151925#381952 theta = atan2(vectorNorm3d(crossProduct3d(v1, v2)), sum(bsxfun(@times, v1, v2),2)); % equivalent to: % v1 = normalizeVector3d(v1); % v2 = normalizeVector3d(v2); % theta = acos(dot(v1, v2, 2)); matgeom-1.2.4/inst/geom3d/PaxHeaders/projPointOnLine3d.m0000644000000000000000000000013214576357161020075 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/projPointOnLine3d.m0000644000175000017500000000543014576357161021657 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = projPointOnLine3d(point, line) %PROJPOINTONLINE3D Project a 3D point orthogonally onto a 3D line. % % PT2 = projPointOnLine3d(PT, LINE). % Computes the (orthogonal) projection of 3D point PT onto the 3D line % LINE. % % Function works also for multiple points and lines. In this case, it % returns multiple points. % Point PT1 is a N-by-3 array, and LINE is a N-by-6 array. % Result PT2 is a N-by-3 array, containing coordinates of orthogonal % projections of PT1 onto lines LINE. % % % See also % projPointOnLine, distancePointLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-08-23 % Copyright 2012-2023 INRA - TPV URPOI - BIA IMASTE % direction vector of the line vx = line(:, 4); vy = line(:, 5); vz = line(:, 6); % difference of point with line origin dx = point(:,1) - line(:,1); dy = point(:,2) - line(:,2); dz = point(:,3) - line(:,3); % Position of projection on line, using dot product delta = vx .* vx + vy .* vy + vz .* vz; tp = (dx .* vx + dy .* vy + dz .* vz) ./ delta; % convert position on line to cartesian coordinates point = [line(:,1) + tp .* vx, line(:,2) + tp .* vy, line(:,3) + tp .* vz]; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawAxisCube.m0000644000000000000000000000013214576357161017136 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawAxisCube.m0000644000175000017500000000516514576357161020725 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function p = drawAxisCube(varargin) %DRAWAXISCUBE Draw a colored cube representing axis orientation. % % Usage: % drawAxisCube(); % Display a 3D unit cube with one corner located at position (0,0,0), and % face colored according to the direction of their normal. % % Example % drawAxisCube % % See also % drawAxis3d, createCube, patch % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % extract handle of axis to draw on if isempty(varargin) hAx = gca; else if isAxisHandle(varargin{1}) hAx = varargin{1}; else error('If first argument is specified, it must be an axis handle'); end end [n, e, f] = createCube; %#ok faceColors = [ ... 1 1 0; ... 0 0 1; ... 1 0 0; ... 0 1 1; ... 1 0 1; ... 0 1 0; ... ]; p = patch(hAx, 'vertices', n, 'faces', f, ... 'facecolor', 'flat', 'FaceVertexCData', faceColors); matgeom-1.2.4/inst/geom3d/PaxHeaders/drawSphericalTriangle.m0000644000000000000000000000013214576357161021033 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawSphericalTriangle.m0000644000175000017500000000665714576357161022631 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawSphericalTriangle(varargin) %DRAWSPHERICALTRIANGLE Draw a triangle on a sphere. % % drawSphericalTriangle(SPHERE, PT1, PT2, PT3); % Draws the spherical triangle defined by the three input 3D points and % the reference sphere. % Points are given as 3D points, and are projected onto the sphere. The % order of the points is not relevant. % % drawSphericalTriangle(SPHERE, PT1, PT2, PT3, OPTIONS); % Allows to specify plot options for spherical edges, in the form of % parameter name-value pairs. % % Example % % Draw a sphere and a spherical triangle on it % s = [0 0 0 2]; % pts = [1 0 0;0 -1 0;0 0 1]; % drawSphere(s); hold on; % drawSphericalTriangle(s, pts(1,:), pts(2,:), pts(3,:), 'linewidth', 2); % view(3); axis equal; % % See also % drawSphere, fillSphericalTriangle, drawSphericalPolygon, % drawSphericalEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-22 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); sphere = varargin{1}; p1 = varargin{2}; p2 = varargin{3}; p3 = varargin{4}; varargin(1:4) = []; % extract data of the sphere ori = sphere(:, 1:3); % extract direction vectors for each point v1 = normalizeVector3d(p1 - ori); v2 = normalizeVector3d(p2 - ori); v3 = normalizeVector3d(p3 - ori); % keep hold state of current axis holdState = ishold(hAx); hold(hAx, 'on'); % draw each spherical edge h1 = drawSphericalEdge(hAx, sphere, [v1 v2], varargin{:}); h2 = drawSphericalEdge(hAx, sphere, [v2 v3], varargin{:}); h3 = drawSphericalEdge(hAx, sphere, [v3 v1], varargin{:}); % return to previous hold state if needed if ~holdState hold(hAx, 'off'); end if nargout > 0 varargout = {h1, h2, h3}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/linePosition3d.m0000644000000000000000000000013214576357161017460 xustar0030 mtime=1710874225.090193391 30 atime=1710874225.090193391 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/linePosition3d.m0000644000175000017500000000771714576357161021254 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function pos = linePosition3d(point, line) %LINEPOSITION3D Return the position of a 3D point projected on a 3D line. % % T = linePosition3d(POINT, LINE) % Computes position of point POINT on the line LINE, relative to origin % point and direction vector of the line. % LINE has the form [x0 y0 z0 dx dy dy], % POINT has the form [x y z], and is assumed to belong to line. % The result T is the value such that POINT = LINE(1:3) + T * LINE(4:6). % If POINT does not belong to LINE, the position of its orthogonal % projection is computed instead. % % T = linePosition3d(POINT, LINES) % If LINES is an array of NL lines, return NL positions, corresponding to % each line. % % T = linePosition3d(POINTS, LINE) % If POINTS is an array of NP points, return NP positions, corresponding % to each point. % % See also % lines3d, createLine3d, distancePointLine3d, projPointOnLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % size of input arguments np = size(point, 1); nl = size(line, 1); if np == 1 || nl == 1 || np == nl % standard case where result is either scalar or vector % vector from line origin to point dp = bsxfun(@minus, point, line(:,1:3)); % direction vector of the line vl = line(:, 4:6); % precompute and check validity of denominator denom = sum(vl.^2, 2); invalidLine = denom < eps; denom(invalidLine) = 1; % compute position using dot product normalized with norm of line vector. pos = bsxfun(@rdivide, sum(bsxfun(@times, dp, vl), 2), denom); % position on a degenerated line is set to 0 pos(invalidLine) = 0; else % reshape input point = reshape(point, [np 1 3]); line = reshape(line, [1 nl 6]); % vector from line origin to point dp = bsxfun(@minus, point, line(:,:,1:3)); % direction vector of the line vl = line(:, :, 4:6); % precompute and check validity of denominator denom = sum(vl.^2, 3); invalidLine = denom < eps; denom(invalidLine) = 1; % compute position using dot product normalized with norm of line vector. pos = bsxfun(@rdivide, sum(bsxfun(@times, dp, vl), 3), denom); % position on a degenerated line is set to 0 pos(invalidLine) = 0; end matgeom-1.2.4/inst/geom3d/PaxHeaders/anglePoints3d.m0000644000000000000000000000013214576357161017267 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/anglePoints3d.m0000644000175000017500000000647214576357161021060 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function alpha = anglePoints3d(varargin) %ANGLEPOINTS3D Compute angle between three 3D points. % % ALPHA = anglePoints3d(P1, P2) % Computes angle (P1, O, P2), in radians, between 0 and PI. % % ALPHA = anglePoints3d(P1, P2, P3) % Computes angle (P1, P2, P3), in radians, between 0 and PI. % % ALPHA = anglePoints3d(PTS) % PTS is a 3x3 or 2x3 array containing coordinate of points. % % Example % rad2deg(anglePoints3d([0 0 1],[1 1 0])) % % See also % points3d, angles3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE p2 = [0 0 0]; if length(varargin) == 1 pts = varargin{1}; if size(pts, 1)==2 p1 = pts(1,:); p0 = [0 0 0]; p2 = pts(2,:); else p1 = pts(1,:); p0 = pts(2,:); p2 = pts(3,:); end elseif length(varargin) == 2 p1 = varargin{1}; p0 = [0 0 0]; p2 = varargin{2}; elseif length(varargin) == 3 p1 = varargin{1}; p0 = varargin{2}; p2 = varargin{3}; end % ensure all data have same size n1 = size(p1, 1); n2 = size(p2, 1); n0 = size(p0, 1); if n1 ~= n0 if n1 == 1 p1 = repmat(p1, [n0 1]); n1 = n0; elseif n0==1 p0 = repmat(p0, [n1 1]); else error('Arguments P1 and P0 must have the same size'); end end if n1 ~= n2 if n1 == 1 p1 = repmat(p1, [n2 1]); elseif n2 == 1 p2 = repmat(p2, [n1 1]); else error('Arguments P1 and P2 must have the same size'); end end % normalized vectors p1 = normalizeVector3d(p1 - p0); p2 = normalizeVector3d(p2 - p0); % compute angle alpha = acos(dot(p1, p2, 2)); matgeom-1.2.4/inst/geom3d/PaxHeaders/drawEllipseCylinder.m0000644000000000000000000000013214576357161020522 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawEllipseCylinder.m0000644000175000017500000001376214576357161022313 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipseCylinder(varargin) %DRAWELLIPSECYLINDER Draw a cylinder with ellipse cross-section. % % drawEllipseCylinder(CYL) % draws the cylinder CYL on the current axis. % CYL is a cylinder defined by [x1 y1 z1 x2 y2 z2 r1 r2 roll], with: % * [x1 y2 z1] are coordinates of starting point, % * [x2 y2 z2] are coordinates of ending point, % * R1 and R2 are the lengths of the ellipse semi axes, and % * ROLL is the rotation of the cylinder around its main axis (in % degrees) % % drawEllipseCylinder(CYL, N) % uses N points for discretisation of angle. Default value is 32. % % drawEllipseCylinder(..., OPT) % with OPT = 'open' (default) or 'closed', specify if bases of the % cylinder should be drawn. % % drawEllipseCylinder(..., 'FaceColor', COLOR) % Specifies the color of the cylinder. Any couple of parameters name and % value can be given as argument, and will be transfered to the 'surf' % matlab function % % H = drawEllipseCylinder(...) % returns a handle to the patch representing the cylinder. % % % Example: % figure; drawEllipseCylinder([0 0 0 10 20 30 5 2]); % % figure; drawEllipseCylinder([0 0 0 10 20 30 5 2], 'open'); % % figure; drawEllipseCylinder([0 0 0 10 20 30 5 2], 'FaceColor', 'r'); % % figure; % h = drawEllipseCylinder([0 0 0 10 20 30 5 2]); % set(h, 'facecolor', 'b'); % % % Draw three mutually intersecting elliptic cylinders % p1 = [30 0 0]; % p2 = [0 30 0]; % p3 = [0 0 30]; % radii = [20 10]; % figure; % drawEllipseCylinder([-p1 p1 radii 0], 'FaceColor', 'r'); % hold on % drawEllipseCylinder([-p2 p2 radii 90], 'FaceColor', 'g'); % drawEllipseCylinder([-p3 p3 radii 90], 'FaceColor', 'b'); % axis equal % set(gcf, 'renderer', 'opengl') % view([60 30]); light; % % See also % drawCylinder, drawSphere, cylinderMesh, drawLine3d, surf % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2014-02-27 % Copyright 2014-2023 INRA - TPV URPOI - BIA IMASTE %% Input argument processing % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % retrieve cylinder cyl = varargin{1}; varargin(1) = []; if iscell(cyl) res = zeros(length(cyl), 1); for i = 1:length(cyl) res(i) = drawEllipseCylinder(hAx, cyl{i}, varargin{:}); end if nargout > 0 varargout{1} = res; end return; end % default values N = 32; closed = true; % check number of discretization steps if ~isempty(varargin) var = varargin{1}; if isnumeric(var) N = var; varargin = varargin(2:end); end end % check if cylinder must be closed or open if ~isempty(varargin) var = varargin{1}; if ischar(var) if strncmpi(var, 'open', 4) closed = false; varargin = varargin(2:end); elseif strncmpi(var, 'closed', 5) closed = true; varargin = varargin(2:end); end end end %% Computation of mesh coordinates % extreme points of cylinder p1 = cyl(1:3); p2 = cyl(4:6); % radius of cylinder r1 = cyl(7); r2 = cyl(8); roll = 0; if size(cyl, 2) > 8 roll = cyl(9); end % compute orientation angle of cylinder (in degrees) [theta, phi, rho] = cart2sph2d(p2 - p1); dphi = linspace(0, 2*pi, N+1); % generate a cylinder oriented upwards x = repmat(cos(dphi) * r1, [2 1]); y = repmat(sin(dphi) * r2, [2 1]); z = repmat([0 ; rho], [1 length(dphi)]); % transform points trans = localToGlobal3d(p1, theta, phi, roll); pts = transformPoint3d([x(:) y(:) z(:)], trans); % reshape transformed points x2 = reshape(pts(:,1), size(x)); y2 = reshape(pts(:,2), size(x)); z2 = reshape(pts(:,3), size(x)); %% Display cylinder mesh % add default drawing options varargin = [{'FaceColor', 'g', 'edgeColor', 'none'} varargin]; % plot the cylinder as a surface hSurf = surf(hAx, x2, y2, z2, varargin{:}); % eventually plot the ends of the cylinder if closed ind = find(strcmpi(varargin, 'facecolor'), 1, 'last'); if isempty(ind) color = 'k'; else color = varargin{ind+1}; end patch(hAx, x2(1,:)', y2(1,:)', z2(1,:)', color, 'edgeColor', 'none'); patch(hAx, x2(2,:)', y2(2,:)', z2(2,:)', color, 'edgeColor', 'none'); end % format ouptut if nargout == 1 varargout{1} = hSurf; end matgeom-1.2.4/inst/geom3d/PaxHeaders/distancePoints3d.m0000644000000000000000000000013214576357161017773 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/distancePoints3d.m0000644000175000017500000000547614576357161021567 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dist = distancePoints3d(p1, p2, varargin) %DISTANCEPOINTS3D Compute euclidean distance between pairs of 3D Points. % % D = distancePoints3d(P1, P2) return distance between points P1 and % P2, given as [X Y Z]. % % If P1 and P2 are two arrays of points, result is a N1*N2 array % containing distance between each point of P1 and each point of P2. % % % D = distancePoints3d(P1, P2, NOR) % with NOR being 1, 2, or Inf, corresponfing to the norm used. Default is % 2 (euclidean norm). 1 correspond to manhattan (or taxi driver) distance % and Inf to maximum difference in each coordinate. % % % See also % points3d, minDistancePoints, distancePoints % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE norm = 2; if length(varargin)==1 norm = varargin{1}; end % compute difference of coordinate for each pair of points ptsDiff = bsxfun(@minus, p2, p1); % Return dist based on the type of measurement requested switch(norm) case 1 dist = sum(abs(ptsDiff),2); case 2 dist = vectorNorm3d(ptsDiff); case Inf dist = max(abs(ptsDiff), [], 2); otherwise dist = power(sum(power(ptsDiff, norm),2), 1/norm); end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawGrid3d.m0000644000000000000000000000013214576357161016547 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawGrid3d.m0000644000175000017500000001110014576357161020320 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawGrid3d(varargin) %DRAWGRID3D Draw a 3D grid on the current axis. % % drawGrid3d % draws a 3D square grid, with origin (0,0,0) and spacing 1 in each % direction, with bounds corresponding to the bounds of current axis. % % drawGrid3d(SPACING) % where spacing is either a scalar or a [1x3] matrix, specifies the size % of the unit cell. % % drawGrid3d(ORIGIN, SPACING) % Also specify origin of grid. ORIGIN is a [1x3] array. % % drawGrid3d(..., EDGE) % specifies whether function should draw edges touching edges of axis. % EDGE is a characheter string, which can be : % - 'OPEN' : each line start from one face of window to the opposite % face. This results in a 'spiky' grid. % - 'CLOSED' (default value) : each line stops at the last visible point % of the grid for this line. The result looks like a box (no free spikes % around the grid). % % H = drawGrid3d(...); % return a vector of handles for each LINE object which was crated. % % % Example % figure; hold on; axis equal; axis([-5 65 -5 45 -5 45]); view(3); % drawGrid3d([0 0 0], [20 20 20]); % % % See also % drawLine3d, drawEdge3d, clipLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-17 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) %% initialize variables % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % default values closed = true; origin = [0 0 0]; spacing = [1 1 1]; % check if grid is open or not str = ''; if ~isempty(varargin) str = varargin{end}; end if ischar(str) if strncmpi(str, 'open', 4) closed = false; end varargin = varargin(1:end-1); end % check origin and grid spacing if length(varargin)==1 spacing = varargin{1}; elseif length(varargin)==2 origin = varargin{1}; spacing = varargin{2}; end %% Compute internal data % get axis limits ax = axis(hAx); x0 = ax(1); x1 = ax(2); y0 = ax(3); y1 = ax(4); z0 = ax(5); z1 = ax(6); % get first and last coordinates of the grid in each direction dx = spacing(1); dy = spacing(2); dz = spacing(3); xe = x0 + mod(origin(1) - x0, dx); xf = x1 - mod(x1 - origin(1), dx); ye = y0 + mod(origin(2) - y0, dy); yf = y1 - mod(y1 - origin(2), dy); ze = z0 + mod(origin(1) - z0, dz); zf = z1 - mod(z1 - origin(1), dz); % update first and last coordinate if grid is 'closed' if closed x0 = xe; x1 = xf; y0 = ye; y1 = yf; z0 = ze; z1 = zf; end %% Draw the grid % header array, one header for each line segment h = []; % draw lines parallel to x axis for y = ye:dy:yf for z = ze:dz:zf h = [h; drawEdge3d(hAx, [x0 y z x1 y z])]; %#ok end end % draw lines parallel to y axis for x = xe:dx:xf for z = ze:dz:zf h = [h; drawEdge3d(hAx, [x y0 z x y1 z])]; %#ok end end % draw lines parallel to z axis for x = xe:dx:xf for y = ye:dy:yf h = [h; drawEdge3d(hAx, [x y z0 x y z1])]; %#ok end end %% Check output arguments if nargout > 0 varargout{1} = h; end matgeom-1.2.4/inst/geom3d/PaxHeaders/projPointOnCylinder.m0000644000000000000000000000013214576357161020530 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/projPointOnCylinder.m0000644000175000017500000001253314576357161022314 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ptProj = projPointOnCylinder(pt, cyl, varargin) %PROJPOINTONCYLINDER Project a 3D point onto a cylinder. % % PTPROJ = projPointOnCircle3d(PT, CYLINDER). % Computes the projection of 3D point PT onto the CYLINDER. % % Point PT is a 1-by-3 array, and CYLINDER is a 1-by-7 array. % Result PTPROJ is a 1-by-3 array, containing the coordinates of the % projection of PT onto the CYLINDER. % % PTPROJ = projPointOnCircle3d(..., OPT) % with OPT = 'open' (0) (default) or 'closed' (1), specify if the bases % of the cylinder should be included. % % Example % demoProjPointOnCylinder % % See also % projPointOnLine3d, projPointOnPlane, projPointOnCircle3d % % ------ % Author: oqilipo % E-mail: N/A % Created: 2021-04-17, using R2020b % Copyright 2021-2023 parser = inputParser; addRequired(parser, 'pt', @(x) validateattributes(x, {'numeric'},... {'size',[1 3],'real','finite','nonnan'})); addRequired(parser, 'cyl', @(x) validateattributes(x, {'numeric'},... {'size',[1 7],'real','finite','nonnan'})); capParValidFunc = @(x) (islogical(x) ... || isequal(x,1) || isequal(x,0) || any(validatestring(x, {'open','closed'}))); addOptional(parser,'cap','open', capParValidFunc); parse(parser,pt,cyl,varargin{:}); pt = parser.Results.pt; cyl = parser.Results.cyl; cap = lower(parser.Results.cap(1)); % Radius of the cylinder cylRadius = cyl(7); % Height of the cylinder cylBottom = -Inf; cylHeight = Inf; if cap == 'c' || cap == 1 cylBottom = 0; cylHeight = distancePoints3d(cyl(1:3),cyl(4:6)); end % Create a transformation for the point into a local cylinder coordinate % system. Align the cylinder axis with the z axis and translate the % starting point of the cylinder to the origin. TFM = createRotationVector3d(cyl(4:6)-cyl(1:3), [0 0 1])*createTranslation3d(-cyl(1:3)); % cylTfm = [transformPoint3d(cyl(1:3), TFM) transformPoint3d(cyl(4:6), TFM) cylRadius]; % cylTfm2 = [0 0 0 0 0 cylHeight, cylRadius]; % assert(ismembertol(cylTfm,cylTfm2,'byRows',1,'DataScale',1e1)) % Transform the point. ptTfm = transformPoint3d(pt,TFM); % Convert the transformed point to cylindrical coordinates. [ptTheta, ptRadius, ptHeight] = cart2cyl(ptTfm); if ptRadius <= cylRadius && (ptHeight <= cylBottom || ptHeight >= cylHeight) % If point is inside the radius of the cylinder but outside its height if ptHeight <= cylBottom ptProj_cyl = [ptTheta, ptRadius, 0]; else ptProj_cyl = [ptTheta, ptRadius, cylHeight]; end elseif ptRadius > cylRadius && (ptHeight <= cylBottom || ptHeight >= cylHeight) % If point is outside the cylinder's radius and height if ptHeight <= cylBottom ptProj_cyl = [ptTheta, cylRadius, 0]; else ptProj_cyl = [ptTheta, cylRadius, cylHeight]; end elseif ptRadius < cylRadius && (ptHeight > cylBottom && ptHeight < cylHeight) % If point is inside the cylinder's radius and height deltaRadius = cylRadius - ptRadius; deltaHeight = cylHeight - ptHeight; if (deltaRadius < ptHeight && deltaRadius < deltaHeight) || isinf(cylBottom) % If the distance to the cylinder's surface is smaller than the % distance to the top and bottom surfaces. ptProj_cyl = [ptTheta, cylRadius, ptHeight]; else if ptHeight < deltaHeight ptProj_cyl = [ptTheta, ptRadius, 0]; else ptProj_cyl = [ptTheta, ptRadius, cylHeight]; end end elseif ptRadius >= cylRadius && (ptHeight > cylBottom && ptHeight < cylHeight) % If point is outside the radius of the cylinder and inside its height ptProj_cyl = [ptTheta, cylRadius, ptHeight]; end % Convert the projected point back to Cartesian coordinates ptProj_cart = cyl2cart(ptProj_cyl); % Transform the projected point back to the global coordinate system ptProj = transformPoint3d(ptProj_cart,inv(TFM)); end matgeom-1.2.4/inst/geom3d/PaxHeaders/lineToEdge3d.m0000644000000000000000000000013214576357161017023 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/lineToEdge3d.m0000644000175000017500000000450514576357161020607 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = lineToEdge3d(line) %LINETOEDGE3D Convert a 3D straight line to a 3D finite edge. % % EDGE = lineToEdge3d(LINE) % Returns the edge with same origin as the line LINE, and with second % extremity corresponding to the addition of line origin and direction. % LINE is represented as [X0 Y0 Z0 DX DY DZ] % EDGE is represented as [X1 Y1 Z1 X2 Y2 Z2] % % Example % line = [3 4 5 1 2 3]; % edge = lineToEdge3d(line) % edge = % 3 4 5 4 6 8 % % See also % lines3d, edges3d, edgeToLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-05-07, using Matlab 9.6.0.1072779 (R2019a) % Copyright 2019-2023 INRA - Cepia Software Platform edge = [line(:, 1:3) line(:,1:3)+line(:,4:6)]; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawAxis3d.m0000644000000000000000000000013214576357161016566 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawAxis3d.m0000644000175000017500000000733014576357161020351 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawAxis3d(varargin) %DRAWAXIS3D Draw a coordinate system and an origin. % % drawAxis3d % Adds three 3D arrows to the current axis, corresponding to the % directions of the 3 basis vectors Ox, Oy and Oz. % Ox vector is red, Oy vector is green, and Oz vector is blue. % % drawAxis3d(L, R) % Specifies the length L and the radius of the cylinders representing the % different axes. % % drawAxis3d(..., 'TFM', TRANSFORM) % Transforms the coordinate system before drawing using TRANSFORM. % % H = drawAxis3d(...) returns the group handle of the axis object. % % Example % drawAxis3d % % figure; % drawAxis3d(20, 1); % view([135,15]); lighting('phong'); camlight('head'); axis('equal') % xlabel X; ylabel Y; zlabel Z % % See also % drawAxisCube % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-08-14, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % extract handle of axis to draw on if isempty(varargin) hAx = gca; else if isAxisHandle(varargin{1}) hAx = varargin{1}; varargin(1) = []; else hAx = gca; end end % Parsing p = inputParser; addOptional(p, 'L', 1, @(x)validateattributes(x, {'numeric'},... {'scalar','nonempty','real','finite','positive','nonnan'})); addOptional(p, 'R', [], @(x)validateattributes(x, {'numeric'},... {'scalar','nonempty','real','finite','positive','nonnan'})); addParameter(p, 'TFM', eye(4), @isTransform3d); parse(p,varargin{:}); L = p.Results.L; R = p.Results.R; if isempty(R) R = L/10; elseif R/L > 0.1 R = (0.1-eps)*L; warning('Value of R is invalid and was ignored!') end TFM = p.Results.TFM; % geometrical data origin = transformPoint3d(zeros(3,3), TFM); vector = transformVector3d(eye(3,3), TFM); color = eye(3,3); % draw three arrows and a ball hold on; sh = drawArrow3d(hAx, origin, vector*L, color, 'arrowRadius', R/L); sh(4) = drawSphere(hAx, [origin(1,:) 2*R], 'faceColor', 'black'); gh = hggroup(hAx); set(sh, 'Parent', gh) if nargout > 0 varargout = {gh}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/clipLine3d.m0000644000000000000000000000013214576357161016543 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/clipLine3d.m0000644000175000017500000001042214576357161020322 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = clipLine3d(line, box) %CLIPLINE3D Clip a line with a box and return an edge. % % EDGE = clipLine3d(LINE, BOX); % Clips the line LINE with the bounds given in BOX, and returns the % corresponding edge. % % If the line lies totally outside of the box, returns a 1-by-6 row array % containing only NaN's. % % If LINE is a N-by-6 array, with one line by row, returns the clipped % edge coresponding to each line in a N-by-6 array. % % See also % lines3d, edges3d, createLine3d, clipRay3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-30, from drawLine3d % Copyright 2008-2023 INRA - TPV URPOI - BIA IMASTE % get box limits xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); zmin = box(5); zmax = box(6); % extreme corners of the box p000 = [xmin ymin zmin]; p111 = [xmax ymax zmax]; % main vectors ex = [1 0 0]; ey = [0 1 0]; ez = [0 0 1]; % box faces parallel to Oxy planeZ0 = [p000 ex ey]; planeZ1 = [p111 ex ey]; % box faces parallel to Oxz planeY0 = [p000 ex ez]; planeY1 = [p111 ex ez]; % box faces parallel to Oyz planeX0 = [p000 ey ez]; planeX1 = [p111 ey ez]; % number of lines nLines = size(line, 1); % allocate memory for result edge = zeros(nLines, 6); % iterate over lines to clip for i = 1:nLines % compute intersection point with each plane ipZ0 = intersectLinePlane(line(i,:), planeZ0); ipZ1 = intersectLinePlane(line(i,:), planeZ1); ipY0 = intersectLinePlane(line(i,:), planeY0); ipY1 = intersectLinePlane(line(i,:), planeY1); ipX1 = intersectLinePlane(line(i,:), planeX1); ipX0 = intersectLinePlane(line(i,:), planeX0); % concatenate resulting points points = [ipX0;ipX1;ipY0;ipY1;ipZ0;ipZ1]; % compute position of each point on the line pos = linePosition3d(points, line(i,:)); % keep only defined points ind = find(~isnan(pos)); pos = pos(ind); points = points(ind,:); % sort points with respect to their position [pos, ind] = sort(pos); %#ok points = points(ind, :); % keep median points wrt to position. These points define the limit of % the clipped edge. nv = length(ind)/2; % create resulting edge. edge(i,:) = [points(nv, :) points(nv+1, :)]; end % check that middle point of the edge is contained in the box midX = mean(edge(:, [1 4]), 2); xOk = xmin <= midX & midX <= xmax; midY = mean(edge(:, [2 5]), 2); yOk = ymin <= midY & midY <= ymax; midZ = mean(edge(:, [3 6]), 2); zOk = zmin <= midZ & midZ <= zmax; % if one of the bounding condition is not met, set edge to NaN edge (~(xOk & yOk & zOk), :) = NaN; matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectEdgePolygon3d.m0000644000000000000000000000013214576357161021141 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectEdgePolygon3d.m0000644000175000017500000000756114576357161022732 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [inter, valid] = intersectEdgePolygon3d(edge, poly) %INTERSECTEDGEPOLYGON3D Intersection point of a 3D edge segment and a 3D polygon. % % INTER = intersectEdgePolygon3d(EDGE, POLY) % Compute coordinates of intersection point between the 3D edge EDGE and % the 3D polygon POLY. EDGE is a 1-by-6 row vector containing source and % target positions of the edge, POLY is a Nv-by-3 array containing % coordinates of 3D polygon vertices. % INTER is a 1-by-3 row vector containing coordinates of intersection % point, or [NaN NaN NaN] if edge and polygon do not intersect. % % INTERS = intersectEdgePolygon3d(EDGES, POLY) % If EDGES is a N-by-6 array representing several edges, the result % INTERS is a N-by-3 array containing coordinates of intersection of each % edge with the polygon. % % [INTER, INSIDE] = intersectEdgePolygon3d(EDGE, POLY) % Also return a N-by-1 boolean array containing TRUE if the corresponding % edge contains the intersection point. % % Example % % Compute intersection between a 3D edge and a 3D triangle % pts3d = [3 0 0; 0 6 0;0 0 9]; % edge1 = [0 0 0 3 6 9]; % inter = intersectEdgePolygon3d(edge1, pts3d) % inter = % 1 2 3 % % % keep only valid intersections with several edges % pts3d = [3 0 0; 0 6 0;0 0 9]; % edges = [0 0 0 3 6 9;10 0 0 10 2 3]; % [inter, inside] = intersectEdgePolygon3d(edges, pts3d); % inter(inside, :) % ans = % 1 2 3 % % See also % intersectLinePolygon, intersectRayPolygon3d, intersectLinePlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % supporting plane of polygon vertices plane = createPlane(poly(1:3, :)); % intersection of edge supporting line with the plane line = edgeToLine3d(edge); inter = intersectLinePlane(line, plane); onEdge = isPointOnEdge3d(inter, edge); % project all points on reference plane pts2d = planePosition(poly, plane); pInt2d = planePosition(inter, plane); % need to check polygon orientation insidePoly = xor(isPointInPolygon(pInt2d, pts2d), polygonArea(pts2d) < 0); % intersection points either outside the polygon on outside the edge bounds % are set to NaN valid = insidePoly & onEdge; inter(~valid, :) = NaN; matgeom-1.2.4/inst/geom3d/PaxHeaders/transformCircle3d.m0000644000000000000000000000013214576357161020141 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/transformCircle3d.m0000644000175000017500000000574614576357161021735 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function circle2 = transformCircle3d(circle, tfm) %TRANSFORMCIRCLE3D Transform a 3D circle with a 3D affine transformation. % % CIRCLE2 = transformPlane3d(CIRCLE, TFM) % % Example % circle = [1 1 1 2 45 45 0]; % tfm = createRotationOz(pi); % circle2 = transformCircle3d(circle, tfm); % figure('color','w'); hold on; axis equal tight; view(-10,25); % xlabel('x'); ylabel('y'); zlabel('z'); % drawCircle3d(circle,'r'); drawPoint3d(circle(1:3),'r+') % drawCircle3d(circle2,'g'); drawPoint3d(circle2(1:3),'g+') % % See also % transforms3d, transformPoint3d, transformVector3d, transformLine3d, % transformPlane3d % % ------ % Author: oqilipo % E-mail: N/A % Created: 2022-12-03, using MATLAB 9.13.0.2080170 (R2022b) Update 1 % Copyright 2022-2023 parser = inputParser; addRequired(parser, 'circle', @(x) validateattributes(x, {'numeric'},... {'ncols',7,'real','finite','nonnan'})); addRequired(parser, 'tfm', @isTransform3d); parse(parser, circle, tfm); circle = parser.Results.circle; tfm = parser.Results.tfm; % Compute transformation from local basis to world basis initialTfm = localToGlobal3d(circle(1:3), circle(5), circle(6), circle(7)); % Add the additional transformation newTfm = tfm*initialTfm; % Convert to Euler angles [phi, theta, psi] = rotation3dToEulerAngles(newTfm, 'ZYZ'); % Create transformed circle circle2 = [transformPoint3d(circle(1:3), tfm), circle(4), theta, phi, psi]; matgeom-1.2.4/inst/geom3d/PaxHeaders/ellipsoidSurfaceArea.m0000644000000000000000000000013214576357161020643 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/ellipsoidSurfaceArea.m0000644000175000017500000000601114576357161022421 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function s = ellipsoidSurfaceArea(elli) %ELLIPSOIDSURFACEAREA Approximated surface area of an ellipsoid. % % S = ellipsoidSurfaceArea(ELLI) % Computes an approximation of the surface area of an ellipsoid. % ELLI is a 1-by-9 row vector given by [XC YC ZC A B C THETA PHI PSI], % where (XC YC ZC) is the center, (A B C) is the length of each semi axis % and (THETA PHI PSI) representes the orientation. % If ELLI is a 1-by-3 row vector, it is assumed to contain only the % lengths of semi-axes. % % This functions computes an approximation of the surface area, given by: % S = 4 * pi * ( (a^p * b^p + a^p * c^p + b^p * c^p) / 3) ^ (1/p) % with p = 1.6075. The resulting error should be less than 1.061%. % % Example % ellipsoidSurfaceArea % % See also % geom3d, ellipsePerimeter, oblateSurfaceArea, prolateSurfaceArea % % References % * http://en.wikipedia.org/wiki/Ellipsoid % * http://mathworld.wolfram.com/Ellipsoid.html % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-24, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform %% Parse input argument if size(elli, 2) == 9 a = elli(:, 4); b = elli(:, 5); c = elli(:, 6); elseif size(elli, 2) == 3 a = elli(:, 1); b = elli(:, 2); c = elli(:, 3); end p = 1.6075; s = 4 * pi * ( (a.^p .* b.^p + a.^p .* c.^p + b.^p .* c.^p) / 3) .^ (1 / p); matgeom-1.2.4/inst/geom3d/PaxHeaders/fillSphericalTriangle.m0000644000000000000000000000013214576357161021024 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/fillSphericalTriangle.m0000644000175000017500000000715114576357161022610 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = fillSphericalTriangle(sphere, p1, p2, p3, varargin) %FILLSPHERICALTRIANGLE Fill a triangle on a sphere. % % fillSphericalTriangle(SPHERE, PT1, PT2, PT3); % % % See also % fillSphericalPolygon, drawSphericalTriangle, drawSphere % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-22 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract data of the sphere ori = sphere(:, 1:3); r = sphere(4); % extract direction vectors for each point v1 = normalizeVector3d(p1 - ori); v2 = normalizeVector3d(p2 - ori); v3 = normalizeVector3d(p3 - ori); % create a plane tangent to the sphere containing first point plane = createPlane(v1, v1); % position on the plane of the direction vectors pp2 = planePosition(intersectLinePlane([ori v2], plane), plane); pp3 = planePosition(intersectLinePlane([ori v3], plane), plane); % create rough parametrization with 2 variables nTri = 5; s = linspace(0, 1, nTri); t = linspace(0, 1, nTri); ns = length(s); nt = length(t); s = repmat(s, [nt, 1]); t = repmat(t', [1, ns]); % convert to plane coordinates xp = s * pp2(1) + t .* (1-s) * pp3(1); yp = s * pp2(2) + t .* (1-s) * pp3(2); % convert to 3D coordinates (still on the 3D plane) x = plane(1) * ones(size(xp)) + plane(4) * xp + plane(7) * yp - ori(1); y = plane(2) * ones(size(xp)) + plane(5) * xp + plane(8) * yp - ori(2); z = plane(3) * ones(size(xp)) + plane(6) * xp + plane(9) * yp - ori(3); % project on the sphere norm = hypot(hypot(x, y), z); xn = x ./ norm * r + ori(1); yn = y ./ norm * r + ori(2); zn = z ./ norm * r + ori(3); if nargout == 0 % simply display the patch surf(xn, yn, zn, 'FaceColor', 'g', 'EdgeColor', 'none', varargin{:}); elseif nargout == 1 % display the patch and return a handle h = surf(xn, yn, zn, 'FaceColor', 'g', 'EdgeColor', 'none', varargin{:}); varargout = {h}; elseif nargout == 3 % If 3 outputs are required, return patch vertex coordinates varargout = {x, y, z}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawDome.m0000644000000000000000000000013214576357161016317 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawDome.m0000644000175000017500000001571114576357161020104 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawDome(varargin) %DRAWDOME Draw a dome (half-sphere, semi-sphere) as a mesh. % % drawDome(DOME) % Where DOME = [XC YC ZC R], draw the dome centered on the point with % coordinates [XC YC ZC] and with radius R, using a quad mesh. % % drawDome(Dome, V) % Where DOME = [XC YC ZC R] and V is a vector in the direction of the top % % drawDome(CENTER, R, V) % Where CENTER = [XC YC ZC], specifies the center and the radius with two % arguments and vector as third argument. % % drawDome(XC, YC, ZC, R, V) % Specifiy dome center, radius and vector as five arguments. % % drawDome(..., NAME, VALUE); % Specifies one or several options using parameter name-value pairs. % Available options are usual drawing options, as well as: % 'nPhi' the number of arcs used for drawing the meridians % 'nTheta' the number of circles used for drawing the parallels % % H = drawDome(...) % Return a handle to the graphical object created by the function. % % [X Y Z] = drawDome(...) % Return the coordinates of the vertices used by the dome. In this % case, the dome is not drawn. % % Example % % Draw four domes with different centers % figure(1); clf; hold on; % drawDome([0 0 1 1], 'FaceColor', 'b', 'EdgeColor', 'k', 'LineStyle', ':'); % drawDome([0 1 0 1], [0 1 0]); % drawDome([0 -1 0 0.5], [1 0 0]); % drawDome([0 -5 4 10], 'FaceAlpha', 0.5, 'EdgeColor', 'r', 'LineStyle', '-'); % view([-30 20]); axis equal; l = light; % % % Draw dome with different settings % figure(1); clf; % drawDome([10 20 30 10], [0 0 1], 'linestyle', ':', 'facecolor', 'r'); % axis([0 50 0 50 0 50]); axis equal; % l = light; % % % The same, but changes style using graphic handle % figure(1); clf; % h = drawDome([10 20 30 10], [1 0 0]); % set(h, 'linestyle', ':'); % set(h, 'facecolor', 'r'); % axis([0 50 0 50 0 50]); axis equal; % l = light; % % % Draw a dome with high resolution % figure(1); clf; % h = drawDome([10 20 30 10], 'nPhi', 360, 'nTheta', 180); % l = light; view(3); % % % See also % drawSphere % ------ % Author: Moritz Schappler % E-mail: N/A % Created: 2013-07-27 % Copyright 2013-2023 % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % process input options: when a string is found, assumes this is the % beginning of options options = {'FaceColor', 'g', 'LineStyle', 'none'}; for i = 1:length(varargin) if ischar(varargin{i}) if length(varargin) == 1 options = {'FaceColor', varargin{1}, 'LineStyle', 'none'}; else options = [options(1:end) varargin(i:end)]; end varargin = varargin(1:i-1); break; end end % Parse the input (try to extract center coordinates and radius) if isempty(varargin) % no input: assumes unit dome xc = 0; yc = 0; zc = 0; r = 1; v = [0;0;1]; elseif length(varargin) == 1 % one argument: concatenates center and radius dome = varargin{1}; xc = dome(:,1); yc = dome(:,2); zc = dome(:,3); r = dome(:,4); v = [0;0;1]; elseif length(varargin) == 2 % two arguments: concatenates center and radius with Rotation dome = varargin{1}; xc = dome(:,1); yc = dome(:,2); zc = dome(:,3); r = dome(:,4); v = varargin{2}; elseif length(varargin) == 3 % three arguments, corresponding to center and radius and rotation center = varargin{1}; xc = center(1); yc = center(2); zc = center(3); r = varargin{2}; v = varargin{3}; elseif length(varargin) == 5 % five arguments, corresponding to XC, YX, ZC, R and V xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; r = varargin{4}; v = varargin{5}; else error('drawDome: please specify center and radius'); end % Rotation given by z-Axis. Calculate rotation matrix v = v(:) / norm(v(:)); if all(abs(v(:)-[0;0;1]) < 1e-10) RM = eye(3); elseif all(abs(v(:) - [0;0;-1]) < 1e-10) RM = [[1;0;0], [0; -1; 0], [0; 0; -1]]; else % z-axis given by argument ez = v(:); % x-axis perpendicular ex = cross(ez, [0; 0; 1]); ex = ex/norm(ex); % y-axis to create right-handed coordinate system ey = cross(ez, ex); RM = [ex, ey, ez]; end % number of meridians nPhi = 32; ind = find(strcmpi('nPhi', options(1:2:end))); if ~isempty(ind) ind = ind(1); nPhi = options{2*ind}; options(2*ind-1:2*ind) = []; end % number of parallels nTheta = 8; ind = find(strcmpi('nTheta', options(1:2:end))); if ~isempty(ind) ind = ind(1); nTheta = options{2*ind}; options(2*ind-1:2*ind) = []; end % compute spherical coordinates theta = linspace(0, pi/2, nTheta+1); phi = linspace(0, 2*pi, nPhi+1); % convert to Cartesian coordinates and rotate % Rotate the Dome x = zeros(nPhi+1, nTheta+1); y = x; z = x; sintheta = sin(theta); dx = cos(phi')*sintheta*r; dy = sin(phi')*sintheta*r; dz = ones(length(phi),1)*cos(theta)*r; for i = 1:nPhi+1 for j = 1:nTheta+1 dxyz = RM*[dx(i, j);dy(i, j);dz(i, j)]; x(i, j) = xc + dxyz(1); y(i, j) = yc + dxyz(2); z(i, j) = zc + dxyz(3); end end % Process output if nargout == 0 % no output: draw the dome surf(hAx, x, y, z, options{:}); elseif nargout == 1 % one output: compute varargout{1} = surf(hAx, x, y, z, options{:}); elseif nargout == 3 varargout{1} = x; varargout{2} = y; varargout{3} = z; end matgeom-1.2.4/inst/geom3d/PaxHeaders/createPlane.m0000644000000000000000000000013214576357161017000 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createPlane.m0000644000175000017500000001463714576357161020573 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function plane = createPlane(varargin) %CREATEPLANE Create a plane in parametrized form. % % PLANE = createPlane(P1, P2, P3) % creates a plane containing the 3 points % % PLANE = createPlane(PTS) % The 3 points are packed into a single 3-by-3 array. % % PLANE = createPlane(P0, N); % Creates a plane from a point P0 and a normal N to the plane. The % parameter N is given either as a 3D vector (1-by-3 row vector), or as % [THETA PHI], where THETA is the colatitute (angle with the vertical % axis) and PHI is angle with Ox axis, counted counter-clockwise (both % given in radians). % % PLANE = createPlane(P0, Dip, DipDir); % Creates a plane from a point and from a dip and dip direction angles % of the plane. Parameters Dip and DipDir angles are given as numbers. % Dip : maximum inclination to the horizontal. % DipDir : direction of the horizontal trace of the line of dip, % measured clockwise from north. % % The created plane data has the following format: % PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], with % - (X0, Y0, Z0) is a point belonging to the plane % - (DX1, DY1, DZ1) is a first direction vector % - (DX2, DY2, DZ2) is a second direction vector % The 2 direction vectors are normalized and orthogonal. % % See also % planes3d, medianPlane % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE if length(varargin) == 1 % If a single input is provided, it can be: % * an array of three points belonging to the plane % * a cell array -> one plane per array element is created var = varargin{1}; if iscell(var) plane = zeros([length(var) 9]); for i = 1:length(var) plane(i,:) = createPlane(var{i}); end elseif size(var, 1) >= 3 % 3 points in a single array p1 = var(1,:); p2 = var(2,:); p3 = var(3,:); % create direction vectors v1 = p2 - p1; v2 = p3 - p1; % create plane plane = normalizePlane([p1 v1 v2]); else error ('MatGeom:createPlane', 'In case of single a.'); end elseif length(varargin) == 2 % Two arguments -> correspond to plane origin and plane normal % plane origin p0 = varargin{1}; % second parameter is either a 3D vector or a 3D angle (2 params) var = varargin{2}; if size(var, 2) == 2 % normal is given in spherical coordinates n = sph2cart2([var ones(size(var, 1))]); elseif size(var, 2) == 3 % normal is given by a 3D vector n = normalizeVector3d(var); else error ('MatGeom:createPlane', 'Can not parse plane normal.'); end % ensure same dimension for parameters if size(p0, 1) == 1 p0 = repmat(p0, [size(n, 1) 1]); end if size(n, 1) == 1 n = repmat(n, [size(p0, 1) 1]); end % find a vector not colinear to the normal, in the direction of [1 0 0] % first try with vector [0 0 1] v0 = repmat([0 0 1], [size(p0, 1) 1]); % if vectors are close to colinear, use vector [0 -1 0] inds = vectorNorm3d(cross(n, v0, 2)) < 1e-12; v0(inds, :) = repmat([0 -1 0], [sum(inds) 1]); % create direction vectors v1 = normalizeVector3d(cross(n, v0, 2)); v2 = -normalizeVector3d(cross(v1, n, 2)); % concatenate results in the array representing the plane plane = [p0 v1 v2]; elseif length(varargin) == 3 % Three input arguments: % * three points (as 1-by-3 or 1-by-N numeric arrays) % * center, Dip and DipDir (?) var1 = varargin{1}; var2 = varargin{2}; var3 = varargin{3}; if size(var1, 2) == 3 && size(var2, 2) == 3 && size(var3, 2) == 3 % input arguments are three points p1 = var1; p2 = var2; p3 = var3; % create direction vectors v1 = p2 - p1; v2 = p3 - p1; plane = normalizePlane([p1 v1 v2]); elseif size(var1, 2) == 3 && size(var2, 2) == 1 && size(var3, 2) == 1 p0 = var1; n = [sin(var2)*sin(var3) sin(var2)*cos(var3) cos(var2)]; % find a vector not colinear to the normal v0 = repmat([1 0 0], [size(p0, 1) 1]); inds = vectorNorm3d(cross(n, v0, 2))<1e-14; v0(inds, :) = repmat([0 1 0], [sum(inds) 1]); % create direction vectors v1 = normalizeVector3d(cross(n, v0, 2)); v2 = -normalizeVector3d(cross(v1, n, 2)); % concatenate result in the array representing the plane plane = [p0 v1 v2]; else error('MatGeom:createPlane', 'Wrong argument in "createPlane".'); end else error ('MatGeom:createPlane', 'Wrong number of input parameters.'); end matgeom-1.2.4/inst/geom3d/PaxHeaders/isPointInEllipsoid.m0000644000000000000000000000013214576357161020336 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/isPointInEllipsoid.m0000644000175000017500000000576314576357161022131 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointInEllipsoid(point, elli, varargin) %ISPOINTINELLIPSOID Check if a point is located inside a 3D ellipsoid. % % output = isPointInEllipsoid(input) % % Example % % create an ellipsoid % elli = [10 20 30 50 30 10 5 10 0]; % display it % figure; hold on; % drawEllipsoid(elli, 'FaceColor', 'g', 'FaceAlpha', .5, ... % 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); % view(3); axis equal; % % check for a point inside the ellipsoid % p1 = [20 30 35]; % b1 = isPointInEllipsoid(p1, elli) % ans = % 1 % % check for a point outside the ellipsoid % p2 = [-20 10 25]; % b2 = isPointInEllipsoid(p2, elli) % ans = % 0 % % % See also % equivalentEllipsoid, drawEllipsoid, isPointInEllipse % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-11-19, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % compute ellipse to unit circle transform rot = eulerAnglesToRotation3d(elli(7:9)); sca = createScaling3d(elli(4:6)); trans = inv(rot * sca); % transform points to unit sphere basis pTrans = bsxfun(@minus, point, elli(1:3)); pTrans = transformPoint3d(pTrans, trans); % test if norm is smaller than 1 b = sqrt(sum(power(pTrans, 2), 2)) - 1 <= tol; matgeom-1.2.4/inst/geom3d/PaxHeaders/distancePointTriangle3d.m0000644000000000000000000000013214576357161021276 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/distancePointTriangle3d.m0000644000175000017500000001654214576357161023066 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [dist, proj] = distancePointTriangle3d(point, triangle) %DISTANCEPOINTTRIANGLE3D Minimum distance between a 3D point and a 3D triangle. % % DIST = distancePointTriangle3d(PT, TRI); % Computes the minimum distance between the point PT and the triangle % TRI. The Point PT is given as a row vector of three coordinates. The % triangle TRI is given as a 3-by-3 array containing the coordinates of % each vertex in a row of the array: % TRI = [... % X1 Y1 Z1;... % X2 Y2 Z2;... % X3 Y3 Z3]; % % [DIST, PROJ] = distancePointTriangle3d(PT, TRI); % Also returns the coordinates of the projeced point. % % Example % tri = [1 0 0; 0 1 0;0 0 1]; % pt = [0 0 0]; % dist = distancePointTriangle3d(pt, tri) % dist = % 0.5774 % % See also % meshes3d, distancePointMesh, distancePointEdge3d, distancePointPlane % % Reference % * David Eberly (1999), "Distance Between Point and Triangle in 3D" % https://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf % * see Distance between a point and a triangle in 3d, by Gwendolyn Fischer. % (same algorithm, but different order of input argument) % % * https://fr.mathworks.com/matlabcentral/fileexchange/22857-distance-between-a-point-and-a-triangle-in-3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-03-08, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018-2023 INRA - Cepia Software Platform % triangle origin and vectors p1 = triangle(1,:); v12 = triangle(2,:) - p1; v13 = triangle(3,:) - p1; % identify coefficients of second order equation a = dot(v12, v12, 2); b = dot(v12, v13, 2); c = dot(v13, v13, 2); diffP = p1 - point; d = dot(v12, diffP, 2); e = dot(v13, diffP, 2); % f = dot(diffP, diffP, 2); % compute position of projected point in the plane of the triangle det = a * c - b * b ; s = b * e - c * d ; t = b * d - a * e ; % switch depending on the region where the projection occur if s + t < det if s < 0 if t < 0 % region 4 % The minimum distance must occur % * on the line t = 0 % * on the line s = 0 with t >= 0 % * at the intersection of the two lines if d < 0 % minimum on edge t = 0 with s > 0. t = 0; if a <= -d s = 1; else s = -d / a; end else % minimum on edge s = 0 s = 0; if e >= 0 t = 0; elseif c <= -e t = 1; else t = -e / c; end end else % region 3 % The minimum distance must occur on the line s = 0 s = 0; if e >= 0 t = 0; else if c <= -e t = 1; else t = -e / c; end end end else if t < 0 % region 5 % The minimum distance must occur on the line t = 0 t = 0; if d >= 0 s = 0; else if a <= -d s = 1; else s = -d / a; end end else % region 0 % the minimum distance occurs inside the triangle s = s / det; t = t / det; end end else if s < 0 % region 2 % The minimum distance must occur: % * on the line s + t = 1 % * on the line s = 0 with t <= 1 % * or at the intersection of the two (s=0; t=1) tmp0 = b + d; tmp1 = c + e; if tmp1 > tmp0 % minimum on edge s+t = 1, with s > 1 numer = tmp1 - tmp0; denom = a - 2 * b + c; if numer >= denom s = 1; else s = numer / denom; end t = 1 - s; else % minimum on edge s = 0, with t <= 1 s = 0; if tmp1 <= 0 t = 1; elseif e >= 0 t = 0; else t = -e / c; end end elseif t < 0 % region 6 % The minimum distance must occur % * on the line s + t = 1 % * on the line t = 0, with s <= 1 % * at the intersection of the two lines tmp0 = b + e; tmp1 = a + d; if tmp1 > tmp0 % minimum on edge s+t=1, with t > 0 numer = tmp1 - tmp0; denom = a - 2 * b + c; if numer > denom t = 1; else t = numer / denom; end s = 1 - t; else % minimum on edge t = 0 with s <= 1 t = 0; if tmp1 <= 0 s = 1; elseif d >= 0 s = 0; else s = -d / a; end end else % region 1 % The minimum distance must occur on the line s + t = 1 numer = (c + e) - (b + d); if numer <= 0 s = 0; else denom = a - 2 * b + c; if numer >= denom s = 1; else s = numer / denom; end end t = 1 - s; end end % compute coordinates of closest point on plane proj = p1 + s * v12 + t * v13; % distance between point and closest point on plane dist = sqrt(sum((point - proj).^2)); matgeom-1.2.4/inst/geom3d/PaxHeaders/spheres.m0000644000000000000000000000013214576357161016226 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/spheres.m0000644000175000017500000000471314576357161020013 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function spheres(varargin) %SPHERES Description of functions operating on 3D spheres. % % Spheres are represented by their center and their radius: % S = [xc yc zc r]; % % An ellipsoid is defined by: % ELL = [XC YC ZC A B C PHI THETA PSI] % where [XC YC ZY] is the center, [A B C] are length of semi-axes (in % decreasing order), and [PHI THETA PSI] are euler angles representing % the ellipsoid orientation. % % See also % createSphere, equivalentEllipsoid % intersectLineSphere, intersectPlaneSphere, sphericalVoronoiDomain % drawSphere, drawEllipsoid, fillSphericalTriangle, fillSphericalPolygon % drawSphericalEdge, drawSphericalTriangle, drawSphericalPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/geom3d/PaxHeaders/isParallel3d.m0000644000000000000000000000013214576357161017074 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/isParallel3d.m0000644000175000017500000000522114576357161020654 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isParallel3d(v1, v2, varargin) %ISPARALLEL3D Check parallelism of two 3D vectors. % % B = isParallel3d(V1, V2) % where V1 and V2 are 2 [1x3] arrays, returns 1 if the vectors are % parallels, and 0 otherwise. % % Also works when V1 and V2 are two [Nx3] arrays with same number of % rows. In this case, return a [Nx1] array containing 1 at the positions % of parallel vectors. % % Also works when one of V1 or V2 is scalar and the other one is [Nx3] % array, in this case return [Nx1] results. % % B = isPerpendicular3d(V1, V2, TOL) % Specifies the absolute tolerance (default is 1e-14). % % Example % isParallel3d([1 2 1], [2 4 2]) % ans = % 1 % % isParallel3d([1 2 1], [1 3 2]) % ans = % 0 % % See also % vectors3d, isPerpendicular3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-04-25 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % check if tolerance is specified tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % compute b = vectorNorm3d(crossProduct3d(v1, v2)) < tol; matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectBoxes3d.m0000644000000000000000000000013214576357161020005 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectBoxes3d.m0000644000175000017500000000506714576357161021575 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = intersectBoxes3d(box1, box2) %INTERSECTBOXES3D Intersection of two 3D bounding boxes. % % RES = intersectBoxes3d(BOX1, BOX2) % % Example % box1 = [5 20 5 30 10 50]; % box2 = [0 15 0 15 0 20]; % intersectBoxes3d(box1, box2) % ans = % 5 15 5 15 10 20 % % See also % boxes3d, drawBox3d, mergeBoxes3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % unify sizes of data if size(box1,1) == 1 box1 = repmat(box1, size(box2,1), 1); elseif size(box2, 1) == 1 box2 = repmat(box2, size(box1,1), 1); elseif size(box1,1) ~= size(box2,1) error('Bad size for inputs'); end % compute extreme coords mini = min(box1(:,2:2:end), box2(:,2:2:end)); maxi = max(box1(:,1:2:end), box2(:,1:2:end)); % concatenate result into a new box structure box = [maxi(:,1) mini(:,1) maxi(:,2) mini(:,2) maxi(:,3) mini(:,3)]; matgeom-1.2.4/inst/geom3d/PaxHeaders/registerPoints3d_icp.m0000644000000000000000000000013214576357161020660 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/registerPoints3d_icp.m0000644000175000017500000003232614576357161022446 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [transfo, pt, ER, t] = registerPoints3d_icp(p, q, varargin) %REGISTERPOINTS3D_ICP Computes rigid transform between two 3D point sets. % % TRANSFO = registerPoints3d_icp(SOURCE, TARGET) % Computes the 3D rigid transform (composed of a rotation and a % translation) that maps the shape defined by the SOURCE points onto the % shape defined by the the TARGET points, using the "Iterated Closest % Point" (ICP) algorithm. % Both SOURCE and TARGET are N-by-3 numeric arrays representing point % coordinates, not necessarily the same size. % The result TRANSFO is a 4-by-4 matrix representing the final affine % transform. % % TRANSFO = registerPoints3d_icp(SOURCE, TARGET, NITERS) % Specifies the number of iterations of the algorithm (default is 10). % % [TRANSFO, RES] = registerPoints3d_icp(...) % Also returns the result of the transform applied to SOURCE points. % % [TRANSFO, RES, ER] = registerPoints3d_icp(...) % Also returns the error according to the iteration, as a NITERS+1 array % of numeric values. % % [TRANSFO, RES, ER, T] = registerPoints3d_icp(...) % Also returns the time spent for each iteration, as a NITERS+1 array % of numeric values. T(1) corresponds to initialization time, T(end) % corresponds to the total processing time % % [...] = registerPoints3d_icp(..., PNAME, PVALUE) % Specifies additional optional arguments are parameter name-value pairs. % Supported parameter names are: % * 'Matching' The point matching method. Can be one of 'naive' % (the slowest), 'delaunay' (use a Delaunay diagram to reduce % computations) or 'kdTree' (use a kd-Tree data structure. This is % usually the fastest, but requires the Statistics Toolbox). % % % Example % registerPoints3d_icp % % See also % transforms3d, registerPoints3dAffine, pcregistericp % % Rewritten from the "icp" function, by Martin Kjer and Jakob Wilm, % Technical University of Denmark, 2012. % Notable differences: % * SOURCE and TARGET input arrays are given as N-by-3 arrays (using the % general MatGeom convention) rather than 3-by-N arrays. % * The resulting transform is packed into a single 4-by-4 array, % representing the affine transfom matrix in homogeneous coordinates. % * All the options available in the original file are not managed in this % port. % % ------ % Author: David Legland % e-mail: david.legland@inrae.fr % INRAE - BIA Research Unit - BIBS Platform (Nantes) % Created: 2023-05-30, using Matlab 9.14.0.2206163 (R2023a) % Copyright 2023 INRAE. %% Parse input arguments % parse input arguments using an instance of InputParser class parser = inputParser; % require source and target points sets, as N-by-3 and M-by-3 numeric arrays parser.addRequired('p', @(x) isreal(x) && size(x,2) == 3); parser.addRequired('q', @(x) isreal(x) && size(x,2) == 3); % optional number of iterations, default is 10. parser.addOptional('nIters', 10, @ (x) x > 0 && x < 10^5); % parse parameters as name-value pairs. % the algorithm to match transformed source to target validMatching = {'bruteForce', 'Delaunay', 'kDtree'}; parser.addParameter('Matching', 'bruteForce', @(x) any(strcmpi(x, validMatching))); % the criterium to minimize validMinimize = {'point', 'plane', 'lmapoint'}; parser.addParameter('Minimize', 'point', @(x) any(strcmpi(x,validMinimize))); % the normals computed for each point of the target cloud (used for plane % minimization) parser.addParameter('Normals', [], @(x) isreal(x) && size(x,2) == 3); parser.addParameter('NormalsData', [], @(x) isreal(x) && size(x,2) == 3); % should the function returns the list of transforms (one for each iter) parser.addParameter('ReturnAll', false, @(x) islogical(x)); % If Delaunay matching is used, the triangulation can be pre-computed parser.addParameter('Triangulation', [], @(x) isreal(x) && size(x,2) == 3); % Verbosity option parser.addParameter('Verbose', false, @(x) islogical(x)); % Weights associated to the points parser.addParameter('Weight', @(x) ones(length(x),1), @(x) isa(x,'function_handle')); parser.addParameter('WorstRejection', 0, @(x) isscalar(x) && x > 0 && x < 1); parser.parse(p, q, varargin{:}); args = parser.Results; %% Initialisations % Start timer tic; % number of iterations nIters = args.nIters; % transformed point set % initialized to initial point clouds, but will correspond to transformed % cloud during subsequent iterations pt = p; % allocate array for timing and RMS error at every iteration t = zeros(nIters+1,1); ER = zeros(nIters+1, 1); % Initialize total transform vector(s) and rotation matric(es). TT = zeros(1, 3, nIters+1); TR = repmat(eye(3,3), [1,1, nIters+1]); transfo = eye(4); transfoList = cell(nIters+1, 1); transfoList{1} = transfo; % perform pre-processing depending on matching method if strcmpi(args.Matching, 'Delaunay') % If Matching == 'Delaunay', a triangulation is needed DT = delaunayTriangulation(q); elseif strcmpi(args.Matching, 'kDtree') % If Matching == 'kDtree', a kD tree should be built % (requires Statistics Toolbox >= 7.3) kdTree = KDTreeSearcher(q); end % in case plane minimizer is used, check Normals" data exist if strcmpi(args.Minimize, 'plane') && isempty(args.Normals) args.Normals = estimateVertexNormals(q, 4); end t(1) = toc; %% Main loop for iIter = 1:nIters % Identify the points in Q that match the points in P. % Each function returns an array with as many rows as the number of % source points, containing the index of the closest target point, % and the distance between each pair of points. switch lower(args.Matching) case lower('bruteForce') [matchInds, mindist] = matchPoints_naive(pt, q); case lower('Delaunay') [matchInds, mindist] = matchPoints_Delaunay(pt, DT); case lower('kDtree') [matchInds, mindist] = matchPoints_kDtree(pt, kdTree); otherwise error('Unknown option for point matching: %s', args.Matching); end if iIter == 1 ER(iIter) = rms(mindist); end % Identify the rotation and translation parts of the motion transform. % Each function should return two output arguments: % R as a 3-by-3 matrix representing the (vectorial) 3D rotation % T as a 1-by-3 row vector representing the translation vector switch lower(args.Minimize) case 'point' % Determine weight vector weights = args.Weight(matchInds); [R,T] = eq_point(q(matchInds, :), pt, weights); case 'plane' normals = args.Normals(matchInds,:); weights = args.Weight(matchInds); [R,T] = eq_plane(q(matchInds,:), pt, normals, weights); case lower('lmaPoint') [R,T] = eq_lmaPoint(q(matchInds,:), pt); otherwise error('Unknown option for Minimizer: %s', args.Minimize); end % update the concatenated transform TR(:,:,iIter+1) = R * TR(:,:,iIter); TT(:,:,iIter+1) = TT(:,:,iIter)*R' + T; transfo = [R T' ; 0 0 0 1]; transfoList{iIter+1} = transfo * transfoList{iIter}; % apply last transform to source points pt = transformPoint3d(p, transfoList{iIter+1}); % root mean of objective function ER(iIter+1) = rmse(pt, q(matchInds, :)); t(iIter+1) = toc; end transfo = transfoList{end}; %% Utility functions function [inds, minDist] = matchPoints_naive(p, q) % retrieve number of points n = size(p, 1); % allocate memory inds = zeros(n, 1); minDist = zeros(n, 1); % iterate over points to match for i = 1:n dists = sum((q - p(i,:)).^2, 2); [minDist(i), inds(i)] = min(dists); end minDist = sqrt(minDist); % ---------------------------------------------------------------- function [inds, minDist] = matchPoints_Delaunay(p, DT) inds = nearestNeighbor(DT, p); minDist = sqrt(sum((p - DT.Points(inds,:)).^2, 1)); % ---------------------------------------------------------------- function [inds, minDist] = matchPoints_kDtree(p, kdTree) [inds, minDist] = knnsearch(kdTree, p); % ---------------------------------------------------------------- function [R, T] = eq_point(q, p, weights) % retrieve size of data points m = size(p, 1); n = size(q, 1); % normalize weights weights = weights ./ sum(weights); % find data centroid and deviations from centroid q_bar = weights' * q; q_mark = q - repmat(q_bar, n, 1); % find data centroid and deviations from centroid p_bar = weights' * p; p_mark = p - repmat(p_bar, m, 1); % Apply weights (need to apply to only one of the sets) p_mark = p_mark .* repmat(weights, 1, 3); % compute singular value decomposition N = p_mark' * q_mark; [U, ~, V] = svd(N); % retrieve rotation and translation parts R = V*diag([1 1 det(U*V')]) * U'; T = q_bar - p_bar * R'; % ---------------------------------------------------------------- function [R, T] = eq_plane(q, p, n, weights) n = n .* repmat(weights, 1, 3); c = cross(p, n, 2); cn = horzcat(c, n); C = cn' * cn; b = - [sum(sum((p-q).*repmat(cn(:,1),1,3).*n)); sum(sum((p-q).*repmat(cn(:,2),1,3).*n)); sum(sum((p-q).*repmat(cn(:,3),1,3).*n)); sum(sum((p-q).*repmat(cn(:,4),1,3).*n)); sum(sum((p-q).*repmat(cn(:,5),1,3).*n)); sum(sum((p-q).*repmat(cn(:,6),1,3).*n))]; X = C\b; cx = cos(X(1)); cy = cos(X(2)); cz = cos(X(3)); sx = sin(X(1)); sy = sin(X(2)); sz = sin(X(3)); R = [cy*cz cz*sx*sy-cx*sz cx*cz*sy+sx*sz; cy*sz cx*cz+sx*sy*sz cx*sy*sz-cz*sx; -sy cy*sx cx*cy]; T = X(4:6)'; % ---------------------------------------------------------------- function [R, T] = eq_lmaPoint(q, p) % Fit Rotation and Translation using Levenberg-Marquard minimization. % create the Rotation anonymous function for transforming points Rx = @(a)[1 0 0; 0 cos(a) -sin(a); 0 sin(a) cos(a)]; Ry = @(b)[cos(b) 0 sin(b); 0 1 0; -sin(b) 0 cos(b)]; Rz = @(g)[cos(g) -sin(g) 0; sin(g) cos(g) 0; 0 0 1]; Rot = @(x) Rx(x(1)) * Ry(x(2)) * Rz(x(3)); % anonymous function of the transform vector that transform the points myfun = @(x,xdata) xdata * Rot(x(1:3))' + repmat(x(4:6),length(xdata),1); % myfun = @(x,xdata)Rot(x(1:3))*xdata+repmat(x(4:6),1,length(xdata)); % minimizes the quantity: 'myfun(x,p) - q' options = optimset('Algorithm', 'levenberg-marquardt'); x = lsqcurvefit(myfun, zeros(1,6), p, q, [], [], options); R = Rot(x(1:3)); T = x(4:6); % ---------------------------------------------------------------- function ER = rmse(p1, p2) % Determine the RMS error between two point equally sized point clouds with % point correspondance. % ER = rmse(p1,p2) where p1 and p2 are n-by-3 numeric arrays. sqDist = sum((p1 - p2).^2, 2); ER = sqrt(mean(sqDist)); % ---------------------------------------------------------------- function n = estimateVertexNormals(p, k) % Least squares normal estimation from point clouds using PCA. % % P: input vertices, as a M-by-3 numeric array % K: number of neighbrs to consider for computing PCA % % Ref: % H. Hoppe, T. DeRose, T. Duchamp, J. McDonald, and W. Stuetzle. % Surface reconstruction from unorganized points. % In Proceedings of ACM Siggraph, pages 71:78, 1992. % % Requires the Statistics Toolbox m = size(p,1); n = zeros(m,3); % for each point, find its (k+1) nearest neighbor % (add 1 because each point is counted within its neighbors) neighbors = knnsearch(p, p, 'k', k+1); for i = 1:m % retrieve neighbors of current point x = p(neighbors(i, 2:end), :); % build the variance-covariance matrix to diagonalize p_bar = mean(x); P = (x - p_bar)' * (x - p_bar); % perform SVD [V, D] = eig(P); % choose the smallest eigenvalue [~, idx] = min(diag(D)); % return the corresponding eigenvector n(i,:) = V(:,idx)'; end matgeom-1.2.4/inst/geom3d/PaxHeaders/parallelLine3d.m0000644000000000000000000000013214576357161017410 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/parallelLine3d.m0000644000175000017500000000406614576357161021176 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = parallelLine3d(line, point) %PARALLELLINE3D Create 3D line parallel to another one. % % L2 = parallelLine3d(L, P) % Creates the 3D line L2, parallel to the line L, and containing the % point P. % % Example % % See also % parallelLine, parallelPlane % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-08-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform res = [point line(:, 4:6)]; matgeom-1.2.4/inst/geom3d/PaxHeaders/circles3d.m0000644000000000000000000000013214576357161016430 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/circles3d.m0000644000175000017500000000472014576357161020213 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function circles3d(varargin) %CIRCLES3D Description of functions operating on 3D circles. % % Circles are represented by a center, a radius and a 3D angle % representing the normal of the plane containing the circle. % C = [xc yc zc R theta phi psi]. % THETA is the colatitude of the normal, in degrees, between 0 and 180 % PHI is the azimut of the normal, in degrees, between 0 and 360 % PSI is the proper rotation of the circle around the normal, between 0 % and 360 degrees % The parameter PSI is used to locate a point on the 3D circle. % % See also % circle3dOrigin, circle3dPosition, circle3dPoint, intersectPlaneSphere % drawCircle3d, drawCircleArc3d, drawEllipse3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/geom3d/PaxHeaders/fillPolygon3d.m0000644000000000000000000000013214576357161017302 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/fillPolygon3d.m0000644000175000017500000001001214576357161021054 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = fillPolygon3d(varargin) %FILLPOLYGON3D Fill a 3D polygon specified by a list of vertex coords. % % fillPolygon3d(COORD, COLOR) % packs coordinates in a single [N*3] array. % COORD can also be a cell array of polygon, in this case each polygon is % drawn using the same color. % % fillPolygon3d(PX, PY, PZ, COLOR) % specifies coordinates in separate numeric vectors (either row or % columns) % % fillPolygon3d(..., PARAM, VALUE) % allows to specify some drawing parameter/value pairs as for the plot % function. % % H = fillPolygon3d(...) % also returns a handle to the list of created patch objects. % % Example % t = linspace(0, 2*pi, 100)'; % xt = 10 * cos(t); % yt = 5 * sin(t); % zt = zeros(100,1); % poly = [xt yt zt]; % figure; hold on; axis equal; fillPolygon3d(poly, 'c'); % drawPolygon3d(poly, 'linewidth', 2, 'color', 'k'); % % See also % polygons3d, drawPolygon3d, drawPolyline3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-01-05 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % Check if axes handle is specified if isAxisHandle(varargin{1}) hAx = varargin{1}; varargin(1) = []; else hAx = gca; end % check case we want to draw several curves, stored in a cell array var1 = varargin{1}; if iscell(var1) hold on; h = []; for i = 1:length(var1(:)) h = [h; fillPolygon3d(hAx, var1{i}, varargin{2:end})]; %#ok end if nargout>0 varargout{1}=h; end return; end % extract vertex coordinates if min(size(var1)) == 1 % if first argument is a vector (either row or column), then assumes % first argument contains x coords, second argument contains y coords % and third one the z coords px = var1; if length(varargin) < 3 error('geom3d:fillPolygon3d:Wrong number of arguments in fillPolygon3d'); end py = varargin{2}; pz = varargin{3}; varargin = varargin(4:end); else % first argument contains all three coordinates px = var1(:, 1); py = var1(:, 2); pz = var1(:, 3); varargin = varargin(2:end); end % extract color information if isempty(varargin) color = 'c'; else color = varargin{1}; varargin = varargin(2:end); end % fill the polygon h = fill3(hAx, px, py, pz, color, varargin{:}); if nargout>0 varargout{1}=h; end matgeom-1.2.4/inst/geom3d/PaxHeaders/edgeToLine3d.m0000644000000000000000000000013214576357161017023 xustar0030 mtime=1710874225.094193387 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/edgeToLine3d.m0000644000175000017500000000440014576357161020601 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = edgeToLine3d(edge) %EDGETOLINE3D Convert a 3D edge to a 3D straight line. % % LINE = edgeToLine3d(EDGE) % Returns the 3D straight line containing the 3D edge EDGE. % EDGE is represented as [X1 Y1 Z1 X2 Y2 Z2] % LINE is represented as [X0 Y0 Z0 DX DY DZ] % % Example % edge = [3 4 5 4 6 8]; % line = edgeToLine3d(edge) % line = % 3 4 5 1 2 3 % % See also % lines3d, edges3d, edgeToLine, lineToEdge3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-04-12, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018-2023 INRA - Cepia Software Platform line = [edge(:, 1:3) edge(:, 4:6)-edge(:, 1:3)]; matgeom-1.2.4/inst/geom3d/PaxHeaders/clipEdge3d.m0000644000000000000000000000013214576357161016520 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.094193387 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/clipEdge3d.m0000644000175000017500000000600414576357161020300 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function clipped = clipEdge3d(edge, box) %CLIPEDGE3D Clip a 3D edge with a cuboid box. % % CLIPPED = clipEdge3d(EDGE, BOX) % % Example % clipEdge3d % % See also % lines3d, edges3d, clipLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-04-12, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018-2023 INRA - Cepia Software Platform % compute supporting line of edge line = [edge(:, 1:3) edge(:,4:6)-edge(:,1:3)]; % clip supporting line clipped = clipLine3d(line, box); % for each clipped line, check that extremities are contained in edge nEdges = size(edge, 1); for i = 1:nEdges % if supporting line does not intersect the box, the edge is totally % clipped. if isnan(clipped(i,1)) continue; end % position of intersection points on the current supporting line pos1 = linePosition3d(clipped(i,1:3), line(i,:)); pos2 = linePosition3d(clipped(i,4:6), line(i,:)); if pos1 > 1 || pos2 < 0 % case of an edge totally clipped clipped(i,:) = NaN; elseif pos1 > 0 && pos2 < 1 % case of an edge already contained within the bounding box % -> nothin to do... continue; else % otherwise, need to adjust bounds of the clipped edge pos1 = max(pos1, 0); pos2 = min(pos2, 1); p1 = line(i,1:3) + pos1 * line(i,4:6); p2 = line(i,1:3) + pos2 * line(i,4:6); clipped(i,:) = [p1 p2]; end end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawAngleBetweenVectors3d.m0000644000000000000000000000013214576357161021570 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawAngleBetweenVectors3d.m0000644000175000017500000000743514576357161023361 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawAngleBetweenVectors3d(varargin) %DRAWANGLEBETWEENVECTORS3D Draw an arc between 2 vectors. % % drawAngleBetweenVectors3d(ORIGIN, VECTOR1, VECTOR2, RADIUS) % draws the arc between VECTOR1 and VECTOR2. % % drawAngleBetweenVectors3d(...,'ConjugateAngle',1) draws the conjugate % angle instead of the small angle. Default is false. % % H = drawAngleBetweenVectors3d(...) % returns the handle of the created LINE object % % Example % o=-100 + 200*rand(1,3); % v1=normalizeVector3d(-1 + 2*rand(1,3)); % v2=normalizeVector3d(-1 + 2*rand(1,3)); % r = rand; % figure('color','w'); view(3) % hold on; axis equal tight; xlabel X; ylabel Y; zlabel Z; % drawVector3d(o, v1, 'r') % drawVector3d(o, v2, 'g') % drawAngleBetweenVectors3d(o, v1, v2, r,'Color','m','LineWidth', 3) % % See also % drawCircleArc3d % ------ % Author: oqilipo % E-mail: N/A % Created: 2020-02-02 % Copyright 2020-2023 % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % retrieve inputs if length(varargin) < 4 error('Requires at least four input arguments'); end o = varargin{1}; v1 = varargin{2}; v2 = varargin{3}; r = varargin{4}; varargin(1:4) = []; % parse optional arguments p = inputParser; p.KeepUnmatched = true; logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addParameter(p, 'ConjugateAngle', false, logParValidFunc); parse(p, varargin{:}); conjugate = p.Results.ConjugateAngle; drawOptions = p.Unmatched; % Normal of the two vectors normal = normalizeVector3d(crossProduct3d(v1, v2)); % Align normal with the z axis. ROT = createRotationVector3d(normal,[0 0 1]); % Align first vector with x axis ROTv1 = createRotationVector3d(transformVector3d(v1,ROT),[1 0 0]); % Get Euler angles of the arc. % The arc is an flat object. Hence, use the 'ZYZ' convention. [PHI, THETA, PSI] = rotation3dToEulerAngles((ROTv1*ROT)', 'ZYZ'); % Get angle between the vectors angle = rad2deg(vectorAngle3d(v1, v2)); % Draw the arc if ~conjugate h = drawCircleArc3d(hAx, [o r [THETA PHI PSI] 0 angle], drawOptions); else h = drawCircleArc3d(hAx, [o r [THETA PHI PSI] 0 angle-360], drawOptions); end % Format output if nargout > 0 varargout{1} = h; end matgeom-1.2.4/inst/geom3d/PaxHeaders/isPointOnEdge3d.m0000644000000000000000000000013214576357161017513 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/isPointOnEdge3d.m0000644000175000017500000001030514576357161021272 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointOnEdge3d(point, edge, varargin) %ISPOINTONEDGE3D Test if a 3D point belongs to an edge. % % Usage % B = isPointOnEdge3d(POINT, EDGE) % B = isPointOnEdge3d(POINT, EDGE, TOL) % % Description % B = isPointOnEdge3d(POINT, EDGE) % with POINT being [xp yp zp], and EDGE being [x1 y1 z1 x2 y2 z2], % returns TRUE if the point is located on the edge, and FALSE otherwise. % % B = isPointOnEdge3d(POINT, EDGE, TOL) % Specify an optilonal tolerance value TOL. The tolerance is given as a % fraction of the norm of the edge direction vector. Default is 1e-14. % % B = isPointOnEdge3d(POINTARRAY, EDGE) % B = isPointOnEdge3d(POINT, EDGEARRAY) % When one of the inputs has several rows, return the result of the test % for each element of the array tested against the single parameter. % % B = isPointOnEdge3d(POINTARRAY, EDGEARRAY) % When both POINTARRAY and EDGEARRAY have the same number of rows, % returns a column vector with the same number of rows. % When the number of rows are different and both greater than 1, returns % a Np-by-Ne matrix of booleans, containing the result for each couple of % point and edge. % % Examples % % create a point array % points = [10 10 20;15 10 20; 30 10 20]; % % create an edge array % vertices = [10 10 20;20 10 20;20 20 20;10 20 20]; % edges = [vertices vertices([2:end 1], :)]; % % % Test one point and one edge % isPointOnEdge3d(points(1,:), edges(1,:)) % ans = % 1 % isPointOnEdge3d(points(3,:), edges(1,:)) % ans = % 0 % % % Test one point and several edges % isPointOnEdge3d(points(1,:), edges)' % ans = % 1 0 0 1 % % % Test several points and one edge % isPointOnEdge3d(points, edges(1,:))' % ans = % 1 1 0 % % % Test N points and N edges % isPointOnEdge3d(points, edges(1:3,:))' % ans = % 1 0 0 % % % Test NP points and NE edges % isPointOnEdge3d(points, edges) % ans = % 1 0 0 1 % 1 0 0 0 % 0 0 0 0 % % % See also % edges3d, points3d, isPointOnLine3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2021-02-24, using Matlab 9.9.0.1570001 (R2020b) Update 4 % Copyright 2021-2023 INRAE - BIA-BIBS % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % supporting line of the edge line = edgeToLine3d(edge); % check if point belong to supporting line onLine = isPointOnLine3d(point, line, tol); % check if position is within the [0 1] bounds pos = linePosition3d(point, line); withinBounds = pos > -tol & pos < 1+tol; b = onLine & withinBounds; matgeom-1.2.4/inst/geom3d/PaxHeaders/distancePointLine3d.m0000644000000000000000000000013214576357161020420 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/distancePointLine3d.m0000644000175000017500000000465514576357161022212 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function d = distancePointLine3d(point, line) %DISTANCEPOINTLINE3D Euclidean distance between 3D point and line. % % D = distancePointLine3d(POINT, LINE); % Returns the distance between point POINT and the line LINE, given as: % POINT : [x0 y0 z0] % LINE : [x0 y0 z0 dx dy dz] % D : (positive) scalar % % See also % lines3d, isPointOnLine3d, distancePointEdge3d, projPointOnLine3d, % % % References % http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-23 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % cf. Mathworld (distance point line 3d) for formula d = bsxfun(@rdivide, vectorNorm3d( ... crossProduct3d(line(:,4:6), bsxfun(@minus, line(:,1:3), point)) ), ... vectorNorm3d(line(:,4:6))); matgeom-1.2.4/inst/geom3d/PaxHeaders/medianPlane.m0000644000000000000000000000013214576357161016772 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/medianPlane.m0000644000175000017500000000477514576357161020567 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function plane = medianPlane(p1, p2) %MEDIANPLANE Create a plane in the middle of 2 points. % % PLANE = medianPlane(P1, P2) % Creates a plane in the middle of 2 points. % PLANE is perpendicular to line (P1 P2) and contains the midpoint of P1 % and P2. % The direction of the normal of PLANE is the same as the vector from P1 % to P2. % % See also % planes3d, createPlane % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % unify data dimension if size(p1, 1)==1 p1 = repmat(p1, [size(p2, 1) 1]); elseif size(p2, 1)==1 p2 = repmat(p2, [size(p1, 1) 1]); elseif size(p1, 1)~=size(p2, 1) error('data should have same length, or one data should have length 1'); end % middle point p0 = (p1 + p2)/2; % normal to plane n = p2-p1; % create plane from point and normal plane = createPlane(p0, n); matgeom-1.2.4/inst/geom3d/PaxHeaders/drawEdge3d.m0000644000000000000000000000013214576357161016526 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawEdge3d.m0000644000175000017500000001007014576357161020304 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEdge3d(varargin) %DRAWEDGE3D Draw 3D edge in the current axes. % % drawEdge3d(EDGE) draws the edge EDGE on the current axis. % EDGE has the form: [x1 y1 z1 x2 y2 z2]. No clipping is performed. % % drawEdge3d(AX,...) plots into AX instead of GCA. % % H = drawEdge3d(...) returns a handle H to the line object. % % Example % figure; axis equal; view(3) % p1 = [10 20 80]; % p2 = [80 10 20]; % p3 = [20 50 10]; % drawEdge3d(gca, [p1;p2],[p2;p3],'b'); % drawEdge3d([p1;p3],'k'); % pause(1) % drawEdge3d(gca, [p1 p2; p2 p3],'g'); % drawEdge3d(p1(1), p1(2), p1(3),p3(1), p3(2), p3(3),'Color','r','Marker','x'); % % See also % drawLine3d, clipLine3d, drawEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % extract edges from input arguments nCol = size(varargin{1}, 2); if nCol == 6 % all parameters in a single array edges = varargin{1}; varargin(1) = []; elseif nCol == 3 if isequal(size(varargin{1}), [2 3]) && length(varargin) == 1 % parameters are two points given as 2x3 edges = [varargin{1}(1,:) varargin{1}(2,:)]; elseif isequal(size(varargin{1}), [2 3]) && ~isnumeric(varargin{2}) % parameters are two points given as 2x3 edges = [varargin{1}(1,:) varargin{1}(2,:)]; varargin(1) = []; else % parameters are two points, or two arrays of points, of size N*3. edges = [varargin{1} varargin{2}]; varargin(1:2) = []; end elseif nargin >= 6 % parameters are 6 parameters of the edge : x1 y1 z1 x2 y2 and z2 edges = [varargin{1} varargin{2} varargin{3} varargin{4} varargin{5} varargin{6}]; varargin(1:6) = []; end % Parse and check inputs isEdge3d = @(x) validateattributes(x,{'numeric'},... {'nonempty','size',[nan,6]}); defOpts.Color = 'b'; [~, edges, varargin] = ... parseDrawInput(hAx, isEdge3d, 'line', defOpts, edges, varargin{:}); % identify indices of valid edge (not containing any NaN's). inds = sum(isnan(edges), 2) == 0; % draw edges h = line(... [edges(inds, 1) edges(inds, 4)]', ... [edges(inds, 2) edges(inds, 5)]', ... [edges(inds, 3) edges(inds, 6)]', varargin{:}, ... 'Parent', hAx); % return handle to created Edges if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/angleSort3d.m0000644000000000000000000000013214576357161016742 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/angleSort3d.m0000644000175000017500000000677614576357161020542 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = angleSort3d(pts, varargin) %ANGLESORT3D Sort 3D coplanar points according to their angles in plane. % % PTS2 = angleSort3d(PTS); % Considers all points are located on the same plane, and sort them % according to the angle on plane. PTS is a [Nx2] array. Note that the % result depends on the plane orientation: points can be in reverse order % compared to expected. The reference plane is computed based on the % first three points. % % PTS2 = angleSort3d(PTS, PTS0); % Computes angles between each point of PTS and PT0. By default, uses % centroid of points. % % PTS2 = angleSort3d(PTS, PTS0, PTS1); % Specifies the point which will be used as a start. % % [PTS2, I] = angleSort3d(...); % Also return in I the indices of PTS, such that PTS2 = PTS(I, :); % % See also % points3d, angles3d, angleSort % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-24 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % default values pt0 = mean(pts, 1); pt1 = pts(1,:); if length(varargin)==1 pt0 = varargin{1}; elseif length(varargin)==2 pt0 = varargin{1}; pt1 = varargin{2}; end % create support plane plane = createPlane(pts(1:3, :)); % project points onto the plane pts2d = planePosition(pts, plane); pt0 = planePosition(pt0, plane); pt1 = planePosition(pt1, plane); % compute origin angle theta0 = atan2(pt1(2)-pt0(2), pt1(1)-pt0(1)); theta0 = mod(theta0 + 2*pi, 2*pi); % translate to reference point n = size(pts, 1); pts2d = pts2d - repmat(pt0, [n 1]); % compute angles angle = atan2(pts2d(:,2), pts2d(:,1)); angle = mod(angle - theta0 + 4*pi, 2*pi); % sort points according to angles [angle, I] = sort(angle); %#ok % format output if nargout<2 varargout{1} = pts(I, :); elseif nargout==2 varargout{1} = pts(I, :); varargout{2} = I; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawTorus.m0000644000000000000000000000013214576357161016547 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawTorus.m0000644000175000017500000001037414576357161020334 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawTorus(varargin) %DRAWTORUS Draw a torus (3D ring). % % drawTorus(TORUS) % Draws the torus on the current axis. TORUS is given by: % [XC YC ZY R1 R2 THETA PHI] % where (XC YZ ZC) is the center of the torus, R1 is the main radius, R2 % is the radius of the torus section, and (THETA PHI) is the angle of the % torus normal vector (both in degrees). % % drawTorus(..., PNAME, PVALUE) % Specifies a set of parameter name-value pairs. Parameter names include % plitting options ('facecolor', 'linestyle'...), or options specific to % torus: % 'nPhi' number of meridians used to draw the torus (default is 60). % 'nTheta' number of parallels used to draw the torus (default is 60). % % % Example % % draw sample torus % figure; % drawTorus([50 50 50 30 10 30 45]); % axis equal; view([95 10]); light; % % See also % drawEllipsoid, revolutionSurface, torusMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Default values % number of meridians nPhi = 60; % number of parallels nTheta = 60; %% Extract input arguments % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); torus = varargin{1}; varargin(1) = []; center = torus(:, 1:3); r1 = torus(:, 4); r2 = torus(:, 5); nTorus = size(center, 1); normal = zeros(nTorus, 2); if size(torus, 2) >= 7 normal = torus(:, 6:7); end % default set of options for drawing meshes options = {'FaceColor', 'g', 'linestyle', 'none'}; while length(varargin) > 1 switch lower(varargin{1}) case 'nphi' nPhi = varargin{2}; case 'ntheta' nTheta = varargin{2}; otherwise % assumes this is drawing option options = [options varargin(1:2)]; %#ok end varargin(1:2) = []; end %% Draw the torus % allocate array of handles hs = gobjects(1, nTorus); % save hold state holdState = ishold(hAx); hold(hAx, 'on'); % iteate over torusses for i = 1:nTorus % create base torus circle = circleToPolygon([r1(i) 0 r2(i)], nTheta); [x, y, z] = revolutionSurface(circle, linspace(0, 2*pi, nPhi)); % transform torus trans = localToGlobal3d([center(i,:) normal(i,:)]); [x, y, z] = transformPoint3d(x, y, z, trans); % draw the surface hs(i) = surf(hAx, x, y, z, options{:}); end % restore hold state if ~holdState hold(hAx, 'off'); end %% Process output arguments if nargout > 0 varargout = {hs}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/prolateSurfaceArea.m0000644000000000000000000000013214576357161020325 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/prolateSurfaceArea.m0000644000175000017500000000470214576357161022110 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function S = prolateSurfaceArea(elli, varargin) %PROLATESURFACEAREA Approximated surface area of a prolate ellipsoid. % % S = prolateSurfaceArea(R1,R2) % % Example % prolateSurfaceArea % % See also % geom3d, ellipsoidSurfaceArea, oblateSurfaceArea % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-07-03, using Matlab 7.9.0.529 (R2009b) % Copyright 2015-2023 INRA - Cepia Software Platform %% Parse input argument if size(elli, 2) == 7 R1 = elli(:, 4); R2 = elli(:, 5); elseif size(elli, 2) == 1 && ~isempty(varargin) R1 = elli(:, 1); R2 = varargin{1}; end assert(R1 > R2, 'first radius must be larger than second radius'); % surface theorique d'un ellipsoide prolate % cf http://fr.wikipedia.org/wiki/Ellipso%C3%AFde_de_r%C3%A9volution e = sqrt(R1.^2 - R2.^2) ./ R1; S = 2 * pi * R2.^2 + 2 * pi * R1 .* R2 .* asin(e) ./ e; matgeom-1.2.4/inst/geom3d/PaxHeaders/fitLine3d.m0000644000000000000000000000013214576357161016376 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/fitLine3d.m0000644000175000017500000000621014576357161020155 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = fitLine3d(points) %FITLINE3D Fit a 3D line to a set of points. % % LINE = fitLine3d(PTS) % % Example % pts = randn(300, 3); % pts = transformPoint3d(pts, createScaling3d([6 4 2])); % pts = transformPoint3d(pts, createRotationOx(pi/6)); % pts = transformPoint3d(pts, createRotationOy(pi/4)); % pts = transformPoint3d(pts, createRotationOz(pi/3)); % pts = transformPoint3d(pts, createTranslation3d([5 4 3])); % elli = equivalentEllipsoid(pts); % figure; drawPoint3d(pts); axis equal; % hold on; drawEllipsoid(elli, ... % 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); % line = fitLine3d(pts); % drawLine3d(line, 'color', 'm', 'LineWidth', 4); % % See also % lines3d, equivalentEllipsoid, fitPlane, fitLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-11-11, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % number of points n = size(points, 1); % compute centroid center = mean(points); % compute the covariance matrix covPts = cov(points)/n; % perform a principal component analysis with 2 variables, % to extract inertia axes [U, S] = svd(covPts); % sort axes from greater to lower [dummy, ind] = sort(diag(S), 'descend'); %#ok % format U to ensure first axis points to positive x direction U = U(ind, :); if U(1,1) < 0 U = -U; % keep matrix determinant positive U(:,3) = -U(:,3); end % create row vector representing the line line = [center U(:,1)']; matgeom-1.2.4/inst/geom3d/PaxHeaders/createRotationOy.m0000644000000000000000000000013214576357161020050 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createRotationOy.m0000644000175000017500000000674114576357161021640 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createRotationOy(varargin) %CREATEROTATIONOY Create the 4x4 matrix of a 3D rotation around y-axis. % % TRANS = createRotationOy(THETA); % Returns the transform matrix corresponding to a rotation by the angle % THETA (in radians) around the Oy axis. A rotation by an angle of PI/2 % would transform the vector [0 0 1] into the vector [1 0 0]. % % The returned matrix has the form: % [ cos(THETA) 0 sin(THETA) 0 ] % [ 0 1 0 0 ] % [-sin(THETA) 0 cos(THETA) 0 ] % [ 0 0 0 1 ] % % TRANS = createRotationOy(ORIGIN, THETA); % TRANS = createRotationOy(X0, Y0, Z0, THETA); % Also specifies origin of rotation. The result is similar as performing % translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). % % % See also % transforms3d, transformPoint3d, createRotationOx, createRotationOz % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % default values dx = 0; dy = 0; dz = 0; theta = 0; % get input values if length(varargin) == 1 % only one argument -> rotation angle theta = varargin{1}; elseif length(varargin) == 2 % origin point (as array) and angle var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); theta = varargin{2}; elseif length(varargin) == 3 % origin (x and y) and angle dx = varargin{1}; dy = varargin{2}; dz = 0; theta = varargin{3}; elseif length(varargin) == 4 % origin (x and y) and angle dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; theta = varargin{4}; end % compute coefs cot = cos(theta); sit = sin(theta); % create transformation trans = [... cot 0 sit 0;... 0 1 0 0;... -sit 0 cot 0;... 0 0 0 1]; % add the translation part t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; trans = t * trans / t; matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectLineTriangle3d.m0000644000000000000000000000013214576357161021302 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectLineTriangle3d.m0000644000175000017500000001211614576357161023063 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [point, pos, isInside] = intersectLineTriangle3d(line, triangle, varargin) %INTERSECTLINETRIANGLE3D Intersection point of a 3D line and a 3D triangle. % % POINT = intersectLineTriangle3d(LINE, TRI) % Compute coordinates of the intersection point between the line LINE and % the triangle TRI. % LINE is a 1-by-6 row vector given as: [X0 Y0 Z0 DX DY DZ] % TRI is given either as a row vector [X1 Y1 Z1 X2 Y2 Z2 X3 Y3 Z3], or as % a 3-by-3 array, each row containing coordinates of one of the triangle % vertices. % The result is a 1-by-3 array containing coordinates of the intesection % point, or [NaN NaN NaN] if the line and the triangle do not intersect. % % [POINT POS] = intersectLineTriangle3d(LINE, TRI) % Also returns the position of the intersection point on the line, or NaN % if the line and the supporting plane of the triangle are parallel. % % [POINT POS ISINSIDE] = intersectLineTriangle3d(LINE, TRI) % Also returns a boolean value, set to true if the line and the triangle % intersect each other. Can be used for testing validity of result. % % Example % line = [1 1 0 0 0 1]; % tri = [0 0 5;5 0 0;0 5 0]; % intersectLineTriangle3d(line, tri) % ans = % 1 1 3 % % See also % points3d, lines3d, polygons3d, intersectRayPolygon3d, % distancePointTriangle3d % % References % Algorithm adapted from SoftSurfer Ray/Segment-Triangle intersection % http://softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-04-08, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Default values % default return value point = [NaN NaN NaN]; pos = NaN; isInside = false; tol = 1e-13; if ~isempty(varargin) tol = varargin{1}; end %% Process inputs % triangle edge vectors if size(triangle, 2) > 3 % triangle is given as a 1-by-9 row vector t0 = triangle(1:3); u = triangle(4:6) - t0; v = triangle(7:9) - t0; else % triangle is given as a 3-by-3 array t0 = triangle(1, 1:3); u = triangle(2, 1:3) - t0; v = triangle(3, 1:3) - t0; end %% Compute intersection % triangle normal n = cross(u, v); % test for degenerate case of flat triangle if vectorNorm3d(n) < tol return; end % line direction vector dir = line(4:6); % vector between triangle origin and line origin w0 = line(1:3) - t0; % compute projection of each vector on the plane normal a = -dot(n, w0); b = dot(n, dir); % test case of line parallel to the triangle if abs(b) < tol return; end % compute intersection point of line with supporting plane % If r < 0: point before ray % If r > 1: point after edge pos = a / b; % coordinates of intersection point point = line(1:3) + pos * dir; %% test if intersection point is inside triangle % normalize direction vectors of triangle edges uu = dot(u, u); uv = dot(u, v); vv = dot(v, v); % coordinates of vector v in triangle basis w = point - t0; wu = dot(w, u); wv = dot(w, v); % normalization constant D = uv^2 - uu * vv; % test first coordinate s = (uv * wv - vv * wu) / D; if s < 0.0 || s > 1.0 point = [NaN NaN NaN]; pos = NaN; return; end % test second coordinate, and third triangle edge t = (uv * wu - uu * wv) / D; if t < 0.0 || (s + t) > 1.0 point = [NaN NaN NaN]; pos = NaN; return; end % set the validity flag isInside = true; matgeom-1.2.4/inst/geom3d/PaxHeaders/readme.txt0000644000000000000000000000013114576357160016373 xustar0030 mtime=1710874224.414194037 29 atime=1710874224.41019404 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/readme.txt0000644000175000017500000000307614576357160020162 0ustar00juanpijuanpi00000000000000Description of the geom3d library. The aim of geom3d library is to handle and visualize 3D geometric primitives such as points, lines, planes, polyhedra... It provides low-level functions for manipulating 3D geometric primitives, making easier the development of more complex geometric algorithms. Some features of the library are: - creation of various shapes (3D points, 3D lines, planes, polyhedra...) through an intuitive syntax. Ex: createPlane(p1, p2, p3) to create a plane through 3 points. - derivation of new shapes: intersection between 2 planes, intersection between a plane and a line, between a sphere and a line... - functions for 3D polygons and polyhedra. Polyhedra use classical vertex-faces arrays (face array contain indices of vertices), and support faces with any number of vertices. Some basic models are provided (createOctaedron, createCubeoctaedron...), as well as some computation (like faceNormal or centroid) - manipulation of planar transformation. Ex.: ROT = createRotationOx(THETA); P2 = transformPoint3d(P1, ROT); - direct drawing of shapes with specialized functions. Clipping is performed automatically for infinite shapes such as lines or rays. Ex: drawPoint3d([50 50 25; 20 70 10], 'ro'); % draw some points drawLine3d([X0 Y0 Z0 DX DY DZ]); % clip and draw straight line Some functions require the geom2d package. Additional help is provided in geom3d/Contents.m file, as well as summary files like 'points3d.m' or 'lines3d.m'. matgeom-1.2.4/inst/geom3d/PaxHeaders/createScaling3d.m0000644000000000000000000000013214576357161017550 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createScaling3d.m0000644000175000017500000000727514576357161021343 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createScaling3d(varargin) %CREATESCALING3D Create the 4x4 matrix of a 3D scaling. % % TRANS = createScaling3d(S); % returns the scaling transform corresponding to a scaling factor S in % each direction. S can be a scalar, or a 1-by-3 vector containing the % scaling factor in each direction. % % TRANS = createScaling3d(SX, SY, SZ); % returns the scaling transform corresponding to a different scaling % factor in each direction. % % The returned matrix has the form : % [SX 0 0 0] % [ 0 SY 0 0] % [ 0 0 SZ 0] % [ 0 0 0 0] % % See also % transforms3d, transformPoint3d, transformVector3d, createTranslation3d, % createRotationOx, createRotationOy, createRotationOz % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-04-20 % Copyright 2006-2023 INRA - TPV URPOI - BIA IMASTE %% default arguments sx = 1; sy = 1; sz = 1; center = [0 0 0]; %% process input parameters if nargin == 1 % only one argument -> scaling factor [sx, sy, sz]= parseScalingFactors(varargin{1}); elseif nargin == 2 % 2 arguments, giving center and uniform scaling center = varargin{1}; [sx, sy, sz]= parseScalingFactors(varargin{2}); elseif nargin == 3 % 3 arguments, giving scaling in each direction sx = varargin{1}; sy = varargin{2}; sz = varargin{3}; elseif nargin == 4 % 4 arguments, giving center and scaling in each direction center = varargin{1}; sx = varargin{2}; sy = varargin{3}; sz = varargin{4}; end %% create the scaling matrix trans = [... sx 0 0 center(1)*(1-sx);... 0 sy 0 center(2)*(1-sy);... 0 0 sz center(3)*(1-sz);... 0 0 0 1]; %% Helper function function [sx, sy, sz] = parseScalingFactors(var) if length(var)==1 % same scaling factor in each direction sx = var; sy = var; sz = var; elseif length(var)==3 % scaling is a vector, giving different scaling in each direction sx = var(1); sy = var(2); sz = var(3); else error('wrong size for first parameter of "createScaling3d"'); end matgeom-1.2.4/inst/geom3d/PaxHeaders/sphericalVoronoiDomain.m0000644000000000000000000000013214576357161021233 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/sphericalVoronoiDomain.m0000644000175000017500000000614014576357161023014 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly = sphericalVoronoiDomain(refPoint, neighbors) %SPHERICALVORONOIDOMAIN Compute a spherical voronoi domain. % % POLY = sphericalVoronoiDomain(GERM, NEIGHBORS) % GERM is a 1-by-3 row vector representing cartesian coordinates of a % point on the unit sphere (in X, Y Z order) % NEIGHBORS is a N-by-3 array representing cartesian coordinates of the % germ neighbors. It is expected that NEIGHBORS contains only neighbors % that effectively contribute to the voronoi domain. % % Example % sphericalVoronoiDomain % % See also % drawSphericalPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-11-17, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % reference sphere sphere = [0 0 0 1]; % number of neigbors, and number of sides of the domain nbSides = size(neighbors, 1); % compute planes containing separating circles planes = zeros(nbSides, 9); for i = 1:nbSides planes(i,1:9) = normalizePlane(medianPlane(refPoint, neighbors(i,:))); end % allocate memory lines = zeros(nbSides, 6); intersects = zeros(2 * nbSides, 3); % compute circle-circle intersections for i = 1:nbSides ind2 = mod(i, nbSides) + 1; lines(i,1:6) = intersectPlanes(planes(i,:), planes(ind2,:)); intersects(2*i-1:2*i,1:3) = intersectLineSphere(lines(i,:), sphere); end % keep only points in the same direction than refPoint ind = dot(intersects, repmat(refPoint, [2 * nbSides 1]), 2) > 0; poly = intersects(ind,:); matgeom-1.2.4/inst/geom3d/PaxHeaders/fitAffineTransform3d.m0000644000000000000000000000013214576357161020573 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/fitAffineTransform3d.m0000644000175000017500000000623714576357161022363 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = fitAffineTransform3d(ref, src) %FITAFFINETRANSFORM3D Compute the affine transform that best register two 3D point sets. % % TRANS = fitAffineTransform3d(REF, SRC) % Returns the affine transform matrix that minimizes the distance between % the reference point set REF and the point set SRC after transformation. % Both REF and SRC must by N-by-3 arrays with the same number of rows, % and the points must be in correspondence. % The function minimizes the sum of the squared distances: % CRIT = sum(distancePoints3d(REF, transformPoint3d(PTS, TRANSFO)).^2); % % Example % N = 50; % pts = rand(N, 3)*10; % trans = createRotationOx([5 4 3], pi/4); % pts2 = transformPoint3d(pts, trans); % pts3 = pts2 + randn(N, 3)*2; % fitted = fitAffineTransform3d(pts, pts2); % % % See also % transforms3d, transformPoint3d, transformVector3d, % fitAffineTransform2d, registerPoints3dAffine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-07-31, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRAE - Cepia Software Platform % number of points N = size(src, 1); if size(ref, 1) ~= N error('Requires the same number of points for both arrays'); end % main matrix of the problem tmp = [src(:,1) src(:,2) src(:,3) ones(N,1)]; A = [... tmp zeros(N, 8) ; ... zeros(N, 4) tmp zeros(N, 4) ; ... zeros(N, 8) tmp ]; % conditions initialisations B = [ref(:,1) ; ref(:,2) ; ref(:,3)]; % compute coefficients using least square coefs = A\B; % format to a matrix trans = [coefs(1:4)' ; coefs(5:8)'; coefs(9:12)'; 0 0 0 1]; matgeom-1.2.4/inst/geom3d/PaxHeaders/recenterTransform3d.m0000644000000000000000000000013214576357161020507 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/recenterTransform3d.m0000644000175000017500000000545714576357161022302 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = recenterTransform3d(transfo, center) %RECENTERTRANSFORM3D Change the fixed point of an affine 3D transform. % % TRANSFO2 = recenterTransform3d(TRANSFO, CENTER) % where TRANSFO is a 4x4 transformation matrix, and CENTER is a 1x3 row % vector, computes the new transformations that uses the same linear part % (defined by the upper-left 3x3 corner of the transformation matrix) as % the initial transform, and that will leave the point CENTER unchanged. % % % % Example % % creating a re-centered rotation using: % rot1 = createRotationOx(pi/3); % rot2 = recenterTransform3d(rot1, [3 4 5]); % % will give the same result as: % rot3 = createRotationOx([3 4 5], pi/3); % % % See also % transforms3d, createRotationOx, createRotationOy, createRotationOz % createTranslation3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-27, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % remove former translation part res = eye(4); res(1:3, 1:3) = transfo(1:3, 1:3); % create translations t1 = createTranslation3d(-center); t2 = createTranslation3d(center); % compute translated transform res = t2*res*t1; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawPartialPatch.m0000644000000000000000000000013214576357161020007 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawPartialPatch.m0000644000175000017500000000534714576357161021600 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function drawPartialPatch(u, v, z, varargin) %DRAWPARTIALPATCH Draw surface patch, with 2 parametrized surfaces. % % usage: % drawSurfPatch(u, v, zuv) % where u, v, and zuv are three matrices the same size, u and % corresponding to each parameter, and zuv being equal to a function of u % and v. % % drawSurfPatch(u, v, zuv, p0) % If p0 is specified, two lines with u(p0(1)) and v(p0(2)) are drawn on % the surface % % % See also % drawPolyline3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-24 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % prepare figure hold on; % draw the surface interior surf(u, v, z, 'FaceColor', 'g', 'EdgeColor', 'none'); % draw the surface boundaries drawPolyline3d(u(1,:), v(1,:), z(1,:)) drawPolyline3d(u(end,:), v(end,:), z(end,:)) drawPolyline3d(u(:,end), v(:,end), z(:,end)) drawPolyline3d(u(:,1), v(:,1), z(:,1)) % eventually draw two perpendicular lines on the surface if ~isempty(varargin) pos = varargin{1}; drawPolyline3d(u(pos(1),:), v(pos(1),:), z(pos(1),:)); drawPolyline3d(u(:,pos(2)), v(:,pos(2)), z(:,pos(2))); end matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectEdgePlane.m0000644000000000000000000000013214576357161020322 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectEdgePlane.m0000644000175000017500000000777614576357161022123 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = intersectEdgePlane(edge, plane, varargin) %INTERSECTEDGEPLANE Return intersection point between a plane and a edge. % % PT = intersectEdgePlane(edge, PLANE) return the intersection point of % the given edge and the given plane. % PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % edge : [x1 y1 z1 x2 y2 z2] % PT : [xi yi zi] % If EDGE and PLANE are parallel, return [NaN NaN NaN]. % If EDGE (or PLANE) is a matrix with 6 (or 9) columns and N rows, result % is an array of points with N rows and 3 columns. % % Example: % edge = [5 5 -1 5 5 1]; % plane = [0 0 0 1 0 0 0 1 0]; % intersectEdgePlane(edge, plane) % should return [5 5 0]. % ans = % 5 5 0 % % See also % planes3d, intersectLinePlane, createLine3d, createPlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-04-24, from intersectLinePlane % Copyright 2007-2023 INRA - TPV URPOI - BIA IMASTE % extract tolerance for determination of parallel edges and planes tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % number of planes and edges np = size(plane, 1); ne = size(edge, 1); % unify sizes of data if np ~= ne if ne == 1 % one edge and many planes edge = edge(ones(np, 1), :); elseif np == 1 % one plane possible many edges plane = plane(ones(ne, 1), :); else % N planes and M edges, not allowed for now. error('Should have the same number of planes and edges'); end end % initialize empty arrays point = zeros(size(plane, 1), 3); t = zeros(size(plane,1),3); % plane normal n = cross(plane(:,4:6), plane(:,7:9), 2); % create line supporting edge line = createLine3d(edge(:,1:3), edge(:,4:6)); % get indices of edge and plane which are parallel par = abs(dot(n, line(:,4:6), 2)) < tol; point(par,:) = NaN; t(par) = NaN; % difference between origins of plane and edge dp = plane(:, 1:3) - line(:, 1:3); % relative position of intersection on line %t = dot(n(~par,:), dp(~par,:), 2)./dot(n(~par,:), line(~par,4:6), 2); t(~par) = dot(n(~par,:), dp(~par,:), 2) ./ dot(n(~par,:), line(~par,4:6), 2); % compute coord of intersection point %point(~par, :) = line(~par,1:3) + repmat(t,1,3).*line(~par,4:6); point(~par, :) = line(~par,1:3) + repmat(t(~par),1,3) .* line(~par,4:6); % set points outside of edge to [NaN NaN NaN] point(t<0, :) = NaN; point(t>1, :) = NaN; matgeom-1.2.4/inst/geom3d/PaxHeaders/createRay3d.m0000644000000000000000000000013214576357161016723 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createRay3d.m0000644000175000017500000000402214576357161020501 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ray = createRay3d(p1, p2) %CREATERAY3D Create a 3D ray. % % RAY = createRay3d(P1, P2) % Create a ray starting from point P1 and going in the direction of point % P2. % % Example % createRay3d % % See also % creatLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-05-25, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) ray = [p1 (p2-p1)]; matgeom-1.2.4/inst/geom3d/PaxHeaders/fillSphericalPolygon.m0000644000000000000000000000013214576357161020706 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/fillSphericalPolygon.m0000644000175000017500000000436614576357161022477 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = fillSphericalPolygon(sphere, poly, germ) %FILLSPHERICALPOLYGON Fill a spherical polygon. % % fillSphericalPolygon(SPHERE, POLY, GERM) % % % Example % fillSphericalPolygon % % See also % drawSphericalPolygon, fillSphericalTriangle, drawSphere % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform nv = size(poly, 1); h = zeros(nv, 1); for i = 1:nv v1 = poly(i, :); v2 = poly(mod(i, nv) + 1, :); h(i) = fillSphericalTriangle(sphere, germ, v1, v2); end if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawSphericalPolygon.m0000644000000000000000000000013214576357161020715 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawSphericalPolygon.m0000644000175000017500000000547114576357161022504 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawSphericalPolygon(varargin) %DRAWSPHERICALPOLYGON Draw a spherical polygon. % % output = drawSphericalPolygon(input) % % Example % % Draw a non convex spherical polygon on the surface of a sphere % sphere = [0 0 0 1]; % poly = [0 -1 0;0 0 1; [-1 0 1]/sqrt(2); [-1 -1 1]/sqrt(3); [-1 -1 0]/sqrt(2)]; % figure; hold on; axis equal; drawSphere([0 0 0 1]); view(3); % drawSphericalPolygon(sphere, poly, 'LineWidth', 2, 'color', 'b') % % See also % drawSphere, drawSphericalTriangle, drawSphericalEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); sphere = varargin{1}; poly = varargin{2}; varargin(1:2) = []; nv = size(poly, 1); h = zeros(nv, 1); % save hold state holdState = ishold(hAx); hold(hAx, 'on'); for i = 1:nv v1 = poly(i, :); v2 = poly(mod(i, nv) + 1, :); h(i) = drawSphericalEdge(hAx, sphere, [v1 v2], varargin{:}); end % restore hold state if ~holdState hold(hAx, 'off'); end if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/clipPoints3d.m0000644000000000000000000000013214576357161017130 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/clipPoints3d.m0000644000175000017500000000776514576357161020727 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = clipPoints3d(points, shape, varargin) %CLIPPOINTS3D Clip a set of points by a box or other 3d shapes. % % CLIP = clipPoints3d(POINTS, BOX); % Returns the set of points which are located inside of the box BOX. % % [CLIP, IND] = clipPoints3d(POINTS, BOX); % Also returns the indices of clipped points. % % ... = clipPoints3d(..., 'shape', 'sphere') Specify the shape. % Default is 'box'. But it is also possible to use 'sphere' or 'plane'. % % ... = clipPoints3d(..., 'inside', false) returns the set of % points outside the shape instead of inside. % % See also % points3d, boxes3d, spheres % % ------ % Author: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA Nantes - MIAJ Jouy-en-Josas parser = inputParser; validStrings = {'box', 'sphere', 'plane'}; addParameter(parser, 'shape', 'box', @(x) any(validatestring(x, validStrings))); addParameter(parser, 'inside', true, @islogical); parse(parser,varargin{:}); switch parser.Results.shape case 'box' LI = clipPointsByBox(points, shape); case 'plane' LI = clipPointsByPlane(points, shape); case 'sphere' LI = clipPointsBySphere(points, shape); end if parser.Results.inside % keep points inside the shape ind = find(LI); else % keep points outside the shape ind = find(~LI); end points = points(ind, :); % process output arguments varargout{1} = points; if nargout == 2 varargout{2} = ind; end function LI = clipPointsByBox(points, box) % get bounding box limits xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); zmin = box(5); zmax = box(6); % compute indices of points inside visible area xOk = points(:,1) >= xmin & points(:,1) <= xmax; yOk = points(:,2) >= ymin & points(:,2) <= ymax; zOk = points(:,3) >= zmin & points(:,3) <= zmax; LI = xOk & yOk & zOk; end function LI = clipPointsByPlane(points, plane) % points inside and on the surface of the sphere LI = isBelowPlane(points, plane); end function LI = clipPointsBySphere(points, sphere) % points inside and on the surface of the sphere LI = distancePoints3d(points, sphere(1:3)) <= sphere(4); end end matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectThreePlanes.m0000644000000000000000000000013214576357161020710 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectThreePlanes.m0000644000175000017500000000615014576357161022472 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = intersectThreePlanes(plane1, plane2, plane3) %INTERSECTTHREEPLANES Return intersection point between 3 planes in space. % % LINE = intersectThreePlanes(PLANE1, PLANE2, PLANE3) % Returns the point or straight line belonging to three planes. % PLANE: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % POINT: [x0 y0 z0] % IF rank of the coefficient matrix r1 = 3 and % Rank of the augmented matrix r2 = 3 return point % Otherwise returns point with NaN values. % % See also % planes3d, intersectPlanes, intersectLinePlane % ------ % Author: Roozbeh Geraili Mikola % E-mail: roozbehg@berkeley.edu or roozbehg@live.com % Created: 2017-09-20 % Copyright 2017-2023 % plane normal n1 = normalizeVector3d(cross(plane1(:,4:6), plane1(:, 7:9), 2)); n2 = normalizeVector3d(cross(plane2(:,4:6), plane2(:, 7:9), 2)); n3 = normalizeVector3d(cross(plane3(:,4:6), plane3(:, 7:9), 2)); % Uses Hessian form, ie : N.p = d % I this case, d can be found as : -N.p0, when N is normalized d1 = dot(n1, plane1(:,1:3), 2); d2 = dot(n2, plane2(:,1:3), 2); d3 = dot(n3, plane3(:,1:3), 2); % create coefficient and augmented matrices A = [n1;n2;n3]; D = [d1;d2;d3]; AD = [n1,d1;n2,d2;n3,d3]; % calculate rank of the coefficient and augmented matrices r1 = rank(A); r2 = rank(AD); % if rank of the coefficient matrix r1 = 3 and % rank of the augmented matrix r2 = 3 return point % and if r1 = 2 and r2 = 2 return line, % otherwise returns point with NaN values. if r1 == 3 && r2 == 3 % Intersecting at a point point = (A\D)'; else point = [NaN NaN NaN]; end matgeom-1.2.4/inst/geom3d/PaxHeaders/crossProduct3d.m0000644000000000000000000000013214576357161017476 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/crossProduct3d.m0000644000175000017500000000527414576357161021266 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function c = crossProduct3d(a,b) %CROSSPRODUCT3D Vector cross product faster than inbuilt MATLAB cross. % % C = crossProduct3d(A, B) % returns the cross product of the two 3D vectors A and B, that is: % C = A x B % A and B must be N-by-3 element vectors. If either A or B is a 1-by-3 % row vector, the result C will have the size of the other input and will % be the concatenation of each row's cross product. % % Example % v1 = [2 0 0]; % v2 = [0 3 0]; % crossProduct3d(v1, v2) % ans = % 0 0 6 % % See also % vectorAngle3d % ------ % Author: Sven Holcombe % E-mail: N/A % Created: 2011 % Copyright 2011-2023 % size of inputs sizeA = size(a); sizeB = size(b); % Initialise c to the size of a or b, whichever has more dimensions. If % they have the same dimensions, initialise to the larger of the two switch sign(numel(sizeA) - numel(sizeB)) case 1 c = zeros(sizeA); case -1 c = zeros(sizeB); otherwise c = zeros(max(sizeA, sizeB)); end c(:) = bsxfun(@times, a(:,[2 3 1],:), b(:,[3 1 2],:)) - ... bsxfun(@times, b(:,[2 3 1],:), a(:,[3 1 2],:)); matgeom-1.2.4/inst/geom3d/PaxHeaders/transformPolygon3d.m0000644000000000000000000000013214576357161020367 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/transformPolygon3d.m0000644000175000017500000000717214576357161022156 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function tfmPoly = transformPolygon3d(poly, tfm) %TRANSFORMPOINT3D Transform a polygon with a 3D affine transform. % % TFMPOLY = transformPoint3d(POLY, TFM); % returns the polygon TFMPOLY by transforming POLY according to the % affine transform specified by TFM. POLY can be either 2D or 3D. If POLY % is 2D, zeros are added as third dimension, before the transformation is % performed. % % Example % center=-100+200*rand(1,3); % phi=randi([-180,180]); theta=randi([-180,180]); psi=randi([-180,180]); % tfm=eulerAnglesToRotation3d(phi, theta, psi, 'ZYZ'); tfm(1:3,4)=center'; % r = [2.5, 2, 1]; % poly = flipud(circleToPolygon([0 0 r(1)], round(2*pi*r(1)))); % midCircle = circleToPolygon([0 0 r(2)], round(2*pi*r(2))); % innerCircle = flipud(circleToPolygon([0 0 r(3)], round(2*pi*r(3)))); % poly = {poly, midCircle, innerCircle}; % tfmPoly = transformPolygon3d(poly, tfm); % figure('color','w'); axis equal; view(3) % drawPolygon3d(tfmPoly, 'r') % % See also % transforms3d, transformPoint3d, createTranslation3d % createRotationOx, createRotationOy, createRotationOz, createScaling % % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-01-05, using MATLAB 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 if isnumeric(poly) c = size(poly,2); if c < 2 || c > 3 error(['The polygon has ' num2str(c) ' columns. A polygon must have either 2 or 3 columns!']) end tfmPoly = transformPoint3d(twoD2threeD(poly), tfm); elseif iscell(poly) c = cellfun(@(x) size(x,2), poly); if all(c == 2) || all(c == 3) poly = cellfun(@twoD2threeD, poly, 'uni', 0); tfmPoly = cellfun(@(x) transformPoint3d(x, tfm), poly, 'uni', 0); else error(['The polygon has ' num2str(c) ' columns. A polygon must have either 2 or 3 columns!']) end elseif isa(poly, 'polyshape') error('Polyshape format cannot be used for 3D polygons!') else error('Unknown polygon format!') end end function pts = twoD2threeD(pts) if size(pts,2) == 2 pts(:,3)=0; pts(isnan(pts(:,1)),3)=nan; end end matgeom-1.2.4/inst/geom3d/PaxHeaders/isPlane.m0000644000000000000000000000013214576357161016150 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/isPlane.m0000644000175000017500000000432414576357161017733 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function d = isPlane(plane) %ISPLANE Check if input is a plane. % % B = isPlane(PLANE) where PLANE should be a plane or multiple planes % % Example % isPlane([... % 0 0 0 1 0 0 0 1 0;... % 0 0 0 1 0 0 -1 0 0;... % 0 0 0 1i 0 0 -1 0 0;... % 0 0 0 nan 0 0 0 1 0;... % 0 0 0 inf 0 0 0 1 0]) % % See also % createPlane3d % ------ % Author: oqilipo % E-mail: N/A % Created: 2017-07-09 % Copyright 2017-2023 narginchk(1,1) if size(plane,2)~=9 d=false(size(plane,1),1); return end a = ~any(isnan(plane),2); b = ~any(isinf(plane),2); c = ~isParallel3d(plane(:,4:6), plane(:,7:9)); d = a & b & c; end matgeom-1.2.4/inst/geom3d/PaxHeaders/equivalentEllipsoid.m0000644000000000000000000000013214576357161020577 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/equivalentEllipsoid.m0000644000175000017500000000713314576357161022363 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ell = equivalentEllipsoid(points) %EQUIVALENTELLIPSOID Equivalent ellipsoid of a set of 3D points. % % ELL = equivalentEllipsoid(PTS) % Compute the equivalent ellipsoid of the set of points PTS. The result % is an ellipsoid defined by: % ELL = [XC YC ZC A B C PHI THETA PSI] % where [XC YC ZY] is the center, [A B C] are the lengths of the % semi-axes (in decreasing order), and [PHI THETA PSI] are Euler angles % representing the ellipsoid orientation, in degrees. % % Example % pts = randn(300, 3); % pts = transformPoint3d(pts, createScaling3d([6 4 2])); % pts = transformPoint3d(pts, createRotationOx(pi/6)); % pts = transformPoint3d(pts, createRotationOy(pi/4)); % pts = transformPoint3d(pts, createRotationOz(pi/3)); % pts = transformPoint3d(pts, createTranslation3d([5 4 3])); % elli = equivalentEllipsoid(pts); % figure; drawPoint3d(pts); axis equal; % hold on; drawEllipsoid(elli, ... % 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); % % See also % spheres, drawEllipsoid, equivalentEllipse, principalAxes % principalAxesTransform, rotation3dToEulerAngles % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % number of points n = size(points, 1); % compute centroid center = mean(points); % compute the covariance matrix covPts = cov(points)/n; % perform a principal component analysis with 3 variables, % to extract equivalent axes [U, S] = svd(covPts); % extract length of each semi axis radii = sqrt(5) * sqrt(diag(S)*n)'; % sort axes from greater to lower [radii, ind] = sort(radii, 'descend'); % format U to ensure first axis points to positive x direction U = U(ind, :); if U(1,1) < 0 U = -U; % keep matrix determinant positive U(:,3) = -U(:,3); end % convert axes rotation matrix to Euler angles angles = rotation3dToEulerAngles(U); % concatenate result to form an ellipsoid object ell = [center, radii, angles]; matgeom-1.2.4/inst/geom3d/PaxHeaders/vectorNorm3d.m0000644000000000000000000000013214576357161017142 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/vectorNorm3d.m0000644000175000017500000000423514576357161020726 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function n = vectorNorm3d(v) %VECTORNORM3D Norm of a 3D vector or of set of 3D vectors. % % N = vectorNorm3d(V); % Returns the norm of vector V. % % When V is a N-by-3 array, compute norm for each vector of the array. % Vectors are given as rows. Result is then a N-by-1 array. % % NOTE: Computes only the Euclidean norm. % % See also % vectors3d, normalizeVector3d, vectorAngle3d, hypot3 % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE n = sqrt(sum(v.*v, ndims(v))); matgeom-1.2.4/inst/geom3d/PaxHeaders/boundingBox3d.m0000644000000000000000000000013214576357161017262 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/boundingBox3d.m0000644000175000017500000000573314576357161021052 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = boundingBox3d(points) %BOUNDINGBOX3D Bounding box of a set of 3D points. % % BOX = boundingBox3d(POINTS) % Returns the bounding box of the set of points POINTS. POINTS is a % N-by-3 array containing points coordinates. The result BOX is a 1-by-6 % array, containing: % [XMIN XMAX YMIN YMAX ZMIN ZMAX] % % Example % % Draw bounding box of a cubeoctehedron % [v e f] = createCubeOctahedron; % box3d = boundingBox3d(v); % figure; hold on; % drawMesh(v, f); % drawBox3d(box3d); % set(gcf, 'renderer', 'opengl') % axis([-2 2 -2 2 -2 2]); % view(3) % % See also % boxes3d, drawBox3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-04-01, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % Parse input if isstruct(points) if isfield(points, 'vertices') points = points.vertices; else error(['If a struct is passed to boundingBox3d, it must have ' ... 'the field ''vertices''!']) end end % compute extreme x and y values xmin = min(points(:,1)); xmax = max(points(:,1)); ymin = min(points(:,2)); ymax = max(points(:,2)); box = [xmin xmax ymin ymax]; % process case of 3D points if size(points, 2) > 2 zmin = min(points(:,3)); zmax = max(points(:,3)); box = [xmin xmax ymin ymax zmin zmax]; end matgeom-1.2.4/inst/geom3d/PaxHeaders/lines3d.m0000644000000000000000000000013214576357161016116 xustar0030 mtime=1710874225.098193384 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/lines3d.m0000644000175000017500000000442214576357161017700 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function lines3d(varargin) %LINES3D Description of functions operating on 3D lines. % % A 3D Line is represented by a 1-by-6 row vector containing a 3D point % (its origin) and a 3D vector (its direction): % LINE = [X0 Y0 Z0 DX DY DZ]; % % See also % createLine3d, distancePointLine3d, isPointOnLine3d, linePosition3d % intersectLinePlane, distanceLines3d, parallelLine3d, projPointOnLine3d % clipLine3d, fitLine3d, drawLine3d, transformLine3d % edgeToLine3d, lineToEdge3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('lines3d'); matgeom-1.2.4/inst/geom3d/PaxHeaders/drawSphere.m0000644000000000000000000000013214576357161016661 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.098193384 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawSphere.m0000644000175000017500000001371514576357161020450 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawSphere(varargin) %DRAWSPHERE Draw a sphere as a mesh. % % drawSphere(SPHERE) % Where SPHERE = [XC YC ZC R], draw the sphere centered on the point with % coordinates [XC YC ZC] and with radius R, using a quad mesh. % % drawSphere(CENTER, R) % Where CENTER = [XC YC ZC], specifies the center and the radius with two % arguments. % % drawSphere(XC, YC, ZC, R) % Specifiy sphere center and radius as four arguments. % % drawSphere(..., NAME, VALUE); % Specifies one or several options using parameter name-value pairs. % Available options are usual drawing options, as well as: % 'nPhi' the number of arcs used for drawing the meridians % 'nTheta' the number of circles used for drawing the parallels % % H = drawSphere(...) % Return a handle to the graphical object created by the function. % % [X Y Z] = drawSphere(...) % Return the coordinates of the vertices used by the sphere. In this % case, the sphere is not drawn. % % Example % % Draw four spheres with different centers % figure(1); clf; hold on; % drawSphere([10 10 30 5]); % drawSphere([20 30 10 5]); % drawSphere([30 30 30 5]); % drawSphere([30 20 10 5]); % view([-30 20]); axis equal; l = light; % % % Draw sphere with different settings % figure(1); clf; % drawSphere([10 20 30 10], 'linestyle', ':', 'facecolor', 'r'); % axis([0 50 0 50 0 50]); axis equal; % l = light; % % % The same, but changes style using graphic handle % figure(1); clf; % h = drawSphere([10 20 30 10]); % set(h, 'linestyle', ':'); % set(h, 'facecolor', 'r'); % axis([0 50 0 50 0 50]); axis equal; % l = light; % % % Draw a sphere with high resolution % figure(1); clf; % h = drawSphere([10 20 30 10], 'nPhi', 360, 'nTheta', 180); % l = light; view(3); % % % See also % spheres, circles3d, sphere, drawEllipsoid % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % process input options: when a string is found, assumes this is the % beginning of options options = {'FaceColor', 'g', 'LineStyle', 'none'}; for i = 1:length(varargin) if ischar(varargin{i}) if length(varargin) == 1 options = {'FaceColor', varargin{1}, 'LineStyle', 'none'}; else options = [options(1:end) varargin(i:end)]; end varargin = varargin(1:i-1); break; end end % Parse the input (try to extract center coordinates and radius) if isempty(varargin) % no input: assumes unit sphere xc = 0; yc = 0; zc = 0; r = 1; elseif length(varargin) == 1 % one argument: concatenates center and radius sphere = varargin{1}; xc = sphere(:,1); yc = sphere(:,2); zc = sphere(:,3); r = sphere(:,4); elseif length(varargin) == 2 % two arguments, corresponding to center and radius center = varargin{1}; xc = center(1); yc = center(2); zc = center(3); r = varargin{2}; elseif length(varargin) == 4 % four arguments, corresponding to XC, YX, ZC and R xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; r = varargin{4}; else error('drawSphere: please specify center and radius'); end % number of meridians nPhi = 32; ind = find(strcmpi('nPhi', options(1:2:end))); if ~isempty(ind) ind = ind(1); nPhi = options{2*ind}; options(2*ind-1:2*ind) = []; end % number of parallels nTheta = 16; ind = find(strcmpi('nTheta', options(1:2:end))); if ~isempty(ind) ind = ind(1); nTheta = options{2*ind}; options(2*ind-1:2*ind) = []; end % compute spherical coordinates theta = linspace(0, pi, nTheta+1); phi = linspace(0, 2*pi, nPhi+1); % convert to cartesian coordinates sintheta = sin(theta); x = xc + cos(phi')*sintheta*r; y = yc + sin(phi')*sintheta*r; z = zc + ones(length(phi),1)*cos(theta)*r; % Process output if nargout == 0 % no output: draw the sphere surf(hAx, x, y, z, options{:}); elseif nargout == 1 % one output: compute varargout{1} = surf(hAx, x, y, z, options{:}); elseif nargout == 3 varargout{1} = x; varargout{2} = y; varargout{3} = z; end matgeom-1.2.4/inst/geom3d/PaxHeaders/createBasisTransform3d.m0000644000000000000000000000013214576357161021125 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createBasisTransform3d.m0000644000175000017500000001173614576357161022715 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function transfo = createBasisTransform3d(source, target) %CREATEBASISTRANSFORM3D Compute matrix for transforming a basis into another basis. % % TRANSFO = createBasisTransform3d(SOURCE, TARGET) will create a 4-by-4 % transformation matrix representing the transformation from SOURCE basis % to TARGET basis. % SOURCE and TARGET are either standard 1-by-9 geom3d PLANE % representations of the form: [x0 y0 z0 ex1 ey1 ez1 ex2 ey2 ez2] % OR % SOURCE and TARGET may be any string such as 'global' or 'g' in which % case they represent the global plane [0 0 0 1 0 0 0 1 0]. % % The resulting TRANSFO matrix is such that a point expressed with % coordinates of the first basis will be represented by new coordinates % P2 = transformPoint3d(P1, TRANSFO) in the target basis. % % Either (or both) SOURCE or TARGET may be an N-by-9 set of N planes. In % that case, TRANSFO will be a 4-by-4-by-N array of N transformation % matrices. % % Example: % % Calculate local plane coords. of a point given in global coords. % plane = [10 10 10 1 0 0 0 1 0]; % transfo = createBasisTransform3d('global', plane); % PT_IN_PLANE = transformPoint3d([3 8 2], transfo) % PT_IN_PLANE = % 13 18 12 % % See also % transforms3d, transformPoint3d, planePosition, createBasisTransform % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-12-03, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % size of input arguments srcSz = size(source, 1); tgtSz = size(target, 1); maxSz = max(srcSz, tgtSz); % check case of multiple inputs if maxSz > 1 [t1, t2] = deal( bsxfun(@times, eye(4), ones(1,1,maxSz)) ); if srcSz > 1 source = permute(source, [3 2 1]); end if tgtSz > 1 target = permute(target, [3 2 1]); end else [t1, t2] = deal(eye(4)); end % Place source and target planes into t1 and t2 t-form matrices. If either % input is non-numeric it is assumed to mean 'global', or identity t-form. if isnumeric(source) if maxSz > 1 && srcSz == 1 source = bsxfun(@times, source, ones(1,1,maxSz)); end t1(1:3, 1, :) = source(1, 4:6, :); t1(1:3, 2, :) = source(1, 7:9, :); t1(1:3, 3, :) = crossProduct3d(source(1,4:6,:), source(1,7:9,:)); t1(1:3, 4, :) = source(1, 1:3, :); end if isnumeric(target) if maxSz > 1 && tgtSz == 1 target = bsxfun(@times, target, ones(1,1,maxSz)); end t2(1:3, 1, :) = target(1, 4:6, :); t2(1:3, 2, :) = target(1, 7:9, :); t2(1:3, 3, :) = crossProduct3d(target(1,4:6,:), target(1,7:9,:)); t2(1:3, 4, :) = target(1, 1:3, :); end % compute transform matrix transfo = zeros(4, 4, maxSz); for i = 1:maxSz % coordinate of four reference points in source basis po = t1(1:3, 4, i)'; px = po + t1(1:3, 1, i)'; py = po + t1(1:3, 2, i)'; pz = po + t1(1:3, 3, i)'; % express coordinates of reference points in the new basis t2i = inv(t2(:,:,i)); pot = transformPoint3d(po, t2i); pxt = transformPoint3d(px, t2i); pyt = transformPoint3d(py, t2i); pzt = transformPoint3d(pz, t2i); % compute direction vectors in new basis vx = pxt - pot; vy = pyt - pot; vz = pzt - pot; % concatenate result in a 4-by-4 affine transform matrix transfo(:,:,i) = [vx' vy' vz' pot' ; 0 0 0 1]; end matgeom-1.2.4/inst/geom3d/PaxHeaders/parallelPlane.m0000644000000000000000000000013214576357161017331 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/parallelPlane.m0000644000175000017500000000573514576357161021123 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = parallelPlane(plane, point) %PARALLELPLANE Parallel to a plane through a point or at a given distance. % % PL2 = parallelPlane(PL, PT) % Constructs the plane parallel to plane PL and containing the point PT. % % PL2 = parallelPlane(PL, D) % Constructs the plane parallel to plane PL, and located at the given % signed distance D. % % Example % % Create a plane normal to the 3D vector DIR % dir = [3 4 5]; % plane = createPlane([3 4 5], dir); % % Create plane at a specific distance % plane2 = parallelPlane(plane, 5); % % Create a line perpendicular to both planes % line = [2 4 1 3 4 5]; % pi1 = intersectLinePlane(line, plane); % pi2 = intersectLinePlane(line, plane2); % % check the distance between intersection points % distancePoints3d(pi1, pi2) % ans = % 5 % % See also % geom3d, parallelLine3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-08-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform if size(point, 2) == 1 % use a distance. Compute position of point located at distance DIST on % the line normal to the plane. normal = normalizeVector3d(planeNormal(plane)); point = plane(:, 1:3) + bsxfun(@times, point, normal); end % change origin, and keep direction vectors res = [point plane(:, 4:9)]; matgeom-1.2.4/inst/geom3d/PaxHeaders/edges3d.m0000644000000000000000000000013214576357161016073 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/edges3d.m0000644000175000017500000000434114576357161017655 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges3d(varargin) %EDGES3D Description of functions operating on 3D edges. % % A 3D edge is represented by the coordinates of its extremities: % EDGE = [X1 Y1 Z1 X2 Y2 Z2]; % % A set of 3D edges is represented by a N-by-6 array, each row % representing an edge. % % See also % lines3d, edges2d, createEdge3d, edgeLength3d % intersectEdgePlane, edgeToLine3d, edgeToLine3d, clipEdge3d, midPoint3d % distancePointEdge3d, drawEdge3d, drawSphericalEdge % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-04-12, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018-2023 INRA - Cepia Software Platform help('edges3d'); matgeom-1.2.4/inst/geom3d/PaxHeaders/circle3dPosition.m0000644000000000000000000000013214576357161017772 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/circle3dPosition.m0000644000175000017500000000562014576357161021555 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = circle3dPosition(point, circle) %CIRCLE3DPOSITION Return the angular position of a point on a 3D circle. % % POS = circle3dPosition(POINT, CIRCLE) % Returns angular position of point on the circle, in degrees, between 0 % and 360. % with POINT: [xp yp zp] % and CIRCLE: [X0 Y0 Z0 R THETA PHI] or [X0 Y0 Z0 R THETA PHI PSI] % (THETA being the colatitude, and PHI the azimut) % % See also % circles3d, circle3dOrigin, circle3dPoint % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % get center and radius xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); % get angle of normal theta = circle(:,5); phi = circle(:,6); % find origin of the circle ori = circle3dOrigin(circle); % normal vector of the supporting plane (cartesian coords) vn = sph2cart2d([theta phi]); % create plane containing the circle plane = createPlane([xc yc zc], vn); % find position of point on the circle plane pp0 = planePosition(ori, plane); pp = planePosition(point, plane); % compute angles in the planes theta0 = mod(atan2(pp0(:,2), pp0(:,1)) + 2*pi, 2*pi); theta = mod(atan2(pp(:,2), pp(:,1)) + 2*pi - theta0, 2*pi); % convert to degrees theta = theta * 180 / pi; matgeom-1.2.4/inst/geom3d/PaxHeaders/isCoplanar.m0000644000000000000000000000013214576357161016650 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/isCoplanar.m0000644000175000017500000000673014576357161020436 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function copl = isCoplanar(x,y,z,tol) %ISCOPLANAR Tests input points for coplanarity in 3-space. % % COPL = isCoplanar(PTS) % Tests the coplanarity of the input points in array PTS. Input array must % be 4-by-3, each row containing coordinate of one point. % % COPL = isCoplanar(PTS, TOLERANCE) % Specifies the tolerance value used for checking coplanarity. Default is % zero. % % % Example: % iscoplanar([1 2 -2; -3 1 -14; -1 2 -6; 1 -2 -8], eps) % % Source: % https://fr.mathworks.com/matlabcentral/fileexchange/46-iscoplanar-m % ------ % Author: Brett Shoelson, David Legland % E-mail: brett.shoelson@joslin.harvard.edu, david.legland@inrae.fr % Created: 2001-10-06 % Copyright 2001-2023 if nargin == 0 error('Requires at least one input argument.'); elseif nargin == 1 if size(x,2) == 3 % Matrix of all x,y,z is input pts = x; tol = 0; else error('Invalid input.') end elseif nargin == 2 if size(x,2) == 3 % Matrix of all x,y,z is input pts = x; tol = y; else error('Invalid input.') end elseif nargin == 3 % Compile a matrix of all x,y,z pts = [x y z]; tol = 0; else pts = [x y z]; end if size(x, 1) < 4 error('Requires at least four points to compute coplanarity'); end % replace first point at the origin and compute SVD of the matrix sv = svd(bsxfun(@minus, pts(2:end,:), pts(1,:))); copl = sv(3) <= tol * sv(1); % % Alterantive version that computes the rank of the matrix % rnk = rank(bsxfun(@minus, pts(2:end,:), pts(1,:)), tol); % copl = rnk <= size(pts, 2) - 1; % % Old version: % %Compare all 4-tuples of point combinations; {P1:P4} are coplanar iff % %det([x1 y1 z1 1;x2 y2 z2 1;x3 y3 z3 1;x4 y4 z4 1])==0 % tmp = nchoosek(1:size(pts,1),4); % for ii = 1:size(tmp,1) % copl = abs(det([pts(tmp(ii, :), :) ones(4,1)])) <= tolerance; % if ~copl % break % end % end matgeom-1.2.4/inst/geom3d/PaxHeaders/projPointOnCircle3d.m0000644000000000000000000000013214576357161020407 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/projPointOnCircle3d.m0000644000175000017500000000630414576357161022172 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point2 = projPointOnCircle3d(point, circle) %PROJPOINTONCIRCLE3D Project a 3D point onto a 3D circle. % % PT2 = projPointOnCircle3d(PT, CIRCLE). % Computes the projection of 3D point PT onto the 3D circle CIRCLE. % % Point PT is a N-by-3 array, and CIRCLE is a 1-by-7 array. % Result PT2 is a N-by-3 array, containing coordinates of projections of % PT onto the circle CIRCLE. % % See also % projPointOnLine3d, projPointOnPlane % % Source % https://www.geometrictools.com/Documentation/DistanceToCircle3.pdf % ------ % Author: oqilipo % E-mail: N/A % Created: 2020-10-12 % Copyright 2020-2023 center = circle(1:3); radius = circle(4); % Compute transformation from local basis to world basis TFM = localToGlobal3d(center, circle(5), circle(6), circle(7)); % Create circle plane circlePlaneNormal = transformVector3d([0 0 1], TFM); circlePlane = createPlane(center, circlePlaneNormal); % Project point on circle plane PTonCP = projPointOnPlane(point, circlePlane); % Calculate vector from the projected point to the center of the circle PTtoCenter = normalizeVector3d(circle(1:3) - PTonCP); % Calculate final point point2 = PTonCP + PTtoCenter.*(distancePoints3d(PTonCP, center) - radius); % Take an arbitrary point of the circle if the point is the center of the circle if any(all(isnan(point2),2)) point2(all(isnan(point2),2),:) = center + normalizeVector3d(circlePlane(4:6))*radius; end % Take an arbitrary point of the circle if the point lies on the normal of the circle plane if any(sum(PTtoCenter == 0,2) == 2) point2(sum(PTtoCenter == 0,2) == 2,:) = center + normalizeVector3d(circlePlane(4:6))*radius; end end matgeom-1.2.4/inst/geom3d/PaxHeaders/planeNormal.m0000644000000000000000000000013214576357161017025 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/planeNormal.m0000644000175000017500000000416014576357161020606 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function n = planeNormal(plane) %PLANENORMAL Compute the normal to a plane. % % N = planeNormal(PLANE) % compute the normal of the given plane % PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % N : [dx dy dz] % % See also % geom3d, planes3d, createPlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % plane normal outSz = size(plane); outSz(2) = 3; n = zeros(outSz); n(:) = crossProduct3d(plane(:,4:6,:), plane(:, 7:9,:)); matgeom-1.2.4/inst/geom3d/PaxHeaders/fitPlane.m0000644000000000000000000000013214576357161016317 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/fitPlane.m0000644000175000017500000000611414576357161020101 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function plane = fitPlane(points) %FITPLANE Fit a 3D plane to a set of points. % % PLANE = fitPlane(POINTS) % % Example % pts = randn(300, 3); % pts = transformPoint3d(pts, createScaling3d([6 4 2])); % pts = transformPoint3d(pts, createRotationOx(pi/6)); % pts = transformPoint3d(pts, createRotationOy(pi/4)); % pts = transformPoint3d(pts, createRotationOz(pi/3)); % pts = transformPoint3d(pts, createTranslation3d([5 4 3])); % elli = equivalentEllipsoid(pts); % figure; drawPoint3d(pts); axis equal; % hold on; drawEllipsoid(elli, ... % 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); % plane = fitPlane(pts); % drawPlane3d(plane, 'm'); % % See also % planes3d, equivalentEllipsoid, fitLine3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-11-11, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % number of points n = size(points, 1); % compute centroid center = mean(points); % compute the covariance matrix covPts = cov(points)/n; % perform a principal component analysis with 2 variables, % to extract inertia axes [U, S] = svd(covPts); % sort axes from greater to lower [dummy, ind] = sort(diag(S), 'descend'); %#ok % format U to ensure first axis points to positive x direction U = U(ind, :); if U(1,1) < 0 U = -U; % keep matrix determinant positive U(:,3) = -U(:,3); end plane = [center U(:,1)' U(:,2)']; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawCube.m0000644000000000000000000000013214576357161016311 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawCube.m0000644000175000017500000001051314576357161020071 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCube(varargin) %DRAWCUBE Draw a 3D centered cube, eventually rotated. % % drawCube(CUBE) % Displays a 3D cube on current axis. CUBE is given by: % [XC YC ZC SIDE THETA PHI PSI] % where (XC, YC, ZC) is the CUBE center, SIDE is the length of the cube % main sides, and THETA PHI PSI are angles representing the cube % orientation, in degrees. THETA is the colatitude of the cube, between 0 % and 90 degrees, PHI is the azimut, and PSI is the rotation angle % around the axis of the normal. % % CUBE can be axis aligned, in this case it should only contain center % and side information: % CUBE = [XC YC ZC SIDE] % % The function drawCuboid is closely related, but uses a different angle % convention, and allows for different sizes along directions. % % Example % % Draw a cube with small rotations % figure; hold on; % drawCube([10 20 30 50 10 20 30], 'FaceColor', 'g'); % axis equal; % view(3); % % See also % meshes3d, polyhedra, createCube, drawCuboid % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); cube = varargin{1}; varargin(1) = []; % default values xc = 0; yc = 0; zc = 0; a = 1; theta = 0; phi = 0; psi = 0; %% Parses the input if nargin > 0 % one argument: parses elements xc = cube(:,1); yc = cube(:,2); zc = cube(:,3); % parses side length if present if size(cube, 2) >= 4 a = cube(:,4); end % parses orientation if present if size(cube, 2) >= 6 theta = deg2rad(cube(:,5)); phi = deg2rad(cube(:,6)); end if size(cube, 2) >= 7 psi = deg2rad(cube(:,7)); end end %% Compute cube coordinates % create unit centered cube [v, f] = createCube; v = bsxfun(@minus, v, mean(v, 1)); % convert unit basis to cube basis sca = createScaling3d(a); rot1 = createRotationOz(psi); rot2 = createRotationOy(theta); rot3 = createRotationOz(phi); tra = createTranslation3d([xc yc zc]); % concatenate transforms trans = tra * rot3 * rot2 * rot1 * sca; % transform mesh vertices v = transformPoint3d(v, trans); %% Process output if nargout == 0 % no output: draw the cube drawMesh(hAx, v, f, varargin{:}); elseif nargout == 1 % one output: draw the cube and return handle varargout{1} = drawMesh(hAx, v, f, varargin{:}); elseif nargout == 3 % 3 outputs: return computed coordinates varargout{1} = v(:,1); varargout{2} = v(:,2); varargout{3} = v(:,3); end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawSphericalEdge.m0000644000000000000000000000013214576357161020132 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawSphericalEdge.m0000644000175000017500000000747514576357161021727 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawSphericalEdge(varargin) %DRAWSPHERICALEDGE Draw an edge on the surface of a sphere. % % drawSphericalEdge(SPHERE, EDGE) % EDGE is given as a couple of 3D coordinates corresponding to edge % extremities. The shortest spherical edge joining the two extremities is % drawn on the current axes. % % drawSphericalEdge(AX, ...) % Specifies the handle of the axis to use for drawing. % % % Example % figure; hold on; axis equal; drawSphere([0 0 0 1]); view(3); % p1 = [0 -1 0]; p2 = [0 0 1]; % drawSphericalEdge([0 0 0 1], [p1 p2], 'LineWidth', 2) % % See also % drawSphericalPolygon, drawSphere, drawCircleArc3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); sphere = varargin{1}; edge = varargin{2}; varargin(1:2) = []; % extract data of the sphere origin = sphere(:, 1:3); % allocate array of handles nEdges = size(edge, 1); he = gobjects(1, nEdges); % save hold state holdState = ishold(hAx); hold(hAx, 'on'); % iterate over edges for iEdge = 1:nEdges % extremities of current edge point1 = edge(iEdge, 1:3); point2 = edge(iEdge, 4:6); % compute plane containing current edge plane = createPlane(origin, point1, point2); % intersection of the plane with unit sphere circle = intersectPlaneSphere(plane, sphere); % find the position (in degrees) of the 2 vertices on the circle angle1 = circle3dPosition(point1, circle); angle2 = circle3dPosition(point2, circle); % ensure angles are in right direction if mod(angle2 - angle1 + 360, 360) > 180 tmp = angle1; angle1 = angle2; angle2 = tmp; end % compute angle extent of the circle arc angleExtent = mod(angle2 - angle1 + 360, 360); % create circle arc arc = [circle angle1 angleExtent]; % draw the arc he(iEdge) = drawCircleArc3d(hAx, arc, varargin{:}); end % restore hold state if ~holdState hold(hAx, 'off'); end if nargout > 0 varargout = {he}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawLabels3d.m0000644000000000000000000000013214576357161017064 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawLabels3d.m0000644000175000017500000000765214576357161020656 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawLabels3d(varargin) %DRAWLABELS3D Draw text labels at specified 3D positions. % % drawLabels3d(X, Y, Z, LBL) draw labels LBL at position X and Y. % LBL can be either a string array, or a number array. In this case, % string are created by using sprintf function, with '%.2f' mask. % % drawLabels3d(POS, LBL) draw labels LBL at position specified by POS, % where POS is a N-by-3 int array. % % drawLabels3d(..., NUMBERS, FORMAT) create labels using sprintf function, % with the mask given by FORMAT (e. g. '%03d' or '5.3f'), and the % corresponding values. % % See also % drawLabels % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-31 % Copyright 2019-2023 INRA - TPV URPOI - BIA IMASTE %% Parse input arguments % check if enough inputs are given if isempty(varargin) error('wrong number of arguments in drawLabels3d'); end % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % process input parameters var = varargin{1}; if size(var, 2) == 1 % coordinates given as separate arguments if length(varargin) < 4 error('wrong number of arguments in drawLabels'); end px = var; py = varargin{2}; pz = varargin{3}; lbl = varargin{4}; varargin(1:4) = []; else % parameters given as a packed array if length(varargin) < 2 error('wrong number of arguments in drawLabels'); end if size(var, 2) < 3 error('Requires coordinates array to have at least three columns'); end px = var(:,1); py = var(:,2); pz = var(:,3); lbl = varargin{2}; varargin(1:2) = []; end % parse format for displaying numeric values format = '%.2f'; if ~isempty(varargin) if varargin{1}(1) == '%' format = varargin{1}; varargin(1)=[]; end end if size(format, 1) == 1 && size(px, 1) > 1 format = repmat(format, size(px, 1), 1); end %% compute the strings that have to be displayed labels = cell(length(px), 1); if isnumeric(lbl) for i = 1:length(px) labels{i} = sprintf(format(i,:), lbl(i)); end elseif ischar(lbl) for i = 1:length(px) labels{i} = lbl(i,:); end elseif iscell(lbl) labels = lbl; end labels = char(labels); %% display the text h = text(hAx, px, py, pz, labels, varargin{:}); %% format output if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/polygonArea3d.m0000644000000000000000000000013214576357161017264 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/polygonArea3d.m0000644000175000017500000000727014576357161021052 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function area = polygonArea3d(poly, varargin) %POLYGONAREA3D Area of a 3D polygon. % % AREA = polygonArea3d(POLY) % POLY is given as a N-by-3 array of vertex coordinates. The resulting % area is positive. % Works also for polygons given as a cell array of polygons. % % Example % % area of a simple 3D square % poly = [10 30 20;20 30 20;20 40 20;10 40 20]; % polygonArea3d(poly) % ans = % 100 % % % Area of a 3D mesh % [v f] = createCubeOctahedron; % polygons = meshFacePolygons(v, f); % areas = polygonArea3d(polygons); % sum(areas) % ans = % 18.9282 % % See also % polygons3d, triangleArea3d, polygonArea, polygonCentroid3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-24, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % Check multiple polygons if iscell(poly) || sum(sum(isnan(poly))) > 0 % split the polygons into a cell array polygons = splitPolygons3d(poly); nPolys = length(polygons); % compute area of each polygon area = zeros(nPolys, 1); for i = 1:nPolys area(i) = polygonArea3d(polygons{i}); end return; end % put the first vertex at origin (reducing computation errors for polygons % far from origin) v0 = poly(1, :); poly = bsxfun(@minus, poly, v0); % indices of next vertices N = size(poly, 1); iNext = [2:N 1]; % compute cross-product of each elementary triangle formed by origin and % two consecutive vertices cp = cross(poly, poly(iNext,:), 2); % choose one of the triangles as reference for the normal direction vn = vectorNorm3d(cp); [tmp, ind] = max(vn); %#ok cpRef = cp(ind,:); % compute the sign of the area of each triangle % (need to compute the sign explicitely, as the norm of the cross product % does not keep orientation within supporting plane) sign_i = sign(dot(cp, repmat(cpRef, N, 1), 2)); % compute area of each triangle, using sign correction area_i = vectorNorm3d(cp) .* sign_i; % sum up individual triangles area area = sum(area_i) / 2; matgeom-1.2.4/inst/geom3d/PaxHeaders/createRotationVector3d.m0000644000000000000000000000013214576357161021152 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createRotationVector3d.m0000644000175000017500000000533314576357161022736 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ROT = createRotationVector3d(A,B) %CREATEROTATIONVECTOR3D Calculates the rotation between two vectors. % % ROT = createRotationVector3d(A, B) returns the 4x4 rotation matrix ROT % to transform vector A in the same direction as vector B. % % Example % A=[ .1 .2 .3]; % B=-1+2.*rand(1,3); % ROT = createRotationVector3d(A,B); % C = transformVector3d(A,ROT); % figure('color','w'); hold on; view(3) % O=[0 0 0]; % drawVector3d(O, A,'r'); % drawVector3d(O, B,'g'); % drawVector3d(O, C,'r'); % % See also % transformPoint3d, createRotationOx, createRotationOy, createRotationOz % % Source % https://math.stackexchange.com/a/897677 % ------ % Author: oqilipo % E-mail: N/A % Created: 2017-08-07 % Copyright 2017-2023 if isParallel3d(A,B) if A*B'>0 ROT = eye(4); else ROT = -1*eye(4); ROT(end)=1; end else a=normalizeVector3d(A); b=normalizeVector3d(B); a=reshape(a,3,1); b=reshape(b,3,1); v = cross(a,b); ssc = [0 -v(3) v(2); v(3) 0 -v(1); -v(2) v(1) 0]; ROT = eye(3) + ssc + ssc^2*(1-dot(a,b))/(norm(v))^2; ROT = [ROT, [0;0;0]; 0 0 0 1]; end end matgeom-1.2.4/inst/geom3d/PaxHeaders/createEdge3d.m0000644000000000000000000000013214576357161017034 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/createEdge3d.m0000644000175000017500000000637414576357161020626 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = createEdge3d(varargin) %CREATEEDGE3D Create an edge between two 3D points, or from a 3D line. % % E = createEdge3d(P1, P2) % Creates the 3D edge joining the two points P1 and P2. % % E = createEdge3d(LIN) % Creates the 3D edge with same origin and same direction vector as the % 3D line LIN. % % Example % p1 = [1 1 1]; % p2 = [3 4 5]; % edge = createEdge3d(p1, p2); % edgeLength3d(edge) % ans = % 5.3852 % % See also % edges3d, drawEdge3d, clipEdge3d, edgelength3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-08-29, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018-2023 INRA - Cepia Software Platform if nargin == 1 % Only one input parameter. Assumes it corresponds to a 3D line with % 6 params. var = varargin{1}; if size(var, 2) ~= 6 error('single input must have 6 columns'); end % converts 3D line into 3D edge edge = zeros(size(var)); edge(:, 1:3) = var(:, 1:3); edge(:, 4:6) = edge(:, 1:3) + var(:,4:6); elseif nargin == 2 % 2 input parameters correspond to two 3D points % extract the two arguments v1 = varargin{1}; v2 = varargin{2}; if size(v1, 2) ~= 3 || size(v2, 2) ~= 3 error('Input points must be arrays with 3 columns'); end % first input parameter is first point, and second input is the % second point. Allows multiple points. n1 = size(v1, 1); n2 = size(v2, 1); if n1 == n2 edge = [v1 v2]; elseif n1 == 1 || n2 == 1 edge = [repmat(v1, n2, 1) repmat(v2, n1, 1)]; end else error('Wrong number of arguments in ''%s''', mfilename); end matgeom-1.2.4/inst/geom3d/PaxHeaders/surfaceCurvature.m0000644000000000000000000000013214576357161020106 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/surfaceCurvature.m0000644000175000017500000000454014576357161021671 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function kappa = surfaceCurvature(kappa1, kappa2, theta) %SURFACECURVATURE Curvature on a surface from angle and principal curvatures. % % usage: % KAPPA = surfaceCurvature(KAPPA1, KAPPA2, THETA) % return the curvature KAPPA of surface with respect to direction THETA. % KAPPA1 and KAPPA2 are the principal curvatures of the surface at the % considered point. THETA is angle of direction relative to angle of % first principal curvature KAPPA1. % % Examples: % K = surfaceCurvature(KAPPA1, KAPPA2, 0) returns KAPPA1. % K = surfaceCurvature(KAPPA1, KAPPA2, pi/2) returns KAPPA2. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-07 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE kappa = kappa1 * cos(theta).^2 + kappa2 * sin(theta).^2; matgeom-1.2.4/inst/geom3d/PaxHeaders/normalizeVector3d.m0000644000000000000000000000013214576357161020167 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/normalizeVector3d.m0000644000175000017500000000452314576357161021753 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vn = normalizeVector3d(v) %NORMALIZEVECTOR3D Normalize a 3D vector to have norm equal to 1. % % V2 = normalizeVector3d(V); % Returns the normalization of vector V, such that ||V|| = 1. Vector V is % given as a row vector. % % If V is a N-by-3 array, normalization is performed for each row of the % input array. % % If V is a M-by-N-by-3 array, normalization is performed along the last % dimension of the array. % % See also % vectors3d, vectorNorm3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-11-29 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if ismatrix(v) vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); else vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, ndims(v)))); end matgeom-1.2.4/inst/geom3d/PaxHeaders/composeTransforms3d.m0000644000000000000000000000013214576357161020530 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/composeTransforms3d.m0000644000175000017500000000500414576357161022307 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = composeTransforms3d(varargin) %COMPOSETRANSFORMS3D Concatenate several space transformations. % % TRANS = composeTransforms3d(TRANS1, TRANS2, ...); % Computes the affine transform equivalent to performing successively % TRANS1, TRANS2, ... % % Example: % PTS = rand(20, 3); % ROT1 = createRotationOx(pi/3); % ROT2 = createRotationOy(pi/4); % ROT3 = createRotationOz(pi/5); % ROTS = composeTransforms3d(ROT1, ROT2, ROT3); % Then: % PTS2 = transformPoint3d(PTS, ROTS); % will give the same result as: % PTS3 = transformPoint3d(transformPoint3d(transformPoint3d(PTS, ... % ROT1), ROT2), ROT3); % % See also % transforms3d, transformPoint3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-09-29 % Copyright 2006-2023 INRA - TPV URPOI - BIA IMASTE trans = varargin{nargin}; for i=length(varargin)-1:-1:1 trans = trans * varargin{i}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/isPolygon3d.m0000644000000000000000000000013214576357161016767 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/isPolygon3d.m0000644000175000017500000000652214576357161020554 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function a = isPolygon3d(pol, varargin) %ISPOLYGON3D Check if input is a 3d polygon. % % B = isPolygon3d(POL) where POL should be a 3d polygon. % % Example: % % 2d polygon % pol = [6 7 6 6 5 4 3 2 2 1 2 2 6 6 ... % NaN 3 3 4 5 5 3 3 NaN 4 5 5 4; % 4 4 5 6 6 7 6 6 4 2 2 2 1 4 ... % NaN 4 5 5 4 4 3 4 NaN 3 2 3 3]'; % % 3d random transformation % phi=-360+720*rand; % theta=-360+720*rand; % psi=-360+720*rand; % % 3d polygon % pol3d = transformPolygon3d(pol, eulerAnglesToRotation3d(phi, theta, psi)); % disp('Valid 3d polygon') % disp(['Is 3d polygon?: ' num2str(isPolygon3d(pol3d))]) % disp('2d polygon, not 3d') % disp(['Is 3d polygon?: ' num2str(isPolygon3d(pol))]) % pol3d2 = pol3d; pol3d2(12) = pol3d2(12)+1e-12; % disp('Not all points in same plane') % disp(['Is 3d polygon?: ' num2str(isPolygon3d(pol3d2))]) % disp('Not real, contains complex elements') % pol3d3 = pol3d; pol3d3(12) = pol3d3(12)+4i; % disp(['Is 3d polygon?: ' num2str(isPolygon3d(pol3d3))]) % % See also % polygons3d % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-10-15, using MATLAB 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 narginchk(1,2) parser = inputParser; addOptional(parser,'tolerance',1e-12, ... @(x) validateattributes(x,{'numeric'},{'scalar','>',0,'<',1})) parse(parser, varargin{:}); TOL = parser.Results.tolerance; polRep = parsePolygon(pol,'repetition'); % Dimensions of the 3d polygon should be [Nx3]. if size(polRep,2)~=3 a=false; return end % All points must be located in the same plane. polPlane = fitPlane(polRep); if any(abs(distancePointPlane(polRep, polPlane)) > TOL) a=false; return end b = ~any(isinf(polRep(:))); c = isreal(polRep); a = b & c; end matgeom-1.2.4/inst/geom3d/PaxHeaders/vectors3d.m0000644000000000000000000000013214576357161016471 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/vectors3d.m0000644000175000017500000000431114576357161020250 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vectors3d(varargin) %VECTORS3D Description of functions operating on 3D vectors. % % Vectors are represented by their 3 Cartesian coordinates: % V = [VX VY VZ]; % % List of vectors are represented by N-by-3 arrays, with the coordinates % of each vector on a row. % % % See also % vectorNorm3d, normalizeVector3d, crossProduct3d, vectorAngle3d % isParallel3d, isPerpendicular3d, createTranslation3d % drawVector3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/geom3d/PaxHeaders/dihedralAngle.m0000644000000000000000000000013214576357161017300 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/dihedralAngle.m0000644000175000017500000000561014576357161021062 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = dihedralAngle(plane1, plane2) %DIHEDRALANGLE Compute dihedral angle between 2 planes. % % THETA = dihedralAngle(PLANE1, PLANE2) % PLANE1 and PLANE2 are plane representations given in the following % format: % [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % THETA is the angle between the two vectors given by plane normals, % given between 0 and PI. % % References % http://en.wikipedia.org/wiki/Dihedral_angle % http://mathworld.wolfram.com/DihedralAngle.html % % See also % planes3d, lines3d, angles3d, planesBisector % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % compute plane normals v1 = planeNormal(plane1); v2 = planeNormal(plane2); % number of vectors n1 = size(v1, 1); n2 = size(v2, 1); % ensures vectors have same dimension if n1 ~= n2 if n1 == 1 v1 = repmat(v1, [n2 1]); elseif n2 == 1 v2 = repmat(v2, [n1 1]); else error('Arguments V1 and V2 must have the same size'); end end % compute dihedral angle(s) theta = atan2(vectorNorm3d(cross(v1, v2, 2)), dot(v1, v2, 2)); % % equivalent to following formula, but more precise for small angles: % n1 = normalizeVector3d(planeNormal(plane1)); % n2 = normalizeVector3d(planeNormal(plane2)); % theta = acos(dot(n1, n2, 2)); matgeom-1.2.4/inst/geom3d/PaxHeaders/drawCircleArc3d.m0000644000000000000000000000013214576357161017511 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/drawCircleArc3d.m0000644000175000017500000000777714576357161021313 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCircleArc3d(varargin) %DRAWCIRCLEARC3D Draw a 3D circle arc. % % drawCircleArc3d([XC YC ZC R THETA PHI PSI START EXTENT]) % [XC YC ZC] : coordinate of arc center % R : arc radius % [THETA PHI] : orientation of arc normal, in degrees (theta: 0->180). % PSI : roll of arc (rotation of circle origin) % START : starting angle of arc, from arc origin, in degrees % EXTENT : extent of circle arc, in degrees (can be negative) % % Drawing options can be specified, as for the plot command. % % See also % angles3d, circles3d, drawCircle3d, drawCircleArc % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); arc = varargin{1}; varargin(1) = []; if iscell(arc) % save hold state holdState = ishold(hAx); hold(hAx, 'on'); h = []; for i = 1:length(arc) h = [h drawCircleArc3d(hAx, arc{i}, varargin{:})]; %#ok end % restore hold state if ~holdState hold(hAx, 'off'); end if nargout > 0 varargout = {h}; end return; end if size(arc, 1) > 1 % save hold state holdState = ishold(hAx); hold(hAx, 'on'); h = []; for i = 1:size(arc, 1) h = [h drawCircleArc3d(hAx, arc(i,:), varargin{:})]; %#ok end % restore hold state if ~holdState hold(hAx, 'off'); end if nargout > 0 varargout = {h}; end return; end % get center and radius xc = arc(:,1); yc = arc(:,2); zc = arc(:,3); r = arc(:,4); % get angle of normal theta = arc(:,5); phi = arc(:,6); psi = arc(:,7); % get starting angle and angle extent of arc start = arc(:,8); extent = arc(:,9); % positions on circle arc N = 60; t = linspace(start, start+extent, N+1) * pi / 180; % compute coordinate of points x = r*cos(t)'; y = r*sin(t)'; z = zeros(length(t), 1); curve = [x y z]; % compute transformation from local basis to world basis trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); % transform circle arc curve = transformPoint3d(curve, trans); % draw the curve with specified options h = drawPolyline3d(hAx, curve, varargin{:}); if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectLinePlane.m0000644000000000000000000000013214576357161020345 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.222193264 matgeom-1.2.4/inst/geom3d/intersectLinePlane.m0000644000175000017500000000755714576357161022143 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = intersectLinePlane(line, plane, varargin) %INTERSECTLINEPLANE Intersection point between a 3D line and a plane. % % PT = intersectLinePlane(LINE, PLANE) % Returns the intersection point of the given line and the given plane. % LINE: [x0 y0 z0 dx dy dz] % PLANE: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % PT: [xi yi zi] % If LINE and PLANE are parallel, return [NaN NaN NaN]. % If LINE (or PLANE) is a matrix with 6 (or 9) columns and N rows, result % is an array of points with N rows and 3 columns. % % PT = intersectLinePlane(LINE, PLANE, TOL) % Specifies the tolerance factor to test if a line is parallel to a % plane. Default is 1e-14. % % Example % % define horizontal plane through origin % plane = [0 0 0 1 0 0 0 1 0]; % % intersection with a vertical line % line = [2 3 4 0 0 1]; % intersectLinePlane(line, plane) % ans = % 2 3 0 % % intersection with a line "parallel" to plane % line = [2 3 4 1 2 0]; % intersectLinePlane(line, plane) % ans = % NaN NaN NaN % % See also % lines3d, planes3d, points3d, clipLine3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract tolerance if needed tol = 1e-14; if nargin > 2 tol = varargin{1}; end % unify sizes of data nLines = size(line, 1); nPlanes = size(plane, 1); % N planes and M lines not allowed if nLines ~= nPlanes && min(nLines, nPlanes) > 1 error('MatGeom:geom3d:intersectLinePlane', ... 'Input must have same number of rows, or one must be 1'); end % plane normal n = crossProduct3d(plane(:,4:6), plane(:,7:9)); % difference between origins of plane and line dp = bsxfun(@minus, plane(:, 1:3), line(:, 1:3)); % dot product of line direction with plane normal denom = sum(bsxfun(@times, n, line(:,4:6)), 2); % relative position of intersection point on line (can be inf in case of a % line parallel to the plane) t = sum(bsxfun(@times, n, dp),2) ./ denom; % compute coord of intersection point point = bsxfun(@plus, line(:,1:3), bsxfun(@times, [t t t], line(:,4:6))); % set indices of line and plane which are parallel to NaN par = abs(denom) < tol; point(par,:) = NaN; matgeom-1.2.4/inst/geom3d/PaxHeaders/reverseLine3d.m0000644000000000000000000000013214576357161017267 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/reverseLine3d.m0000644000175000017500000000417214576357161021053 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = reverseLine3d(line) %REVERSELINE3D Return same 3D line but with opposite orientation. % % INVLINE = reverseLine(LINE); % Returns the opposite line of LINE. % LINE has the format [x0 y0 z0 dx dy dz], then INVLINE will have % following parameters: [x0 y0 z0 -dx -dy -dz]. % % See also % reverseLine, reversePlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-05-24, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform line(:, 4:6) = -line(:, 4:6); matgeom-1.2.4/inst/geom3d/PaxHeaders/transformLine3d.m0000644000000000000000000000013214576357161017627 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/transformLine3d.m0000644000175000017500000000470314576357161021413 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = transformLine3d(line, trans) %TRANSFORMLINE3D Transform a 3D line with a 3D affine transform. % % LINE2 = transformLine3d(LINE1, TRANS) % % Example % P1 = [10 20 30]; % P2 = [30 40 50]; % L = createLine3d(P1, P2); % T = createRotationOx(P1, pi/6); % L2 = transformLine3d(L, T); % figure; hold on; % axis([0 100 0 100 0 100]); view(3); % drawPoint3d([P1;P2]); % drawLine3d(L, 'b'); % drawLine3d(L2, 'm'); % % See also % lines3d, transforms3d, transformPoint3d, transformVector3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-11-25, using Matlab 7.7.0.471 (R2008b) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas res = [... transformPoint3d(line(:, 1:3), trans) ... % transform origin point transformVector3d(line(:,4:6), trans)]; % transform direction vect. matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectPlanes.m0000644000000000000000000000013214576357161017720 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/intersectPlanes.m0000644000175000017500000000612014576357161021477 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = intersectPlanes(plane1, plane2, varargin) %INTERSECTPLANES Return intersection line between 2 planes in space. % % LINE = intersectPlanes(PLANE1, PLANE2) % Returns the straight line belonging to both planes. % PLANE: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % LINE: [x0 y0 z0 dx dy dz] % In case of parallel planes, returns line with NaN values. % % LINE = intersectPlanes(PLANE1, PLANE2, TOL) % Also specifies the tolerance for detecting parallel planes. % % See also % planes3d, lines3d, intersectLinePlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % plane normal n1 = normalizeVector3d(cross(plane1(:,4:6), plane1(:, 7:9), 2)); n2 = normalizeVector3d(cross(plane2(:,4:6), plane2(:, 7:9), 2)); % test if planes are parallel if abs(cross(n1, n2, 2)) < tol line = [NaN NaN NaN NaN NaN NaN]; return; end % Uses Hessian form, ie : N.p = d % I this case, d can be found as : -N.p0, when N is normalized d1 = dot(n1, plane1(:,1:3), 2); d2 = dot(n2, plane2(:,1:3), 2); % compute dot products dot1 = dot(n1, n1, 2); dot2 = dot(n2, n2, 2); dot12 = dot(n1, n2, 2); % intermediate computations det = dot1*dot2 - dot12*dot12; c1 = (d1*dot2 - d2*dot12)./det; c2 = (d2*dot1 - d1*dot12)./det; % compute line origin and direction p0 = c1*n1 + c2*n2; dp = cross(n1, n2, 2); line = [p0 dp]; matgeom-1.2.4/inst/geom3d/PaxHeaders/polygons3d.m0000644000000000000000000000013214576357161016656 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/polygons3d.m0000644000175000017500000000454214576357161020443 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polygons3d(varargin) %POLYGONS3D Description of functions operating on 3D polygons. % % A 3D polygon is simply a set of 3D points (called vertices) which are % assumed to be located in the same plane. % Several functions are provided for computing basic geometrical % parameters (centroid, angles), or intersections with lines or planes. % % See also % polygonArea3d, triangleArea3d, polygonCentroid3d, polygon3dNormalAngle % intersectLinePolygon3d, intersectLineTriangle3d, intersectRayPolygon3d % clipPolygonByPlane3d % drawPolygon3d, drawPolyline3d, fillPolygon3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/geom3d/PaxHeaders/mergeBoxes3d.m0000644000000000000000000000013214576357161017104 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/mergeBoxes3d.m0000644000175000017500000000507114576357161020667 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = mergeBoxes3d(box1, box2) %MERGEBOXES3D Merge 3D boxes, by computing their greatest extent. % % BOX = mergeBoxes3d(BOX1, BOX2); % % Example % box1 = [5 20 5 30 10 50]; % box2 = [0 15 0 15 0 20]; % mergeBoxes3d(box1, box2) % ans = % 0 20 0 30 0 50 % % % See also % boxes3d, drawBox3d, intersectBoxes3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % unify sizes of data if size(box1,1) == 1 box1 = repmat(box1, size(box2,1), 1); elseif size(box2, 1) == 1 box2 = repmat(box2, size(box1,1), 1); elseif size(box1,1) ~= size(box2,1) error('Bad size for inputs'); end % compute extreme coords mini = min(box1(:,1:2:end), box2(:,1:2:end)); maxi = max(box1(:,2:2:end), box2(:,2:2:end)); % concatenate result into a new box structure box = [mini(:,1) maxi(:,1) mini(:,2) maxi(:,2) mini(:,3) maxi(:,3)]; matgeom-1.2.4/inst/geom3d/PaxHeaders/normalizePlane.m0000644000000000000000000000013214576357161017535 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/normalizePlane.m0000644000175000017500000000544714576357161021327 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function plane2 = normalizePlane(plane1) %NORMALIZEPLANE Normalize parametric representation of a plane. % % PLANE2 = normalizePlane(PLANE1); % Transforms the plane PLANE1 in the following format: % [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], where: % - (X0, Y0, Z0) is a point belonging to the plane % - (DX1, DY1, DZ1) is a first direction vector % - (DX2, DY2, DZ2) is a second direction vector % into another plane, with the same format, but with: % - (x0 y0 z0) is the closest point of plane to the origin % - (DX1 DY1 DZ1) has norm equal to 1 % - (DX2 DY2 DZ2) has norm equal to 1 and is orthogonal to (DX1 DY1 DZ1) % % See also % planes3d, createPlane % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % compute first direction vector d1 = normalizeVector3d(plane1(:,4:6)); % compute second direction vector n = normalizeVector3d(planeNormal(plane1)); d2 = -normalizeVector3d(crossProduct3d(d1, n)); % compute origin point of the plane origins = repmat([0 0 0], [size(plane1, 1) 1]); p0 = projPointOnPlane(origins, [plane1(:,1:3) d1 d2]); % create the resulting plane plane2 = [p0 d1 d2]; matgeom-1.2.4/inst/geom3d/PaxHeaders/isBelowPlane.m0000644000000000000000000000013214576357161017141 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/isBelowPlane.m0000644000175000017500000000546114576357161020727 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function below = isBelowPlane(point, varargin) %ISBELOWPLANE Test whether a point is below or above a plane. % % BELOW = isBelowPlane(POINT, PLANE) % where POINT is given as coordinate row vector [XP YP ZP], and PLANE is % given as a row containing initial point and 2 direction vectors, % return TRUE if POINT lie below PLANE. % % Example % isBelowPlane([1 1 1], createPlane([1 2 3], [1 1 1])) % ans = % 1 % isBelowPlane([3 3 3], createPlane([1 2 3], [1 1 1])) % ans = % 0 % % See also % planes3d, points3d, linePosition3d, planePosition % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-01-05 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas if length(varargin)==1 plane = varargin{1}; elseif length(varargin)==2 plane = createPlane(varargin{1}, varargin{2}); end % ensure same dimension for parameters if size(point, 1)==1 point = repmat(point, [size(plane, 1) 1]); end if size(plane, 1)==1 plane = repmat(plane, [size(point, 1) 1]); end % compute position of point projected on 3D line corresponding to plane % normal, and returns true for points located below the plane (pos<=0). below = linePosition3d(point, [plane(:, 1:3) planeNormal(plane)]) <= 0; matgeom-1.2.4/inst/geom3d/PaxHeaders/eulerAnglesToRotation3d.m0000644000000000000000000000013214576357161021275 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/eulerAnglesToRotation3d.m0000644000175000017500000001366414576357161023067 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function mat = eulerAnglesToRotation3d(phi, theta, psi, varargin) %EULERANGLESTOROTATION3D Convert 3D Euler angles to 3D rotation matrix. % % MAT = eulerAnglesToRotation3d(PHI, THETA, PSI) % Creates a rotation matrix from the 3 euler angles PHI THETA and PSI, % given in degrees, using the 'XYZ' convention (local basis), or the % 'ZYX' convention (global basis). The result MAT is a 4-by-4 rotation % matrix in homogeneous coordinates. % % PHI: rotation angle around Z-axis, in degrees, corresponding to the % 'Yaw'. PHI is between -180 and +180. % THETA: rotation angle around Y-axis, in degrees, corresponding to the % 'Pitch'. THETA is between -90 and +90. % PSI: rotation angle around X-axis, in degrees, corresponding to the % 'Roll'. PSI is between -180 and +180. % These angles correspond to the "Yaw-Pitch-Roll" convention, also known % as "Tait-Bryan angles". % % The resulting rotation is equivalent to a rotation around X-axis by an % angle PSI, followed by a rotation around the Y-axis by an angle THETA, % followed by a rotation around the Z-axis by an angle PHI. % That is: % ROT = Rz * Ry * Rx; % % MAT = eulerAnglesToRotation3d(ANGLES) % Concatenates all angles in a single 1-by-3 array. % % ... = eulerAnglesToRotation3d(ANGLES, CONVENTION) % CONVENTION specifies the axis rotation sequence. Default is 'ZYX'. % Supported conventions are: % 'ZYX','ZXY','YXZ','YZX','XYZ','XZY' % 'ZYZ','ZXZ','YZY','YXY','XZX','XYX' % % Example % [n e f] = createCube; % phi = 20; % theta = 30; % psi = 10; % rot = eulerAnglesToRotation3d(phi, theta, psi); % n2 = transformPoint3d(n, rot); % drawPolyhedron(n2, f); % % See also % transforms3d, createRotationOx, createRotationOy, createRotationOz % rotation3dAxisAndAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % Process input arguments if size(phi, 2) == 3 if nargin > 1 varargin{1} = theta; end % manages arguments given as one array psi = phi(:, 3); theta = phi(:, 2); phi = phi(:, 1); end p = inputParser; validStrings = {... 'ZYX','ZXY','YXZ','YZX','XYZ','XZY',... 'ZYZ','ZXZ','YZY','YXY','XZX','XYX'}; addOptional(p,'convention','ZYX',@(x) any(validatestring(x,validStrings))); parse(p,varargin{:}); convention=p.Results.convention; % create individual rotation matrices k = pi / 180; switch convention case 'ZYX' rot1 = createRotationOx(psi * k); rot2 = createRotationOy(theta * k); rot3 = createRotationOz(phi * k); case 'ZXY' rot1 = createRotationOy(psi * k); rot2 = createRotationOx(theta * k); rot3 = createRotationOz(phi * k); case 'YXZ' rot1 = createRotationOz(psi * k); rot2 = createRotationOx(theta * k); rot3 = createRotationOy(phi * k); case 'YZX' rot1 = createRotationOx(psi * k); rot2 = createRotationOz(theta * k); rot3 = createRotationOy(phi * k); case 'XYZ' rot1 = createRotationOz(psi * k); rot2 = createRotationOy(theta * k); rot3 = createRotationOx(phi * k); case 'XZY' rot1 = createRotationOy(psi * k); rot2 = createRotationOz(theta * k); rot3 = createRotationOx(phi * k); case 'ZYZ' rot1 = createRotationOz(psi * k); rot2 = createRotationOy(theta * k); rot3 = createRotationOz(phi * k); case 'ZXZ' rot1 = createRotationOz(psi * k); rot2 = createRotationOx(theta * k); rot3 = createRotationOz(phi * k); case 'YZY' rot1 = createRotationOy(psi * k); rot2 = createRotationOz(theta * k); rot3 = createRotationOy(phi * k); case 'YXY' rot1 = createRotationOy(psi * k); rot2 = createRotationOx(theta * k); rot3 = createRotationOy(phi * k); case 'XZX' rot1 = createRotationOx(psi * k); rot2 = createRotationOz(theta * k); rot3 = createRotationOx(phi * k); case 'XYX' rot1 = createRotationOx(psi * k); rot2 = createRotationOy(theta * k); rot3 = createRotationOx(phi * k); end % concatenate matrices mat = rot3 * rot2 * rot1; matgeom-1.2.4/inst/geom3d/PaxHeaders/geodesicCylinder.m0000644000000000000000000000013214576357161020031 xustar0030 mtime=1710874225.102193378 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/geodesicCylinder.m0000644000175000017500000001222114576357161021607 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [geo, geoLength, conGeo, conGeoLength] = geodesicCylinder(pts, cyl, varargin) %GEODESICCYLINDER Computes the geodesic between two points on a cylinder. % % [GEO, GEOLENGTH] = geodesicCylinder(PTS, CYL) computes the geodesic % between the two points PTS projected onto the infinite cylinder CYL. % PTS is a 2-by-3 array, and CYL is a 1-by-7 array. Result is the % polyline GEO (500-by-3 array) [500 = default] containing the % coordinates of the geodesic between two projected points. GEOLENGTH % contains the analytical length of the geodesic. % % [~, ~, CONGEO, CONGEOLENGTH] = geodesicCylinder(PTS, CYL) provides the % conjugate geodesic and its analytical length. % % ... = geodesicCylinder(PTS, CYL, 'n', N) defines the number of points % representing the geodesic and conjugate geodesic. % % Example % demoGeodesicCylinder % % See also % drawCylinder, projPointOnCylinder % % Source % Based on the script 'geodesic.m' by Lei Wang % https://mathworks.com/matlabcentral/fileexchange/6522 % % ------ % Author: oqilipo % E-mail: N/A % Created: 2021-04-17, using MATLAB R2022b % Copyright 2021-2023 parser = inputParser; addRequired(parser, 'pts', @(x) validateattributes(x, {'numeric'},... {'size',[2 3],'real','finite','nonnan'})); addRequired(parser, 'cyl', @(x) validateattributes(x, {'numeric'},... {'size',[1 7],'real','finite','nonnan'})); addParameter(parser,'n',500, @(x) validateattributes(x, {'numeric'},... {'scalar','>', 2,'<=', 1e5})); parse(parser,pts,cyl,varargin{:}); pts = parser.Results.pts; cyl = parser.Results.cyl; n = parser.Results.n; % Radius of the cylinder cylRadius = cyl(7); % Project points onto the open (infinite) cylinder ptProj(1,:) = projPointOnCylinder(pts(1,:), cyl, 'open'); ptProj(2,:) = projPointOnCylinder(pts(2,:), cyl, 'open'); % Create a transformation for the points into the local cylinder coordinate % system. Align the cylinder axis with the z axis and translate the % starting point of the cylinder to the origin. TFM = createRotationVector3d(cyl(4:6)-cyl(1:3), [0 0 1])*createTranslation3d(-cyl(1:3)); % Transform the points. ptTfm = transformPoint3d(ptProj, TFM); % Convert the transformed points to cylindrical coordinates. [ptsTheta, ptsRadius, ptsHeight] = cart2cyl(ptTfm); assert(ismembertol(ptsRadius(1),ptsRadius(2))) assert(ismembertol(ptsRadius(1),cylRadius)) % Copy thetas for the conjugate geodesic ptsTheta(:,:,2) = ptsTheta; ptsTheta(1,1,2) = ptsTheta(1,1,2) + 2*pi; geoCyl = nan(n,3,size(ptsTheta,3)); arcLength = nan(1,size(ptsTheta,3)); for t = 1:size(ptsTheta,3) [geoCyl(:,:,t), arcLength(t)] = geoCurve(ptsTheta(:,:,t), cylRadius, ptsHeight, n); end % Select the shortest geodesic if arcLength(1) <= arcLength(2) % Transform the geodesics back to the global coordinate system geo = transformPoint3d(geoCyl(:,:,1), inv(TFM)); conGeo = transformPoint3d(geoCyl(:,:,2), inv(TFM)); geoLength = arcLength(1); conGeoLength = arcLength(2); else % Transform the geodesics back to the global coordinate system geo = transformPoint3d(geoCyl(:,:,2), inv(TFM)); conGeo = transformPoint3d(geoCyl(:,:,1), inv(TFM)); geoLength = arcLength(2); conGeoLength = arcLength(1); end end function [geo, arcLength] = geoCurve(theta, r, z, n) % Parametric expression of the geodesic curve u = linspace(theta(1),theta(2),n)'; geo(:,1) = r*cos(u); geo(:,2) = r*sin(u); geo(:,3) = (z(2)-z(1))/(theta(2)-theta(1))*u + (z(1)*theta(2)-z(2)*theta(1))/(theta(2)-theta(1)); if all(isnan(geo(:,3))) geo(:,3) = linspace(z(1),z(2),n)'; end arcLength = sqrt(r^2*(theta(2)-theta(1))^2+(z(2)-z(1))^2); end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawPolyline3d.m0000644000000000000000000000013214576357161017455 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.102193378 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawPolyline3d.m0000644000175000017500000001141414576357161021236 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawPolyline3d(varargin) %DRAWPOLYLINE3D Draw a 3D polyline specified by a list of vertex coords. % % drawPolyline3d(POLY); % packs coordinates in a single N-by-3 array. % % drawPolyline3d(PX, PY, PZ); % specifies coordinates in separate numeric vectors (either row or % columns) % % drawPolyline3d(..., CLOSED); % Specifies if the polyline is closed or open. CLOSED can be one of: % - 'closed' % - 'open' (the default) % - a boolean variable with value TRUE for closed polylines. % % drawPolyline3d(..., PARAM, VALUE); % Specifies style options to draw the polyline, see plot for details. % % H = drawPolyline3d(...); % also returns a handle to the list of created line objects. % % Example % t = linspace(0, 2*pi, 100)'; % xt = 10 * cos(t); % yt = 5 * sin(t); % zt = zeros(1,100); % figure; drawPolyline3d(xt, yt, zt, 'b'); % % See also % polygons3d, drawPolygon3d, fillPolygon3d % % ------ % Author : David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-15 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% Process input arguments % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % check case we want to draw several curves, stored in a cell array var = varargin{1}; if iscell(var) hold on; nPolys = length(var(:)); h = gobjects(1, nPolys); for i = 1:nPolys h(i) = drawPolyline3d(hAx, var{i}, varargin{2:end}); end if nargout > 0 varargout = {h}; end return; end % extract vertex coordinates if min(size(var)) == 1 % if first argument is a vector (either row or column), then assumes % first argument contains x coords, second argument contains y coords % and third one the z coords px = var; if length(varargin) < 3 error('geom3d:drawPolyline3d:Wrong number of arguments in drawPolyline3d'); end if isnumeric(varargin{2}) && isnumeric(varargin{3}) py = varargin{2}; pz = varargin{3}; varargin(1:3) = []; else px = var(:, 1); py = var(:, 2); pz = var(:, 3); varargin(1) = []; end else % all coordinates are grouped in the first argument px = var(:, 1); py = var(:, 2); pz = var(:, 3); varargin(1) = []; end % check if polyline is closed or open (default is open) closed = false; if ~isempty(varargin) var = varargin{1}; if islogical(var) % check boolean flag closed = var; varargin = varargin(2:end); elseif ischar(var) % check string indicating close or open if strncmpi(var, 'close', 5) closed = true; varargin = varargin(2:end); elseif strncmpi(var, 'open', 4) closed = false; varargin = varargin(2:end); end end end %% draw the polyline curve % for closed curve, add the first point at the end to close curve if closed px = [px(:); px(1)]; py = [py(:); py(1)]; pz = [pz(:); pz(1)]; end h = plot3(hAx, px, py, pz, varargin{:}); if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/planePosition.m0000644000000000000000000000013214576357161017401 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/planePosition.m0000644000175000017500000001211314576357161021157 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [pos, zp] = planePosition(point, plane) %PLANEPOSITION Compute position of a point on a plane. % % COORDS2D = planePosition(POINT, PLANE) % POINT has format [X Y Z], and plane has format % [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], where : % - (X0, Y0, Z0) is a point belonging to the plane % - (DX1, DY1, DZ1) is a first direction vector % - (DX2, DY2, DZ2) is a second direction vector % Result COORDS2D has the form [XP YP], with XP and YP the coordinates of % the point in the coordinate system of the plane. % % [COORDS2D, Z] = planePosition(POINT, PLANE) % Also returns the coordinates along the normal of the plane. When the % point is within the plane, this coordinate should be zero. % % Example % plane = [10 20 30 1 0 0 0 1 0]; % point = [13 24 35]; % pos = planePosition(point, plane) % pos = % 3 4 % % Example % % plane with non unit direction vectors % p0 = [30 20 10]; v1 = [2 1 0]; v2 = [-2 4 0]; % plane = [p0 v1 v2]; % pts = [p0 ; p0 + v1 ; p0 + v2 ; p0 + 3 * v1 + 2 * v2]; % pos = planePosition(pts, plane) % pos = % 0 0 % 1 0 % 0 1 % 3 2 % % % See also % geom3d, planes3d, points3d, planePoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % size of input arguments npl = size(plane, 1); npt = size(point, 1); % check inputs have compatible sizes if npl ~= npt && npl > 1 && npt > 1 error('geom3d:planePosition:inputSize', ... 'plane and point should have same size, or one of them must have 1 row'); end % origin and direction vectors of the plane(s) p0 = plane(:, 1:3); v1 = plane(:, 4:6); v2 = plane(:, 7:9); % Principle % % for each (recentered) point, we need to solve the system: % s * v1x + t * v2x + u * v3x = px % s * v1y + t * v2y + u * v3y = py % s * v1z + t * v2z + u * v3z = pz % Assuming the point belong to the place, the value of u is 0. The last % equation is kept only for homogeneity. % We rewrite in matrix form: % [ v1x v2x v3x ] [ s ] [ xp ] % [ v1y v2y v3y ] * [ t ] = [ yp ] % [ v1z v2z v3z ] [ u ] [ zp ] % Or: % A * X = B % We need to solve X = inv(A) * B. In practice, we use the b/A notation, % obtained after using transpositon on the A\b notation. % X' = (inv(mat) * bsxfun(@minus, point, p0)')'; % X' = bsxfun(@minus, point, p0) * inv(mat'); % X' = bsxfun(@minus, point, p0) / mat'; % (and we compute the transpose of the basis transform) % Compute dot products with direction vectors of the plane if npl == 1 % we have npl == 1 and npt > 1 % build transpose of matrix that changes plane basis to global basis mat = [v1 ; v2 ; cross(v1, v2, 2)]; tmp = bsxfun(@minus, point, p0) / mat; pos = tmp(:, 1:2); zp = tmp(:,3); else % NPL > 0 -> iterate over planes % Number of points can be either 1, or the same number as planes pos = zeros(npl, 2); zp = zeros(npl, 1); for ipl = 1:npl mat = [v1(ipl,:) ; v2(ipl,:) ; cross(v1(ipl,:), v2(ipl,:), 2)]; % choose either point with same index, or the single point ind = min(ipl, npt); tmp = bsxfun(@minus, point(ind,:), p0(ipl,:)) / mat; pos(ipl,:) = tmp(1,1:2); zp(ipl) = tmp(1,3); end end % % old version (: % s = dot(point-p0, d1, 2) ./ vectorNorm3d(d1); % t = dot(point-p0, d2, 2) ./ vectorNorm3d(d2); matgeom-1.2.4/inst/geom3d/PaxHeaders/circle3dOrigin.m0000644000000000000000000000013214576357161017415 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/circle3dOrigin.m0000644000175000017500000000511314576357161021175 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ori = circle3dOrigin(varargin) %CIRCLE3DORIGIN Return the first point of a 3D circle. % % P = circle3dOrigin([XC YC ZC R THETA PHI]) % P = circle3dOrigin([XC YC ZC R THETA PHI PSI]) % Returns the origin point of the circle, i.e. the first point used for % drawing circle. % % See also % circles3d, points3d, circle3dPosition % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); % get angle of normal theta = circle(:,5); phi = circle(:,6); % get roll if size(circle, 2)==7 psi = circle(:,7); else psi = zeros(size(circle, 1), 1); end % create origin point pt0 = [r 0 0]; % compute transformation from local basis to world basis trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); % transform the point ori = transformPoint3d(pt0, trans); matgeom-1.2.4/inst/geom3d/PaxHeaders/oblateSurfaceArea.m0000644000000000000000000000013214576357161020125 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/oblateSurfaceArea.m0000644000175000017500000000471014576357161021707 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function S = oblateSurfaceArea(elli, varargin) %OBLATESURFACEAREA Approximated surface area of an oblate ellipsoid. % % S = oblateSurfaceArea(R1,R2) % % Example % oblateSurfaceArea % % See also % geom3d, ellipsoidSurfaceArea, prolateSurfaceArea % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-07-03, using Matlab 7.9.0.529 (R2009b) % Copyright 2015-2023 INRA - Cepia Software Platform %% Parse input argument if size(elli, 2) == 7 R1 = elli(:, 4); R2 = elli(:, 5); elseif size(elli, 2) == 1 && ~isempty(varargin) R1 = elli(:, 1); R2 = varargin{1}; end assert(R1 < R2, 'First radius must be smaller than second radius'); % surface theorique d'un ellipsoide oblate % cf http://fr.wikipedia.org/wiki/Ellipso%C3%AFde_de_r%C3%A9volution e = sqrt(R2.^2 - R1.^2) ./ R2; S = 2 * pi * R2.^2 + pi * R1.^2 * log((1 + e) ./ (1 - e)) ./ e; matgeom-1.2.4/inst/geom3d/PaxHeaders/cart2sph2.m0000644000000000000000000000013214576357161016365 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/cart2sph2.m0000644000175000017500000000625614576357161020156 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cart2sph2(varargin) %CART2SPH2 Convert cartesian coordinates to spherical coordinates. % % [THETA PHI RHO] = cart2sph2([X Y Z]) % [THETA PHI RHO] = cart2sph2(X, Y, Z) % % The following convention is used: % THETA is the colatitude, in radians, 0 for north pole, +pi for south % pole, pi/2 for points with z=0. % PHI is the azimuth, in radians, defined as matlab cart2sph: angle from % Ox axis, counted counter-clockwise. % RHO is the distance of the point to the origin. % Discussion on choice for convention can be found at: % http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf % % Example: % cart2sph2([1 0 0]) returns [pi/2 0 1]; % cart2sph2([1 1 0]) returns [pi/2 pi/4 sqrt(2)]; % cart2sph2([0 0 1]) returns [0 0 1]; % % See also % angles3d, sph2cart2, cart2sph, cart2sph2d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % parse input angles based on input argument number if length(varargin) == 1 xyz = varargin{1}; elseif length(varargin) == 3 xyz = [varargin{1} varargin{2} varargin{3}]; end % ensure z coordinate is specified if size(xyz, 2) == 2 xyz(:,3) = 1; end % convert to spherical coordinates [p, t, r] = cart2sph(xyz(:,1), xyz(:,2), xyz(:,3)); % format output arguments if nargout == 1 || nargout == 0 varargout{1} = [pi/2-t p r]; elseif nargout==2 varargout{1} = pi/2-t; varargout{2} = p; else varargout{1} = pi/2-t; varargout{2} = p; varargout{3} = r; end matgeom-1.2.4/inst/geom3d/PaxHeaders/Contents.m0000644000000000000000000000013214576357161016352 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/Contents.m0000644000175000017500000004174414576357161020144 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. %CONTENTS GEOM3D Geometry 3D Toolbox. % Version 1.22 06-Jun-2018 . % % Creation, transformations, algorithms and visualization of geometrical % 3D primitives, such as points, lines, planes, polyhedra, circles and % spheres. % % Euler Angles are defined as follow: % PHI is the azimut, i.e. the angle of the projection on horizontal plane % with the Ox axis, with value beween 0 and 180 degrees. % THETA is the latitude, i.e. the angle with the Oz axis, with value % between -90 and +90 degrees. % PSI is the 'roll', i.e. the rotation around the (PHI, THETA) direction, % with value in degrees % See also the 'angles3d' page. % % Base format for primitives: % Point: [x0 y0 z0] % Vector: [dx dy dz] % Line: [x0 y0 z0 dx dy dz] % Edge: [x1 y1 z1 x2 y2 z2] % Plane: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % Sphere: [x0 y0 z0 R] % Circle: [x0 y0 z0 R PHI THETA PSI] (origin+center+normal+'roll'). % Ellipsoid: [x0 y0 z0 A B C PHI THETA PSI] % Cylinder: [X1 Y1 Z1 X2 Y2 Z2 R] % Box: [xmin xmax ymin ymax zmin zmax]. Used for clipping shapes. % % Polygons are represented by N-by-3 array of points, the last point is % not necessarily the same as the first one. Points must be coplanar. % % % 3D Points % points3d - Description of functions operating on 3D points. % midPoint3d - Middle point of two 3D points or of a 3D edge. % isCoplanar - Tests input points for coplanarity in 3-space. % transformPoint3d - Transform a point with a 3D affine transform. % distancePoints3d - Compute euclidean distance between pairs of 3D Points. % clipPoints3d - Clip a set of points by a box or other 3d shapes. % drawPoint3d - Draw 3D point on the current axis. % % 3D Vectors % vectors3d - Description of functions operating on 3D vectors. % transformVector3d - Transform a vector with a 3D affine transform. % normalizeVector3d - Normalize a 3D vector to have norm equal to 1. % vectorNorm3d - Norm of a 3D vector or of set of 3D vectors. % hypot3 - Diagonal length of a cuboidal 3D box . % crossProduct3d - Vector cross product faster than inbuilt MATLAB cross. % vectorAngle3d - Angle between two 3D vectors. % isParallel3d - Check parallelism of two 3D vectors. % isPerpendicular3d - Check orthogonality of two 3D vectors. % drawVector3d - Draw vector at a given position. % % Angles % angles3d - Conventions for manipulating angles in 3D. % anglePoints3d - Compute angle between three 3D points. % sphericalAngle - Compute angle between points on the sphere. % angleSort3d - Sort 3D coplanar points according to their angles in plane. % randomAngle3d - Return a 3D angle uniformly distributed on unit sphere. % % Coordinate transforms % sph2cart2 - Convert spherical coordinates to cartesian coordinates. % cart2sph2 - Convert cartesian coordinates to spherical coordinates. % cart2sph2d - Convert cartesian coordinates to spherical coordinates in degrees. % sph2cart2d - Convert spherical coordinates to cartesian coordinates in degrees. % cart2cyl - Convert cartesian to cylindrical coordinates. % cyl2cart - Convert cylindrical to cartesian coordinates. % % 3D Lines and Edges % lines3d - Description of functions operating on 3D lines. % createLine3d - Create a line with various inputs. % createEdge3d - Create an edge between two 3D points, or from a 3D line. % fitLine3d - Fit a 3D line to a set of points. % parallelLine3d - Create 3D line parallel to another one. % projPointOnLine3d - Project a 3D point orthogonally onto a 3D line. % distancePointLine3d - Euclidean distance between 3D point and line. % isPointOnLine3d - Test if a 3D point belongs to a 3D line. % linePosition3d - Return the position of a 3D point projected on a 3D line. % distanceLines3d - Minimal distance between two 3D lines. % transformLine3d - Transform a 3D line with a 3D affine transform. % reverseLine3d - Return same 3D line but with opposite orientation. % normalizeLine3d - Normalizes the direction vector of a 3D line. % clipLine3d - Clip a line with a box and return an edge. % drawLine3d - Draw a 3D line clipped by the current axes. % % 3D Edges and Rays % edges3d - Description of functions operating on 3D edges. % edgeLength3d - Return the length of a 3D edge. % clipEdge3d - Clip a 3D edge with a cuboid box. % lineToEdge3d - Convert a 3D straight line to a 3D finite edge. % edgeToLine3d - Convert a 3D edge to a 3D straight line. % distancePointEdge3d - Minimum distance between a 3D point and a 3D edge. % isPointOnEdge3d - Test if a 3D point belongs to an edge. % drawEdge3d - Draw 3D edge in the current axes. % createRay3d - Create a 3D ray. % clipRay3d - Clip a 3D ray with a box and return a 3D edge. % drawRay3d - Draw a 3D ray on the current axis. % % Planes % planes3d - Description of functions operating on 3D planes. % createPlane - Create a plane in parametrized form. % clipPlane - Compute the 3D polygon representing a clipped plane. % fitPlane - Fit a 3D plane to a set of points. % normalizePlane - Normalize parametric representation of a plane. % parallelPlane - Parallel to a plane through a point or at a given distance. % reversePlane - Return same 3D plane but with opposite orientation. % isPlane - Check if input is a plane. % transformPlane3d - Transform a 3D plane with a 3D affine transform. % planesBisector - Bisector plane between two other planes. % projPointOnPlane - Return the orthogonal projection of a point on a plane. % intersectPlanes - Return intersection line between 2 planes in space. % intersectThreePlanes - Return intersection point between 3 planes in space. % intersectLinePlane - Intersection point between a 3D line and a plane. % intersectEdgePlane - Return intersection point between a plane and a edge. % distancePointPlane - Signed distance betwen 3D point and plane. % projLineOnPlane - Return the orthogonal projection of a line on a plane. % isBelowPlane - Test whether a point is below or above a plane. % medianPlane - Create a plane in the middle of 2 points. % planeNormal - Compute the normal to a plane. % planePosition - Compute position of a point on a plane. % planePoint - Compute 3D position of a point in a plane. % dihedralAngle - Compute dihedral angle between 2 planes. % drawPlane3d - Draw a plane clipped by the current axes. % % 3D Polygons and curves % polygons3d - Description of functions operating on 3D polygons. % isPolygon3d - Check if input is a 3d polygon. % polygonCentroid3d - Centroid (or center of mass) of a polygon. % polygonArea3d - Area of a 3D polygon. % polygon3dNormalAngle - Normal angle at a vertex of the 3D polygon. % intersectEdgePolygon3d - Intersection point of a 3D edge segment and a 3D polygon. % intersectLinePolygon3d - Intersection point of a 3D line and a 3D polygon. % intersectRayPolygon3d - Intersection point of a 3D ray and a 3D polygon. % clipPolygonByPlane3d - Clip a 3D polygon with a plane. % drawPolygon3d - Draw a 3D polygon specified by a list of vertex coords. % drawPolyline3d - Draw a 3D polyline specified by a list of vertex coords. % fillPolygon3d - Fill a 3D polygon specified by a list of vertex coords. % transformPolygon3d - Transform a polygon with a 3D affine transform. % % 3D Triangles % triangleArea3d - Area of a 3D triangle. % distancePointTriangle3d - Minimum distance between a 3D point and a 3D triangle. % intersectLineTriangle3d - Intersection point of a 3D line and a 3D triangle. % % 3D circles and ellipses % circles3d - Description of functions operating on 3D circles. % fitCircle3d - Fit a 3D circle to a set of points. % fitEllipse3d - Fit an ellipse to a set of points. % circle3dPosition - Return the angular position of a point on a 3D circle. % circle3dPoint - Coordinates of a point on a 3D circle from its position. % circle3dOrigin - Return the first point of a 3D circle. % distancePointCircle3d - Distance between 3D points and 3D circle. % drawCircle3d - Draw a 3D circle. % drawCircleArc3d - Draw a 3D circle arc. % drawEllipse3d - Draw a 3D ellipse. % projPointOnCircle3d - Project a 3D point onto a 3D circle. % transformCircle3d - Transform a 3D circle with a 3D affine transformation. % % Spheres % spheres - Description of functions operating on 3D spheres. % createSphere - Create a sphere containing 4 points. % fitSphere - Fit a sphere to 3D points using the least squares approach. % intersectLineSphere - Return intersection points between a line and a sphere. % intersectPlaneSphere - Return intersection circle between a plane and a sphere. % drawSphere - Draw a sphere as a mesh. % drawSphericalEdge - Draw an edge on the surface of a sphere. % drawSphericalTriangle - Draw a triangle on a sphere. % fillSphericalTriangle - Fill a triangle on a sphere. % drawSphericalPolygon - Draw a spherical polygon. % fillSphericalPolygon - Fill a spherical polygon. % sphericalVoronoiDomain - Compute a spherical voronoi domain. % % Smooth surfaces % equivalentEllipsoid - Equivalent ellipsoid of a set of 3D points. % isPointInEllipsoid - Check if a point is located inside a 3D ellipsoid. % ellipsoidSurfaceArea - Approximated surface area of an ellipsoid. % oblateSurfaceArea - Approximated surface area of an oblate ellipsoid. % prolateSurfaceArea - Approximated surface area of a prolate ellipsoid. % cylinderSurfaceArea - Surface area of a cylinder. % geodesicCylinder - Computes the geodesic between two points on a cylinder. % intersectLineCylinder - Compute intersection points between a line and a cylinder. % projPointOnCylinder - Project a 3D point onto a cylinder. % revolutionSurface - Create a surface of revolution from a planar curve. % surfaceCurvature - Curvature on a surface from angle and principal curvatures. % drawEllipsoid - Draw a 3D ellipsoid. % drawTorus - Draw a torus (3D ring). % drawCylinder - Draw a cylinder. % drawEllipseCylinder - Draw a cylinder with ellipse cross-section. % drawCapsule - Draw a capsule. % drawDome - Draw a dome (half-sphere, semi-sphere) as a mesh. % drawSurfPatch - Draw a 3D surface patch, with 2 parametrized surfaces. % % Bounding boxes management % boxes3d - Description of functions operating on 3D boxes. % boundingBox3d - Bounding box of a set of 3D points. % orientedBox3d - Object-oriented bounding box of a set of 3D points. % intersectBoxes3d - Intersection of two 3D bounding boxes. % mergeBoxes3d - Merge 3D boxes, by computing their greatest extent. % box3dVolume - Volume of a 3-dimensional box. % randomPointInBox3d - Generate random point(s) within a 3D box. % drawBox3d - Draw a 3D box defined by coordinate extents. % % Geometric transforms % transforms3d - Conventions for manipulating 3D affine transforms. % fitAffineTransform3d - Compute the affine transform that best register two 3D point sets. % registerPoints3dAffine - Fit 3D affine transform using iterative algorithm. % createTranslation3d - Create the 4x4 matrix of a 3D translation. % createScaling3d - Create the 4x4 matrix of a 3D scaling. % createRotationOx - Create the 4x4 matrix of a 3D rotation around x-axis. % createRotationOy - Create the 4x4 matrix of a 3D rotation around y-axis. % createRotationOz - Create the 4x4 matrix of a 3D rotation around z-axis. % createBasisTransform3d - Compute matrix for transforming a basis into another basis. % eulerAnglesToRotation3d - Convert 3D Euler angles to 3D rotation matrix. % isTransform3d - Check if input is a affine transformation matrix. % rotation3dToEulerAngles - Extract Euler angles from a rotation matrix. % createRotation3dLineAngle - Create rotation around a line by an angle theta. % rotation3dAxisAndAngle - Determine axis and angle of a 3D rotation matrix. % createRotationVector3d - Calculates the rotation between two vectors. % createRotationVectorPoint3d - Calculates the rotation between two vectors. % createRotationAboutPoint3d - Rotate about a point using a rotation matrix. % recenterTransform3d - Change the fixed point of an affine 3D transform. % composeTransforms3d - Concatenate several space transformations. % % Various drawing Functions % drawGrid3d - Draw a 3D grid on the current axis. % drawAxis3d - Draw a coordinate system and an origin. % drawAxisCube - Draw a colored cube representing axis orientation. % drawCube - Draw a 3D centered cube, eventually rotated. % drawCuboid - Draw a 3D cuboid, eventually rotated. % drawPlatform - Draw a rectangular platform with a given size. % drawLabels3d - Draw text labels at specified 3D positions. % drawArrow3d - plot a quiver of 3D arrows. % drawAngleBetweenVectors3d - Draw an arc between 2 vectors. % % % Credits: % * Several functions contributed by Sven Holcombe % * function isCoplanar was originally written by Brett Shoelson. % * Songbai Ji enhanced file intersectPlaneLine (6/23/2006). % * several functions contributed by oqilipo % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-07 % Copyright 2005-2023 INRA help(mfilename); % In development: % drawPartialPatch - draw surface patch, with 2 parametrized surfaces. matgeom-1.2.4/inst/geom3d/PaxHeaders/cart2sph2d.m0000644000000000000000000000013214576357161016531 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/cart2sph2d.m0000644000175000017500000000653214576357161020317 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cart2sph2d(x, y, z) %CART2SPH2D Convert cartesian coordinates to spherical coordinates in degrees. % % [THETA PHI RHO] = cart2sph2d([X Y Z]) % [THETA PHI RHO] = cart2sph2d(X, Y, Z) % % The following convention is used: % THETA is the colatitude, in degrees, 0 for north pole, 180 degrees for % south pole, 90 degrees for points with z=0. % PHI is the azimuth, in degrees, defined as matlab cart2sph: angle from % Ox axis, counted counter-clockwise. % RHO is the distance of the point to the origin. % Discussion on choice for convention can be found at: % http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf % % Example: % cart2sph2d([1 0 0]) % ans = % 90 0 1 % % cart2sph2d([1 1 0]) % ans = % 90 45 1.4142 % % cart2sph2d([0 0 1]) % ans = % 0 0 1 % % % check consistency with sph2cart2d % sph2cart2d(cart2sph2d(30, 40, 5)) % ans = % 30.0000 40.0000 5.0000 % % See also % angles3d, sph2cart2d, cart2sph, cart2sph2 % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % if data are grouped, extract each coordinate if nargin == 1 y = x(:, 2); z = x(:, 3); x = x(:, 1); end % cartesian to spherical conversion hxy = hypot(x, y); rho = hypot(hxy, z); theta = 90 - atan2(z, hxy) * 180 / pi; phi = atan2(y, x) * 180 / pi; % format output if nargout <= 1 varargout{1} = [theta phi rho]; elseif nargout == 2 varargout{1} = theta; varargout{2} = phi; else varargout{1} = theta; varargout{2} = phi; varargout{3} = rho; end matgeom-1.2.4/inst/geom3d/PaxHeaders/projPointOnPlane.m0000644000000000000000000000013214576357161020016 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/projPointOnPlane.m0000644000175000017500000000671114576357161021603 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = projPointOnPlane(point, plane) %PROJPOINTONPLANE Return the orthogonal projection of a point on a plane. % % PT2 = projPointOnPlane(PT1, PLANE); % Compute the (orthogonal) projection of point PT1 onto the plane PLANE, % given as [X0 Y0 Z0 VX1 VY1 VZ1 VX2 VY2 VZ2] (origin point, first % direction vector, second directionvector). % % The function is fully vectorized, in that multiple points may be % projected onto multiple planes in a single call, returning multiple % points. With the exception of the second dimension (where % SIZE(PT1,2)==3, and SIZE(PLANE,2)==9), each dimension of PT1 and PLANE % must either be equal or one, similar to the requirements of BSXFUN. In % basic usage, point PT1 is a [N*3] array, and PLANE is a [N*9] array % (see createPlane for details). Result PT2 is a [N*3] array, containing % coordinates of orthogonal projections of PT1 onto planes PLANE. In % vectorised usage, PT1 is an [N*3*M*P...] matrix, and PLANE is an % [X*9*Y...] matrix, where (N,X), (M,Y), etc, are either equal pairs, or % one of the two is one. % % See also % planes3d, points3d, planePosition, intersectLinePlane % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % Unpack the planes into origins and normals, keeping original shape plSize = size(plane); plSize(2) = 3; [origins, normals] = deal(zeros(plSize)); origins(:) = plane(:,1:3,:); normals(:) = crossProduct3d(plane(:,4:6,:), plane(:, 7:9,:)); % difference between origins of plane and point dp = bsxfun(@minus, origins, point); % relative position of point on normal's line t = bsxfun(@rdivide, sum(bsxfun(@times,normals,dp),2), sum(normals.^2,2)); % add relative difference to project point back to plane point = bsxfun(@plus, point, bsxfun(@times, t, normals)); matgeom-1.2.4/inst/geom3d/PaxHeaders/drawEllipse3d.m0000644000000000000000000000013214576357161017257 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawEllipse3d.m0000644000175000017500000001744514576357161021052 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipse3d(varargin) %DRAWELLIPSE3D Draw a 3D ellipse. % % Possible calls for the function : % drawEllipse3d([XC YC ZC A B THETA PHI]) % drawEllipse3d([XC YC ZC A B THETA PHI PSI]) % drawEllipse3d([XC YC ZC A B], [THETA PHI]) % drawEllipse3d([XC YC ZC A B], [THETA PHI PSI]) % drawEllipse3d([XC YC ZC A B], THETA, PHI) % drawEllipse3d([XC YC ZC], A, B, THETA, PHI) % drawEllipse3d([XC YC ZC A B], THETA, PHI, PSI) % drawEllipse3d([XC YC ZC], A, B, THETA, PHI, PSI) % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI) % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI, PSI) % % where XC, YC, ZY are coordinate of ellipse center, A and B are the % half-lengths of the major and minor axes of the ellipse, % PHI and THETA are 3D angle (in degrees) of the normal to the plane % containing the ellipse (PHI between 0 and 360 corresponding to % longitude, and THETA from 0 to 180, corresponding to angle with % vertical). % % H = drawEllipse3d(...) % return handle on the created LINE object % % Example % figure; axis([-10 10 -10 10 -10 10]); hold on; % ellXY = [0 0 0 8 5 0 0 0]; % drawEllipse3d(ellXY, 'color', [.8 0 0], 'linewidth', 2) % ellXZ = [0 0 0 8 2 90 90 90]; % drawEllipse3d(ellXZ, 'color', [0 .8 0], 'linewidth', 2) % ellYZ = [0 0 0 5 2 90 0 90]; % drawEllipse3d(ellYZ, 'color', [0 0 .8], 'linewidth', 2) % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-05-07 % Copyright 2008-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % Possible calls for the function, with number of arguments : % drawEllipse3d([XC YC ZC A B THETA PHI]) 1 % drawEllipse3d([XC YC ZC A B THETA PHI PSI]) 1 % drawEllipse3d([XC YC ZC A B], [THETA PHI]) 2 % drawEllipse3d([XC YC ZC A B], [THETA PHI PSI]) 2 % drawEllipse3d([XC YC ZC A B], THETA, PHI) 3 % drawEllipse3d([XC YC ZC A B], THETA, PHI, PSI) 4 % drawEllipse3d([XC YC ZC], A, B, THETA, PHI) 5 % drawEllipse3d([XC YC ZC], A, B, THETA, PHI, PSI) 6 % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI) 7 % drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI, PSI) 8 % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % extract drawing options ind = find(cellfun(@ischar, varargin), 1, 'first'); options = {}; if ~isempty(ind) options = varargin(ind:end); varargin(ind:end) = []; end if length(varargin)==1 % get center and radius elli3d = varargin{1}; xc = elli3d(:,1); yc = elli3d(:,2); zc = elli3d(:,3); a = elli3d(:,4); b = elli3d(:,5); % get colatitude of normal if size(elli3d, 2)>=6 theta = elli3d(:,6); else theta = zeros(size(elli3d, 1), 1); end % get azimut of normal if size(elli3d, 2)>=7 phi = elli3d(:,7); else phi = zeros(size(elli3d, 1), 1); end % get roll if size(elli3d, 2)==8 psi = elli3d(:,8); else psi = zeros(size(elli3d, 1), 1); end elseif length(varargin)==2 % get center and radius elli3d = varargin{1}; xc = elli3d(:,1); yc = elli3d(:,2); zc = elli3d(:,3); a = elli3d(:,4); b = elli3d(:,5); % get angle of normal angle = varargin{2}; theta = angle(:,1); phi = angle(:,2); % get roll if size(angle, 2)==3 psi = angle(:,3); else psi = zeros(size(angle, 1), 1); end elseif length(varargin)==3 % get center and radius elli3d = varargin{1}; xc = elli3d(:,1); yc = elli3d(:,2); zc = elli3d(:,3); a = elli3d(:,4); b = elli3d(:,5); % get angle of normal and roll theta = varargin{2}; phi = varargin{3}; psi = zeros(size(phi, 1), 1); elseif length(varargin)==4 % get center and radius elli3d = varargin{1}; xc = elli3d(:,1); yc = elli3d(:,2); zc = elli3d(:,3); if size(elli3d, 2)==5 a = elli3d(:,4); b = elli3d(:,5); end theta = varargin{2}; phi = varargin{3}; psi = varargin{4}; elseif length(varargin)==5 % get center and radius elli3d = varargin{1}; xc = elli3d(:,1); yc = elli3d(:,2); zc = elli3d(:,3); a = varargin{2}; b = varargin{3}; theta = varargin{4}; phi = varargin{5}; psi = zeros(size(phi, 1), 1); elseif length(varargin)==6 elli3d = varargin{1}; xc = elli3d(:,1); yc = elli3d(:,2); zc = elli3d(:,3); a = varargin{2}; b = varargin{3}; theta = varargin{4}; phi = varargin{5}; psi = varargin{6}; elseif length(varargin)==7 xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; a = varargin{4}; b = varargin{5}; theta = varargin{6}; phi = varargin{7}; psi = zeros(size(phi, 1), 1); elseif length(varargin)==8 xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; a = varargin{4}; b = varargin{5}; theta = varargin{6}; phi = varargin{7}; psi = varargin{8}; else error('drawEllipse3d: please specify center and radius'); end % uses 60 intervals t = linspace(0, 2*pi, 61)'; nElli = size(xc, 1); % save hold state holdState = ishold(hAx); hold(hAx, 'on'); % iterate over ellipses to draw for i = 1:nElli % polyline approximation of ellipse, centered and parallel to main axes xt = a(i) * cos(t); yt = b(i) * sin(t); zt = zeros(length(t), 1); elli2d = [xt yt zt]; % compute transformation from local basis to world basis trans = localToGlobal3d(xc(i), yc(i), zc(i), theta(i), phi(i), psi(i)); % transform points composing the ellipse elli3d = transformPoint3d(elli2d, trans); % draw the curve h = drawPolyline3d(hAx, elli3d, options{:}); end % restore hold state if ~holdState hold(hAx, 'off'); end % format output arguments if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/distancePointPlane.m0000644000000000000000000000013214576357161020341 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/distancePointPlane.m0000644000175000017500000000456514576357161022133 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function d = distancePointPlane(point, plane) %DISTANCEPOINTPLANE Signed distance between 3D point and plane. % % D = distancePointPlane(POINT, PLANE) % Returns the euclidean distance between point POINT and the plane PLANE, % given by: % POINT : [x0 y0 z0] % PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % D : scalar % % See also % planes3d, points3d, intersectLinePlane % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % normalized plane normal n = normalizeVector3d(cross(plane(:,4:6), plane(:, 7:9), 2)); % Uses Hessian form, ie : N.p = d % I this case, d can be found as : -N.p0, when N is normalized d = -sum(bsxfun(@times, n, bsxfun(@minus, plane(:,1:3), point)), 2); matgeom-1.2.4/inst/geom3d/PaxHeaders/drawCircle3d.m0000644000000000000000000000013214576357161017063 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawCircle3d.m0000644000175000017500000002004014576357161020637 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCircle3d(varargin) %DRAWCIRCLE3D Draw a 3D circle. % % Possible calls for the function: % drawCircle3d([XC YC ZC R THETA PHI]) % drawCircle3d([XC YC ZC R], [THETA PHI]) % % where XC, YC, ZY are coordinates of circle center, R is the circle % radius, PHI and THETA are 3D angles in degrees of the normal to the % plane containing the circle: % * THETA between 0 and 180 degrees, corresponding to the colatitude % (angle with Oz axis). % * PHI between 0 and 360 degrees corresponding to the longitude (angle % with Ox axis) % % drawCircle3d([XC YC ZC R THETA PHI PSI]) % drawCircle3d([XC YC ZC R], [THETA PHI PSI]) % drawCircle3d([XC YC ZC R], THETA, PHI) % drawCircle3d([XC YC ZC], R, THETA, PHI) % drawCircle3d([XC YC ZC R], THETA, PHI, PSI) % drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) % drawCircle3d(XC, YC, ZC, R, THETA, PHI) % drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) % Are other possible syntaxes for this function. % % H = drawCircle3d(...) % return handle on the created LINE object % % Example % % display 3 mutually orthogonal 3D circles % figure; hold on; % drawCircle3d([10 20 30 50 0 0], 'LineWidth', 2, 'Color', 'b'); % drawCircle3d([10 20 30 50 90 0], 'LineWidth', 2, 'Color', 'r'); % drawCircle3d([10 20 30 50 90 90], 'LineWidth', 2, 'Color', 'g'); % axis equal; % axis([-50 100 -50 100 -50 100]); % view([-10 20]) % % % Draw several circles at once % center = [10 20 30]; % circ1 = [center 50 0 0]; % circ2 = [center 50 90 0]; % circ3 = [center 50 90 90]; % figure; hold on; % drawCircle3d([circ1 ; circ2 ; circ3]); % axis equal; % % See also % circles3d, drawCircleArc3d, drawEllipse3d, drawSphere % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % Possible calls for the function, with number of arguments : % drawCircle3d([XC YC ZC R THETA PHI]) 1 % drawCircle3d([XC YC ZC R THETA PHI PSI]) 1 % drawCircle3d([XC YC ZC R], [THETA PHI]) 2 % drawCircle3d([XC YC ZC R], [THETA PHI PSI]) 2 % drawCircle3d([XC YC ZC R], THETA, PHI) 3 % drawCircle3d([XC YC ZC], R, THETA, PHI) 4 % drawCircle3d([XC YC ZC R], THETA, PHI, PSI) 4 % drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) 5 % drawCircle3d(XC, YC, ZC, R, THETA, PHI) 6 % drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) 7 % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % extract drawing options if verLessThan('matlab', '7.8') ind = find(cellfun('isclass', varargin, 'char'), 1, 'first'); else ind = find(cellfun(@ischar, varargin), 1, 'first'); end options = {}; if ~isempty(ind) options = varargin(ind:end); varargin(ind:end) = []; end % Extract circle data if length(varargin) == 1 % get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); % get colatitude of normal if size(circle, 2) >= 5 theta = circle(:,5); else theta = zeros(size(circle, 1), 1); end % get azimut of normal if size(circle, 2)>=6 phi = circle(:,6); else phi = zeros(size(circle, 1), 1); end % get roll if size(circle, 2)==7 psi = circle(:,7); else psi = zeros(size(circle, 1), 1); end elseif length(varargin) == 2 % get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); % get angle of normal angle = varargin{2}; theta = angle(:,1); phi = angle(:,2); % get roll if size(angle, 2)==3 psi = angle(:,3); else psi = zeros(size(angle, 1), 1); end elseif length(varargin) == 3 % get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); % get angle of normal and roll theta = varargin{2}; phi = varargin{3}; psi = zeros(size(phi, 1), 1); elseif length(varargin) == 4 % get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); if size(circle, 2)==4 r = circle(:,4); theta = varargin{2}; phi = varargin{3}; psi = varargin{4}; else r = varargin{2}; theta = varargin{3}; phi = varargin{4}; psi = zeros(size(phi, 1), 1); end elseif length(varargin) == 5 % get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = varargin{2}; theta = varargin{3}; phi = varargin{4}; psi = varargin{5}; elseif length(varargin) == 6 xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; r = varargin{4}; theta = varargin{5}; phi = varargin{6}; psi = zeros(size(phi, 1), 1); elseif length(varargin) == 7 xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; r = varargin{4}; theta = varargin{5}; phi = varargin{6}; psi = varargin{7}; else error('drawCircle3d: please specify center and radius'); end % circle parametrisation (by using N=60, some vertices are located at % special angles like 45°, 30°...) Nt = 60; t = linspace(0, 2*pi, Nt+1); nCircles = length(xc); h = zeros(nCircles, 1); % save hold state holdState = ishold(hAx); hold(hAx, 'on'); % iterate over circles to draw for i = 1:nCircles % compute position of circle points x = r(i) * cos(t)'; y = r(i) * sin(t)'; z = zeros(length(t), 1); circle0 = [x y z]; % compute transformation from local basis to world basis trans = localToGlobal3d(xc(i), yc(i), zc(i), theta(i), phi(i), psi(i)); % compute points of transformed circle circle = transformPoint3d(circle0, trans); % draw the curve of circle points h(i) = drawPolyline3d(hAx, circle, options{:}); end % restore hold state if ~holdState hold(hAx, 'off'); end if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawPoint3d.m0000644000000000000000000000013214576357161016753 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawPoint3d.m0000644000175000017500000001015614576357161020536 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function h = drawPoint3d(varargin) %DRAWPOINT3D Draw 3D point on the current axis. % % drawPoint3d(X, Y, Z) % will draw points defined by coordinates X, Y and Z. % X, Y and Z are N*1 array, with N being number of points to be drawn. % % drawPoint3d(COORD) packs coordinates in a single [N*3] array. % % drawPoint3d(..., OPT) will draw each point with given option. OPT is a % string compatible with 'plot' model. % % drawPoint3d(AX,...) plots into AX instead of GCA. % % H = drawPoint3d(...) returns a handle H to the line object % % Example % % generate points on a 3D circle % pts = circleToPolygon([40 30 20], 120); % mat = eulerAnglesToRotation3d([30 20 10]); % pts3d = transformPoint3d([pts zeros(120,1)],mat); % figure; drawPoint3d(pts3d, 'b.'); % view(3); axis equal; % % See also % points3d, clipPoints3d, drawPoint % % ------ % Author : David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); if length(varargin) == 1 && size(varargin{1}, 2) == 3 % points are given as one single array with 3 columns px = varargin{1}(:,1); py = varargin{1}(:,2); pz = varargin{1}(:,3); varargin = {}; elseif length(varargin) == 2 && size(varargin{1}, 2) == 3 % points are given as one single array with 3 columns px = varargin{1}(:,1); py = varargin{1}(:,2); pz = varargin{1}(:,3); varargin = varargin(2); elseif length(varargin) >= 3 && size(varargin{1}, 2) == 3 % points are given as one single array with 3 columns px = varargin{1}(:,1); py = varargin{1}(:,2); pz = varargin{1}(:,3); varargin = varargin(2:end); elseif length(varargin) == 3 && numel(varargin{1})==numel(varargin{2}) && numel(varargin{1})==numel(varargin{3}) % points are given as 3 columns with equal lengths px = varargin{1}; py = varargin{2}; pz = varargin{3}; varargin = {}; elseif length(varargin) > 3 % points are given as 3 columns with equal lengths px = varargin{1}; py = varargin{2}; pz = varargin{3}; varargin = varargin(4:end); else error('wrong number of arguments in drawPoint3d'); end % default draw style: no line, marker is 'o' if length(varargin) ~= 1 varargin = ['linestyle', 'none', 'marker', 'o', varargin]; end % plot only points inside the axis. hh = plot3(hAx, px, py, pz, varargin{:}); if nargout > 0 h = hh; end matgeom-1.2.4/inst/geom3d/PaxHeaders/circle3dPoint.m0000644000000000000000000000013214576357161017257 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/circle3dPoint.m0000644000175000017500000000570314576357161021044 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = circle3dPoint(circle, pos) %CIRCLE3DPOINT Coordinates of a point on a 3D circle from its position. % % output = circle3dPoint(input) % % Example % % Draw some points on a 3D circle % figure('color','w'); hold on; view(130,-10); % circle = [10 20 30 50 90 45 0]; % drawCircle3d(circle) % % origin point % pos1 = 0; % drawPoint3d(circle3dPoint(circle, pos1), 'ro') % % few points regularly spaced % drawPoint3d(circle3dPoint(circle, 10:10:40), '+') % % Draw point opposite to origin % drawPoint3d(circle3dPoint(circle, 180), 'k*') % % % See also % circles3d, circle3dPosition % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-21, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform pos=pos(:); % extract circle coordinates xc = circle(1); yc = circle(2); zc = circle(3); r = circle(4); theta = circle(5); phi = circle(6); psi = circle(7); % convert position to angle t = pos * pi / 180; % compute position on base circle x = r * cos(t); y = r * sin(t); z = zeros(length(pos),1); pt0 = [x y z]; % compute transformation from local basis to world basis trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); % compute points of transformed circle point = transformPoint3d(pt0, trans); matgeom-1.2.4/inst/geom3d/PaxHeaders/createRotationVectorPoint3d.m0000644000000000000000000000013214576357161022164 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/createRotationVectorPoint3d.m0000644000175000017500000000510714576357161023747 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function TFM = createRotationVectorPoint3d(A,B,P) %CREATEROTATIONVECTORPOINT3D Calculates the rotation between two vectors. % around a point % % TFM = createRotationVectorPoint3d(A,B,P) returns the transformation % to rotate the vector A in the direction of vector B around point P % % Example % A=-5+10.*rand(1,3); % B=-10+20.*rand(1,3); % P=-50+100.*rand(1,3); % ROT = createRotationVectorPoint3d(A,B,P); % C = transformVector3d(A,ROT); % figure('color','w'); hold on; view(3) % drawPoint3d(P,'k') % drawVector3d(P, A,'r') % drawVector3d(P, B,'g') % drawVector3d(P, C,'r') % % See also % transformPoint3d, createRotationVector3d % ------ % Author: oqilipo % E-mail: N/A % Created: 2017-08-07 % Copyright 2017-2023 P = reshape(P,3,1); % Translation from P to origin invtrans = [eye(3),-P; [0 0 0 1]]; % Rotation from A to B rot = createRotationVector3d(A, B); % Translation from origin to P trans = [eye(3),P; [0 0 0 1]]; % Combine TFM = trans*rot*invtrans; end matgeom-1.2.4/inst/geom3d/PaxHeaders/rotation3dAxisAndAngle.m0000644000000000000000000000013214576357161021062 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/rotation3dAxisAndAngle.m0000644000175000017500000000705014576357161022644 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [axis, theta] = rotation3dAxisAndAngle(mat) %ROTATION3DAXISANDANGLE Determine axis and angle of a 3D rotation matrix. % % [AXIS, ANGLE] = rotation3dAxisAndAngle(MAT) % Where MAT is a 4-by-4 matrix representing a rotation, computes the % rotation axis (containing the points that remain invariant under the % rotation), and the rotation angle around that axis. % AXIS has the format [DX DY DZ], constrained to unity, and ANGLE is the % rotation angle in radians. % % Note: this method use eigen vector extraction. It would be more precise % to use quaternions, see: % http://www.mathworks.cn/matlabcentral/newsreader/view_thread/160945 % % % Example % origin = [1 2 3]; % direction = [4 5 6]; % line = [origin direction]; % angle = pi/3; % rot = createRotation3dLineAngle(line, angle); % [axis angle2] = rotation3dAxisAndAngle(rot); % angle2 % angle2 = % 1.0472 % % See also % transforms3d, vectors3d, angles3d, eulerAnglesToRotation3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-08-11, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % extract the linear part of the rotation matrix A = mat(1:3, 1:3); % extract eigen values and eigen vectors [V, D] = eig(A - eye(3)); % we need the eigen vector corresponding to eigenvalue==1 [dummy, ind] = min(abs(diag(D)-1)); %#ok % extract corresponding eigen vector vector = V(:, ind)'; % compute rotation angle t = [A(3,2)-A(2,3) , A(1,3)-A(3,1) , A(2,1)-A(1,2)]; theta = atan2(dot(t, vector), trace(A)-1); % If angle is negative, invert both angle and vector direction if theta<0 theta = -theta; vector = -vector; end % try to get a point on the line % seems to work, but not sure about stability [V, D] = eig(mat-eye(4)); %#ok origin = V(1:3,4)'/V(4, 4); % create line corresponding to rotation axis axis = [origin vector]; matgeom-1.2.4/inst/geom3d/PaxHeaders/isTransform3d.m0000644000000000000000000000013214576357161017313 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/isTransform3d.m0000644000175000017500000000771114576357161021101 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function a = isTransform3d(trans, varargin) %ISTRANSFORM3D Check if input is a affine transformation matrix. % % A = isTransform3d(TRANS) where TRANS should be a transformation matrix. % The function accepts transformations given using the following formats: % [a b c] , [a b c j] , or [a b c j] % [d e f] [d e f k] [d e f k] % [g h i] [g h i l] [g h i l] % [0 0 0 1] % % If the transformation matrix should only contain rotation and % translation without reflection, scaling, shearing, ... set 'rotation' % to true. Default is false. % % Example % rot = ... % createRotationOx(rand*2*pi)*... % createRotationOy(rand*2*pi)*... % createRotationOx(rand*2*pi); % trans = rot*createTranslation3d(rand(1,3)); % isTransform3d(trans, 'rot', true) % % See also % composeTransforms3d, createBasisTransform3d, recenterTransform3d, % transformPoint3d % ------ % Author: oqilipo % E-mail: N/A % Created: 2018-07-08 % Copyright 2018-2023 narginchk(1,5) p = inputParser; logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addParameter(p,'rotation', 0, logParValidFunc); valTol = @(x) validateattributes(x,{'numeric'},{'scalar', '>=',eps(class(trans)), '<=',1}); addParameter(p,'tolerance', 1e-8, valTol); parse(p,varargin{:}); rotation = p.Results.rotation; tolerance = p.Results.tolerance; % eventually add null translation if size(trans, 2) == 3 trans = [trans zeros(size(trans, 1), 1)]; elseif size(trans, 2) < 3 || size(trans, 2) > 4 a=false; return end % eventually add normalization if size(trans, 1) == 3 trans = [trans;0 0 0 1]; elseif size(trans, 1) < 3 || size(trans, 1) > 4 a=false; return end a=true; % NaN is invalid if any(isnan(trans(:))) a=false; return end % Infinity is invalid if any(isinf(trans(:))) a=false; return end % trans(4,4) has to be a one if ~isequal(1, trans(4,4)) a = false; return end % trans(4,1:3) have to be zeros if ~isequal(zeros(1,3), trans(4,1:3)) a = false; return end if rotation % transpose(trans(1:3,1:3)) * trans(1:3,1:3) has to be eye(3) if any(abs(eye(3) - (trans(1:3,1:3)'*trans(1:3,1:3))) > tolerance) a = false; return; end % determinant of trans(1:3) has to be one if abs(1-det(trans)) > tolerance a = false; return end end end matgeom-1.2.4/inst/geom3d/PaxHeaders/randomPointInBox3d.m0000644000000000000000000000013214576357161020236 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/randomPointInBox3d.m0000644000175000017500000000542414576357161022023 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = randomPointInBox3d(box, N, varargin) %RANDOMPOINTINBOX3D Generate random point(s) within a 3D box. % % PTS = randomPointInBox3d(BOX) % Generate a random point within the 3D box BOX. The result is a 1-by-3 % row vector. % % PTS = randomPointInBox3d(BOX, N) % Generates N points within the box. The result is a N-by-3 array. % % BOX has the format: % BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. % % Example % % draw points within a box % box = [10 40 20 60 30 50]; % pts = randomPointInBox3d(box, 500); % figure(1); hold on; % drawBox3d(box); % drawPoint3d(pts, '.'); % axis('equal'); % axis([0 100 0 100 0 100]); % view(3); % % See also % points3d, boxes3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-27, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform if nargin < 2 N = 1; end % extract box bounds xmin = box(1); ymin = box(3); zmin = box(5); % compute size of box dx = box(2) - xmin; dy = box(4) - ymin; dz = box(6) - zmin; % compute point coordinates points = [rand(N, 1)*dx+xmin , rand(N, 1)*dy+ymin , rand(N, 1)*dz+zmin]; matgeom-1.2.4/inst/geom3d/PaxHeaders/isPointOnLine3d.m0000644000000000000000000000013214576357161017536 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/isPointOnLine3d.m0000644000175000017500000000614114576357161021320 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointOnLine3d(point, line, varargin) %ISPOINTONLINE3D Test if a 3D point belongs to a 3D line. % % B = isPointOnLine3d(POINT, LINE) % with POINT being [xp yp zp], and LINE being [x0 y0 z0 dx dy dz]. % Returns 1 if point lies on the line, 0 otherwise. % % If POINT is an N-by-3 array of points, B is a N-by-1 array of booleans. % % If LINE is a N-by-6 array of lines, B is a N-by-1 array of booleans. % % B = isPointOnLine3d(POINT, LINE, TOL) % Specifies the tolerance used for testing location on 3D line. % % See also % lines3d, distancePointLine3d, linePosition3d, isPointOnLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % size of inputs np = size(point,1); nl = size(line, 1); if np == 1 || nl == 1 || np == nl % test if lines are colinear, using norm of the cross product b = bsxfun(@rdivide, vectorNorm3d( ... crossProduct3d(bsxfun(@minus, line(:,1:3), point), line(:,4:6))), ... vectorNorm3d(line(:,4:6))) < tol; else % same test, but after reshaping arrays to manage difference of % dimensionality point = reshape(point, [np 1 3]); line = reshape(line, [1 nl 6]); b = bsxfun(@rdivide, vectorNorm3d( ... cross(bsxfun(@minus, line(:,:,1:3), point), line(ones(1,np),:,4:6), 3)), ... vectorNorm3d(line(:,:,4:6))) < tol; end matgeom-1.2.4/inst/geom3d/PaxHeaders/hypot3.m0000644000000000000000000000013214576357161016003 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/hypot3.m0000644000175000017500000000434014576357161017564 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function h = hypot3(dx, dy, dz) %HYPOT3 Diagonal length of a cuboidal 3D box . % % h = hypot3(a, b, c) % computes the quantity sqrt(a^2 + b^2 + c^2), by avoiding roundoff % errors. % % Example % % Compute diagonal of unit cube % hypot3(1, 1, 1) % ans = % 1.7321 % % % Compute more complicated diagonal % hypot3(3, 4, 5) % ans = % 7.0711 % % See also % hypot, vectorNorm3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-04-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform h = hypot(hypot(dx, dy), dz); matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectPlaneSphere.m0000644000000000000000000000013214576357161020704 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/intersectPlaneSphere.m0000644000175000017500000000737414576357161022477 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function circle = intersectPlaneSphere(plane, sphere) %INTERSECTPLANESPHERE Return intersection circle between a plane and a sphere. % % CIRC = intersectPlaneSphere(PLANE, SPHERE) % Returns the circle which is the intersection of the given plane % and sphere. % PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % SPHERE : [XS YS ZS RS] % CIRC : [XC YC ZC RC THETA PHI PSI] % [x0 y0 z0] is the origin of the plane, [dx1 dy1 dz1] and [dx2 dy2 dz2] % are two direction vectors, % [XS YS ZS] are coordinates of the sphere center, RS is the sphere % radius, % [XC YC ZC] are coordinates of the circle center, RC is the radius of % the circle, [THETA PHI] is the normal of the plane containing the % circle (THETA being the colatitude, and PHI the azimut), and PSI is a % rotation angle around the normal (equal to zero in this function, but % kept for compatibility with other functions). All angles are given in % degrees. % % See also % planes3d, spheres, circles3d, intersectLinePlane, intersectLineSphere % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-18 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % number of inputs of each type Ns = size(sphere, 1); Np = size(plane, 1); % unify data dimension if Ns ~= Np if Ns == 1 sphere = sphere(ones(Np, 1), :); elseif Np == 1 plane = plane(ones(Ns, 1), :); else error('data should have same length, or one data should have length 1'); end end % center of the spheres center = sphere(:,1:3); % radius of spheres if size(sphere, 2) == 4 Rs = sphere(:,4); else % assume default radius equal to 1 Rs = ones(size(sphere, 1), 1); end % projection of sphere center on plane -> gives circle center circle0 = projPointOnPlane(center, plane); % radius of circles d = distancePoints3d(center, circle0); Rc = sqrt(Rs.*Rs - d.*d); % normal of planes = normal of circles nor = planeNormal(plane); % convert to angles [theta, phi] = cart2sph2(nor(:,1), nor(:,2), nor(:,3)); psi = zeros(Np, 1); % create structure for circle k = 180 / pi; circle = [circle0 Rc [theta phi psi]*k]; matgeom-1.2.4/inst/geom3d/PaxHeaders/angles3d.m0000644000000000000000000000013214576357161016255 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/angles3d.m0000644000175000017500000000673614576357161020051 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function angles3d(varargin) %ANGLES3D Conventions for manipulating angles in 3D. % % The library uses both radians and degrees angles; % Results of angle computation between shapes usually returns angles in % radians. % Representation of 3D shapes use angles in degrees (easier to manipulate % and to save). % % Contrary to the plane, there are no oriented angles in 3D. Angles % between lines or between planes are comprised between 0 and PI. % % Spherical angles % Spherical angles are defined by 2 angles: % * THETA, the colatitude, representing angle with Oz axis (between 0 and % PI) % * PHI, the azimut, representing angle with Ox axis of horizontal % projection of the direction (between 0 and 2*PI) % % Spherical coordinates can be represented by THETA, PHI, and the % distance RHO to the origin. % % Euler angles % Some functions for creating rotations use Euler angles. They follow the % ZYX convention in the global reference system, that is eqivalent to the % XYZ convention ine a local reference system. % Euler angles are given by a triplet of angles [PHI THETA PSI] that % represents the succession of 3 rotations: % * rotation around X by angle PSI ("roll") % * rotation around Y by angle THETA ("pitch") % * rotation around Z by angle PHI ("yaw") % % In this library, euler angles are given in degrees. The functions that % use euler angles use the keyword 'Euler' in their name. % % % See also % cart2sph2, sph2cart2, cart2sph2d, sph2cart2d % anglePoints3d, angleSort3d, sphericalAngle, randomAngle3d % dihedralAngle, polygon3dNormalAngle, eulerAnglesToRotation3d % rotation3dAxisAndAngle, rotation3dToEulerAngles % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/geom3d/PaxHeaders/drawEllipsoid.m0000644000000000000000000000013214576357161017357 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawEllipsoid.m0000644000175000017500000001703714576357161021147 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipsoid(varargin) %DRAWELLIPSOID Draw a 3D ellipsoid. % % drawEllipsoid(ELLI) % Displays a 3D ellipsoid on current axis. ELLI is given by: % [XC YC ZC A B C PHI THETA PSI], % where (XC, YC, ZC) is the ellipsoid center, A, B and C are the half % lengths of the ellipsoid main axes, and PHI THETA PSI are Euler angles % representing ellipsoid orientation, in degrees. % % drawEllipsoid(..., 'drawEllipses', true) % Also displays the main 3D ellipses corresponding to XY, XZ and YZ % planes. % % % Example % figure; hold on; % drawEllipsoid([10 20 30 50 30 10 5 10 0]); % axis equal; % % figure; hold on; % elli = [10 20 30 50 30 10 5 10 0]; % drawEllipsoid(elli, 'FaceColor', 'r', ... % 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); % axis equal; % % See also % spheres, drawSphere, equivalentEllipsoid, ellipsoid, drawTorus, % drawCuboid % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Default values % number of meridians nPhi = 32; % number of parallels nTheta = 16; % settings for drawing ellipses drawEllipses = false; ellipseColor = 'k'; ellipseWidth = 1; drawAxes = false; axesColor = 'k'; axesWidth = 2; %% Extract input arguments % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % retrieve parameters of ellipsoid elli = varargin{1}; varargin(1) = []; % default set of options for drawing meshes options = {'FaceColor', 'g', 'linestyle', 'none'}; while length(varargin) > 1 switch lower(varargin{1}) case 'nphi' nPhi = varargin{2}; case 'ntheta' nTheta = varargin{2}; case 'drawellipses' drawEllipses = varargin{2}; case 'ellipsecolor' ellipseColor = varargin{2}; case 'ellipsewidth' ellipseWidth = varargin{2}; case 'drawaxes' drawAxes = varargin{2}; case 'axescolor' axesColor = varargin{2}; case 'axeswidth' axesWidth = varargin{2}; otherwise % assumes this is drawing option options = [options varargin(1:2)]; %#ok end varargin(1:2) = []; end %% Parse numerical inputs % Extract ellipsoid parameters xc = elli(:,1); yc = elli(:,2); zc = elli(:,3); a = elli(:,4); b = elli(:,5); c = elli(:,6); k = pi / 180; ellPhi = elli(:,7) * k; ellTheta = elli(:,8) * k; ellPsi = elli(:,9) * k; %% Coordinates computation % convert unit basis to ellipsoid basis sca = createScaling3d(a, b, c); rotZ = createRotationOz(ellPhi); rotY = createRotationOy(ellTheta); rotX = createRotationOx(ellPsi); tra = createTranslation3d([xc yc zc]); % concatenate transforms trans = tra * rotZ * rotY * rotX * sca; %% parametrisation of ellipsoid % spherical coordinates theta = linspace(0, pi, nTheta+1); phi = linspace(0, 2*pi, nPhi+1); % convert to cartesian coordinates sintheta = sin(theta); x = cos(phi') * sintheta; y = sin(phi') * sintheta; z = ones(length(phi),1) * cos(theta); % transform mesh vertices [x, y, z] = transformPoint3d(x, y, z, trans); %% parametrisation of ellipses if drawEllipses % parametrisation for ellipses nVertices = 120; t = linspace(0, 2*pi, nVertices+1); % XY circle xc1 = cos(t'); yc1 = sin(t'); zc1 = zeros(size(t')); % XZ circle xc2 = cos(t'); yc2 = zeros(size(t')); zc2 = sin(t'); % YZ circle xc3 = zeros(size(t')); yc3 = cos(t'); zc3 = sin(t'); % compute transformed ellipses [xc1, yc1, zc1] = transformPoint3d(xc1, yc1, zc1, trans); [xc2, yc2, zc2] = transformPoint3d(xc2, yc2, zc2, trans); [xc3, yc3, zc3] = transformPoint3d(xc3, yc3, zc3, trans); end %% parametrisation of main axis edges if drawAxes axesEndings = [-1 0 0; +1 0 0; 0 -1 0; 0 +1 0; 0 0 -1; 0 0 +1]; axesEndings = transformPoint3d(axesEndings, trans); end %% Drawing ellipseOptions = {'color', ellipseColor, 'LineWidth', ellipseWidth}; axesOptions = {'color', axesColor, 'LineWidth', axesWidth}; % Process output if nargout == 0 % no output: draw the ellipsoid surf(x, y, z, options{:}); if drawEllipses plot3(hAx, xc1, yc1, zc1, ellipseOptions{:}); plot3(hAx, xc2, yc2, zc2, ellipseOptions{:}); plot3(hAx, xc3, yc3, zc3, ellipseOptions{:}); end if drawAxes drawEdge3d(hAx, [axesEndings(1,:), axesEndings(2,:)], axesOptions{:}); drawEdge3d(hAx, [axesEndings(3,:), axesEndings(4,:)], axesOptions{:}); drawEdge3d(hAx, [axesEndings(5,:), axesEndings(6,:)], axesOptions{:}); end elseif nargout == 1 % one output: draw the ellipsoid and return handle varargout{1} = surf(x, y, z, options{:}); if drawEllipses plot3(hAx, xc1, yc1, zc1, ellipseOptions{:}); plot3(hAx, xc2, yc2, zc2, ellipseOptions{:}); plot3(hAx, xc3, yc3, zc3, ellipseOptions{:}); end elseif nargout == 3 % 3 outputs: return computed coordinates varargout{1} = x; varargout{2} = y; varargout{3} = z; if drawEllipses plot3(hAx, xc1, yc1, zc1, ellipseOptions{:}); plot3(hAx, xc2, yc2, zc2, ellipseOptions{:}); plot3(hAx, xc3, yc3, zc3, ellipseOptions{:}); end elseif nargout == 4 && drawEllipses % Also returns handles to ellipses varargout{1} = surf(hAx, x, y, z, options{:}); varargout{2} = plot3(hAx, xc1, yc1, zc1, ellipseOptions{:}); varargout{3} = plot3(hAx, xc2, yc2, zc2, ellipseOptions{:}); varargout{4} = plot3(hAx, xc3, yc3, zc3, ellipseOptions{:}); end matgeom-1.2.4/inst/geom3d/PaxHeaders/sph2cart2d.m0000644000000000000000000000013214576357161016531 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/sph2cart2d.m0000644000175000017500000000702014576357161020310 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = sph2cart2d(theta, phi, rho) %SPH2CART2D Convert spherical coordinates to cartesian coordinates in degrees. % % C = SPH2CART2D(THETA, PHI, RHO) % C = SPH2CART2D(THETA, PHI) (assume rho = 1) % C = SPH2CART2D(S) % [X, Y, Z] = SPH2CART2D(THETA, PHI, RHO); % % S = [theta phi rho] (spherical coordinate). % C = [X Y Z] (cartesian coordinate) % % The following convention is used: % THETA is the colatitude, in degrees, 0 for north pole, +180 degrees for % south pole, +90 degrees for points with z=0. % PHI is the azimuth, in degrees, defined as matlab cart2sph: angle from % Ox axis, counted counter-clockwise. % RHO is the distance of the point to the origin. % Discussion on choice for convention can be found at: % http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf % % Example % xyz = sph2cart2d(90, 0, 10) % xyz = % 10 0 0 % % xyz = sph2cart2d(90, 90, 10) % xyz = % 0 10 0 % % % check consistency with cart2sph2d % cart2sph2d(sph2cart2d(30, 40, 5)) % ans = % 30.0000 40.0000 5.0000 % % See also % angles3d, cart2sph2d, sph2cart2, eulerAnglesToRotation3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % Process input arguments if nargin == 1 phi = theta(:, 2); if size(theta, 2) > 2 rho = theta(:, 3); else rho = ones(size(phi)); end theta = theta(:, 1); elseif nargin == 2 rho = ones(size(theta)); end % conversion rz = rho .* sind(theta); x = rz .* cosd(phi); y = rz .* sind(phi); z = rho .* cosd(theta); % Process output arguments if nargout == 1 || nargout == 0 varargout{1} = [x, y, z]; else varargout{1} = x; varargout{2} = y; varargout{3} = z; end matgeom-1.2.4/inst/geom3d/PaxHeaders/createLine3d.m0000644000000000000000000000013214576357161017057 xustar0030 mtime=1710874225.106193375 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/createLine3d.m0000644000175000017500000001375514576357161020652 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = createLine3d(varargin) %CREATELINE3D Create a line with various inputs. % % Line is represented in a parametric form : [x0 y0 z0 dx dy dz] % x = x0 + t*dx % y = y0 + t*dy; % z = z0 + t*dz; % % % L = createLine3d(P1, P2); % Returns the line going through the two given points P1 and P2. % % L = createLine3d(X0, Y0, Z0, DX, DY, DZ); % Returns the line going through the point [x0, y0, z0], and with % direction vector given by [DX DY DZ]. % % L = createLine3d(P0, DX, DY, DZ); % Returns the line going through point P0 given by [x0, y0, z0] and with % direction vector given by [DX DY DZ]. % % L = createLine3d(THETA, PHI); % Create a line originated at (0,0) and with angles theta and phi. % % L = createLine3d(P0, THETA, PHI); % Create a line with direction given by theta and phi, and which contains % point P0. % % % Note : in all cases, parameters can be vertical arrays of the same % dimension. The result is then an array of lines, of dimensions [N*6]. % % See also % lines3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % NOTE : A 3d line can also be represented with a 1*7 array : % [x0 y0 z0 dx dy dz t]. % whith 't' being one of the following : % - t=0 : line is a singleton (x0,y0) % - t=1 : line is an edge segment, between points (x0,y0) and (x0+dx, % y0+dy). % - t=Inf : line is a Ray, originated from (x0,y0) and going to infinity % in the direction(dx,dy). % - t=-Inf : line is a Ray, originated from (x0,y0) and going to infinity % in the direction(-dx,-dy). % - t=NaN : line is a real straight line, and contains all points % verifying the above equation. % This seems to be a convenient way to represent uniformly all kind of % lines (including edges, rays, and even point). % % NOTE2 : Another form is the 1*8 array : % [x0 y0 z0 dx dy dz t1 t2]. % with t1 and t2 giving first and last position of the edge on the % supporting straight line, and with t2>t1. if length(varargin)==1 error('Wrong number of arguments in ''createLine'' '); elseif length(varargin)==2 % 2 input parameters. They can be : % - 2 points, then 2 arrays of 1*2 double. v1 = varargin{1}; v2 = varargin{2}; if size(v1, 2)==3 % first input parameter is first point, and second input is the % second point. line = [v1(:,1) v1(:,2) v1(:,3) v2(:,1)-v1(:,1) v2(:,2)-v1(:,2) v2(:,3)-v1(:,3)]; elseif size(v1, 2)==1 % first parameter is angle with the vertical % second parameter is horizontal angle with Ox axis theta = varargin{1}; phi = varargin{2}; sit = sin(theta); p0 = zeros([size(theta, 1) 3]); line = [p0 cos(phi)*sit sin(phi)*sit cos(theta)]; end elseif length(varargin)==3 % 3 input parameters : % first parameter is a point of the line % second parameter is angle with the vertical % third parameter is horizontal angle with Ox axis p0 = varargin{1}; theta = varargin{2}; phi = varargin{3}; if size(p0, 2)~=3 error('first argument should be a 3D point'); end sit = sin(theta); line = [p0 cos(phi)*sit sin(phi)*sit cos(theta)]; elseif length(varargin)==4 % 4 input parameters : p0 = varargin{1}; dx = varargin{2}; dy = varargin{3}; dz = varargin{4}; if size(p0, 2)~=3 error('first argument should be a 3D point'); end line = [p0 dx dy dz]; elseif length(varargin)==5 % 5 input parameters : % first parameter is distance of lin to origin % second parameter is angle with the vertical % third parameter is horizontal angle with Ox axis x0 = varargin{1}; y0 = varargin{1}; z0 = varargin{1}; theta = varargin{2}; phi = varargin{3}; sit = sin(theta); line = [x0 y0 z0 cos(phi)*sit sin(phi)*sit cos(theta)]; elseif length(varargin)==6 % 6 input parameters, given as separate arguments for x0, y0, z0 and % dx, dy and dz % (not very useful, but anyway...) x0 = varargin{1}; y0 = varargin{2}; z0 = varargin{3}; dx = varargin{4}; dy = varargin{5}; dz = varargin{6}; line = [x0 y0 z0 dx dy dz]; end matgeom-1.2.4/inst/geom3d/PaxHeaders/distanceLines3d.m0000644000000000000000000000013214576357161017571 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.106193375 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/distanceLines3d.m0000644000175000017500000001074014576357161021353 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [d, pt1, pt2] = distanceLines3d(line1, line2) %DISTANCELINES3D Minimal distance between two 3D lines. % % D = distanceLines3d(LINE1, LINE2); % Returns the distance between line LINE1 and the line LINE2, given as: % LINE1 : [x0 y0 z0 dx dy dz] (or M-by-6 array) % LINE2 : [x0 y0 z0 dx dy dz] (or N-by-6 array) % D : (positive) array M-by-N % % [D, PT1, PT2] = distanceLines3d(LINE1, LINE2); % Also returns the points located on LINE1 and LINE2 corresponding to the % shortest distance. % One should get the following: % distancePoints3d(PT1, PT2) - D == 0 % % % Example % line1 = [2 3 4 0 1 0]; % line2 = [8 8 8 0 0 1]; % distanceLines3d(line1, line2) % ans = % 6.0000 % % See also % lines3d, distancePoints3d % ------ % Authors: Brandon Baker, oqilipo, David Legland % E-mail: david.legland@inrae.fr % Created: 2011-01-19 % Copyright 2011-2023 % number of points of each array n1 = size(line1, 1); n2 = size(line2, 1); if nargout <= 1 % express line coordinate as n1-by-n2 arrays v1x = repmat(line1(:,4), [1 n2]); v1y = repmat(line1(:,5), [1 n2]); v1z = repmat(line1(:,6), [1 n2]); p1x = repmat(line1(:,1), [1 n2]); p1y = repmat(line1(:,2), [1 n2]); p1z = repmat(line1(:,3), [1 n2]); v2x = repmat(line2(:,4)', [n1 1]); v2y = repmat(line2(:,5)', [n1 1]); v2z = repmat(line2(:,6)', [n1 1]); p2x = repmat(line2(:,1)', [n1 1]); p2y = repmat(line2(:,2)', [n1 1]); p2z = repmat(line2(:,3)', [n1 1]); % calculates distance for each set of lines vcross = cross([v1x(:) v1y(:) v1z(:)], [v2x(:) v2y(:) v2z(:)]); num = ([p1x(:) p1y(:) p1z(:)] - [p2x(:) p2y(:) p2z(:)]) .* vcross; t1 = sum(num,2); d = abs(t1) ./ (vectorNorm3d(vcross) + eps); % returns result as n1-by-n2 array d = reshape(d, n1, n2); else % check input dimension, as we need to be able to match each pair of % lines if n1 ~= n2 error('geom3d:distanceLines3d:IllegalInputArgument', ... 'when output points are requested, number of lines should be the same'); end p1 = line1(:, 1:3); p2 = line2(:, 1:3); dp = p2 - p1; v1 = line1(:, 4:6); v2 = line2(:, 4:6); % compute distance vcross = cross(v1, v2, 2); num = dp .* vcross; t1 = sum(num, 2); d = abs(t1) ./ (vectorNorm3d(vcross) + eps); % precomputations a = dot(v1, v1, 2); b = dot(v1, v2, 2); e = dot(v2, v2, 2); den = a.*e - b.*b; % 0, if lines are parallel % vector between origin of both lines r = line1(:,1:3) - line2(:,1:3); % solve linear system c = dot(v1, r, 2); f = dot(v2, r, 2); s = (b .* f - c .* e) ./ den; t = (a .* f - c .* b) ./ den; % convert to coordinates of points on lines pt1 = line1(:,1:3) + v1 .* s; pt2 = line2(:,1:3) + v2 .* t; end matgeom-1.2.4/inst/geom3d/PaxHeaders/normalizeLine3d.m0000644000000000000000000000013214576357161017614 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/normalizeLine3d.m0000644000175000017500000000432514576357161021400 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line2 = normalizeLine3d(line) %NORMALIZELINE3D Normalizes the direction vector of a 3D line. % % LINE2 = normalizeVector3d(LINE); % Returns the normalization of the direction vector of the line, such % that ||LINE2(4:6)|| = 1. % % See also % normalizePlane, normalizeVector3d % % ------ % Author: oqilipo % E-mail: N/A % Created: 2020-03-13 % Copyright 2020-2023 isLine3d = @(x) validateattributes(x,{'numeric'},... {'nonempty','nonnan','real','finite','size',[nan,6]}); % Check if the line is valid p=inputParser; addRequired(p,'line',isLine3d) parse(p,line) line2 = line; line2(:,4:6) = normalizeVector3d(line2(:,4:6)); end matgeom-1.2.4/inst/geom3d/PaxHeaders/revolutionSurface.m0000644000000000000000000000013214576357161020274 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/revolutionSurface.m0000644000175000017500000001221514576357161022055 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = revolutionSurface(varargin) %REVOLUTIONSURFACE Create a surface of revolution from a planar curve. % % usage % [X Y Z] = revolutionSurface(C1, C2, N); % create the surface of revolution of parametrized function (xt, yt), % with N+1 equally spaced slices, around the Oz axis. % It assumed that C1 corresponds to the x coordinate, and that C2 % corresponds to the Oz coordinate. % % [X Y Z] = revolutionSurface(CURVE, N); % is the same, but generating curve is given in a single parameter CURVE, % which is a [Nx2] array of 2D points. % % [X Y Z] = revolutionSurface(..., THETA) % where THETA is a vector, uses values of THETA for computing revolution % angles. % % [X Y Z] = revolutionSurface(..., LINE); % where LINE is a 1x4 array, specifes the revolution axis in the % coordinate system of the curve. LINE is a row vector of 4 parameters, % containing [x0 y0 dx dy], where (x0,y0) is the origin of the line and % (dx,dy) is a direction vector of the line. % The resulting revolution surface still has Oz axis as symmetry axis. It % can be transformed using transformPoint3d function. % Surface can be displayed using : % H = surf(X, Y, Z); % H is a handle to the created patch. % % revolutionSurface(...); % by itself, directly shows the created patch. % % Example % % draws a piece of torus % circle = circleAsPolygon([10 0 3], 50); % [x y z] = revolutionSurface(circle, linspace(0, 4*pi/3, 50)); % surf(x, y, z); % axis equal; % % See also % surf, transformPoint3d, drawSphere, drawTorus, drawEllipsoid % surfature (on Matlab File Exchange) % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-09 % Copyright 2004-2023 INRA - CEPIA Nantes - MIAJ Jouy-en-Josas %% Initialisations % default values % use revolution using the full unit circle, decomposed into 24 angular % segments (thus, some vertices correspond to particular angles 30°, % 45°...) theta = linspace(0, 2*pi, 25); % use planar vertical axis as default revolution axis revol = [0 0 0 1]; % extract the generating curve var = varargin{1}; if size(var, 2)==1 xt = var; yt = varargin{2}; varargin(1:2) = []; else xt = var(:,1); yt = var(:,2); varargin(1) = []; end % extract optional parameters: angles, axis of revolution % parameters are identified from their length while ~isempty(varargin) var = varargin{1}; if length(var) == 4 % axis of rotation in the base plane revol = var; elseif length(var) == 1 % number of points -> create row vector of angles theta = linspace(0, 2*pi, var); else % use all specified angle values theta = var(:)'; end varargin(1) = []; end %% Create revolution surface % ensure length is enough m = length(xt); if m==1 xt = [xt xt]; end % ensure x and y are vertical vectors xt = xt(:); yt = yt(:); % transform xt and yt to replace in the reference of the revolution axis tra = createTranslation(-revol(1:2)); rot = createRotation(pi/2 - lineAngle(revol)); [xt, yt] = transformPoint(xt, yt, tra*rot); % compute surface vertices x = xt * cos(theta); y = xt * sin(theta); z = yt * ones(size(theta)); %% Process output arguments % format output depending on how many output parameters are required if nargout == 0 % draw the revolution surface surf(x, y, z); elseif nargout == 1 % draw the surface and return a handle to the shown structure h = surf(x, y, z); varargout{1} = h; elseif nargout == 3 % return computed mesh varargout = {x, y, z}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawPlatform.m0000644000000000000000000000013214576357161017217 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawPlatform.m0000644000175000017500000000772114576357161021006 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawPlatform(varargin) %DRAWPLATFORM Draw a rectangular platform with a given size. % % drawPlatform(PLANE, SIZ) draws a rectangular platform with the % dimensions specified by SIZ. If SIZ contains only one value instead of % two the platform will be quadratic. % % drawPlatform(...,'PropertyName',PropertyValue,...) sets the value of % the specified patch property. Multiple property values can be set with % a single statement. See function patch for details. % % drawPlane3d(AX,...) plots into AX instead of GCA. % % H = drawPlatform(...) returns a handle H to the patch object. % % Example % % p0 = [1 2 3]; % v1 = [1 0 1]; % v2 = [0 -1 1]; % plane = [p0 v1 v2]; % axis([-10 10 -10 10 -10 10]); % drawPlatform(plane, [7,3]) % set(gcf, 'renderer', 'zbuffer'); % % See also % planes3d, createPlane, patch % ------ % Author: oqilipo % E-mail: N/A % Created: 2018-08-09 % Copyright 2018-2023 %% Parse inputs % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % retrieve plane and size plane = varargin{1}; siz = varargin{2}; varargin(1:2) = []; % parse optional arguments p = inputParser; addRequired(p, 'plane', @(x) size(x,1)==1 && isPlane(x)) addRequired(p, 'siz', @(x)validateattributes(x,{'numeric'},... {'size',[1, nan],'positive','nonnan','real','finite'})) parse(p, plane, siz) if ~isempty(varargin) if length(varargin) == 1 if isstruct(varargin{1}) % if options are specified as struct, need to convert to % parameter name-value pairs varargin = [fieldnames(varargin{1}) struct2cell(varargin{1})]'; varargin = varargin(:)'; else % if option is a single argument, assume it corresponds to % plane color varargin = {'FaceColor', varargin{1}}; end end else % default face color varargin = {'FaceColor', 'm'}; end if numel(siz) == 1 siz(2) = siz(1); end %% Algorithm % Calculate vertex points of the platform pts(1,:) = planePoint(plane, [1,1]*0.5.*siz); pts(2,:) = planePoint(plane, [1,-1]*0.5.*siz); pts(3,:) = planePoint(plane, [-1,-1]*0.5.*siz); pts(4,:) = planePoint(plane, [-1,1]*0.5.*siz); pf.vertices = pts; pf.faces = [1 2 3 4]; % Draw the patch h = patch(hAx, pf, varargin{:}); %% Parse outputs % Return handle to plane if needed if nargout > 0 varargout{1} = h; end end matgeom-1.2.4/inst/geom3d/PaxHeaders/fitCircle3d.m0000644000000000000000000000013214576357161016710 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/fitCircle3d.m0000644000175000017500000001562214576357161020476 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [fittedCircle, circleNormal, residuals] = fitCircle3d(pts, varargin) %FITCIRCLE3D Fit a 3D circle to a set of points. % % [FITTEDCIRCLE, CIRCLENORMAL, RESIDUALS] = fitCircle3d(PTS) % % Example % % points on a 2d circle with noise % nop = randi([5 50],1,1); % radius = randi([5 25],1,1); % points2d = circleToPolygon([0 0 radius], nop); % points2d(1,:) = []; % points2d = points2d + rand(size(points2d)); % points2d(:,3)=rand(length(nop),1); % % apply random rotation and translation % [theta, phi] = randomAngle3d; % theta = rad2deg(theta); % phi = rad2deg(phi); % tfm = eulerAnglesToRotation3d(phi, theta, 0); % trans = randi([-250 250],3,1); % tfm(1:3,4)=trans; % points3d = awgn(transformPoint3d(points2d, tfm),1); % % fit 3d circle % [fittedCircle, circleNormal] = fitCircle3d(points3d); % % plot 3d points and 3d circle % figure('Color','w'); hold on; axis equal tight; view(3); % xlabel('X');ylabel('Y');zlabel('Z'); % drawPoint3d(points3d) % drawCircle3d(fittedCircle, 'k') % drawVector3d(fittedCircle(1:3), circleNormal*fittedCircle(4)) % % See also % circle3dOrigin, circle3dPosition, circle3dPoint, intersectPlaneSphere % drawCircle3d, drawCircleArc3d, drawEllipse3d % ------ % Authors: oqilipo % E-mail: N/A % Created: 2017-05-09 % Copyright 2017-2023 parser = inputParser; addRequired(parser, 'pts', @(x) validateattributes(x, {'numeric'},... {'ncols',3,'real','finite','nonnan'})); addOptional(parser,'verbose',true,@islogical); parse(parser,pts,varargin{:}); pts = parser.Results.pts; verbose = parser.Results.verbose; % Mean of all points meanPoint = mean(pts,1); % Center points by subtracting the meanPoint centeredPoints = pts - repmat(meanPoint,size(pts,1),1); % Project 3D data to a plane [~,~,V]=svd(centeredPoints); tfmPoints = transformPoint3d(centeredPoints, V'); % Fit a circle to the points in the xy-plane circleParamter = CircleFitByTaubin(tfmPoints(:,1:2), verbose); center2d = circleParamter(1:2); radius=circleParamter(3); center3d = transformPoint3d([center2d, 0], [inv(V'), meanPoint']); circleNormal = V(:,3)'; [theta, phi, ~] = cart2sph2(circleNormal); fittedCircle = [center3d radius rad2deg(theta) rad2deg(phi) 0]; % Residuals residuals = radius - distancePoints(tfmPoints(:,1:2),center2d); end % Circle Fit (Taubin method) % version 1.0 (2.24 KB) by Nikolai Chernov % http://www.mathworks.com/matlabcentral/fileexchange/22678 function Par = CircleFitByTaubin(XY, varargin) %__________________________________________________________________________ % % Circle fit by Taubin % G. Taubin, "Estimation Of Planar Curves, Surfaces And Nonplanar % Space Curves Defined By Implicit Equations, With % Applications To Edge And Range Image Segmentation", % IEEE Trans. PAMI, Vol. 13, pages 1115-1138, (1991) % % Input: XY(n,2) is the array of coordinates of n points x(i)=XY(i,1), y(i)=XY(i,2) % % Output: Par = [a b R] is the fitting circle: % center (a,b) and radius R % % Note: this fit does not use built-in matrix functions (except "mean"), % so it can be easily programmed in any programming language % %__________________________________________________________________________ parser = inputParser; addRequired(parser, 'XY', @(x) validateattributes(x, {'numeric'},... {'ncols',2,'real','finite','nonnan'})); addOptional(parser,'verbose',true,@islogical); parse(parser,XY,varargin{:}); XY=parser.Results.XY; verbose = parser.Results.verbose; n = size(XY,1); % number of data points centroid = mean(XY); % the centroid of the data set % computing moments (note: all moments will be normed, i.e. divided by n) Mxx = 0; Myy = 0; Mxy = 0; Mxz = 0; Myz = 0; Mzz = 0; for i=1:n Xi = XY(i,1) - centroid(1); % centering data Yi = XY(i,2) - centroid(2); % centering data Zi = Xi*Xi + Yi*Yi; Mxy = Mxy + Xi*Yi; Mxx = Mxx + Xi*Xi; Myy = Myy + Yi*Yi; Mxz = Mxz + Xi*Zi; Myz = Myz + Yi*Zi; Mzz = Mzz + Zi*Zi; end Mxx = Mxx/n; Myy = Myy/n; Mxy = Mxy/n; Mxz = Mxz/n; Myz = Myz/n; Mzz = Mzz/n; % computing the coefficients of the characteristic polynomial Mz = Mxx + Myy; Cov_xy = Mxx*Myy - Mxy*Mxy; A3 = 4*Mz; A2 = -3*Mz*Mz - Mzz; A1 = Mzz*Mz + 4*Cov_xy*Mz - Mxz*Mxz - Myz*Myz - Mz*Mz*Mz; A0 = Mxz*Mxz*Myy + Myz*Myz*Mxx - Mzz*Cov_xy - 2*Mxz*Myz*Mxy + Mz*Mz*Cov_xy; A22 = A2 + A2; A33 = A3 + A3 + A3; xnew = 0; ynew = 1e+20; epsilon = 1e-12; IterMax = 20; % Newton's method starting at x=0 for iter=1:IterMax yold = ynew; ynew = A0 + xnew*(A1 + xnew*(A2 + xnew*A3)); if abs(ynew) > abs(yold) if verbose disp('Newton-Taubin goes wrong direction: |ynew| > |yold|'); end xnew = 0; break; end Dy = A1 + xnew*(A22 + xnew*A33); xold = xnew; xnew = xold - ynew/Dy; if (abs((xnew-xold)/xnew) < epsilon), break, end if (iter >= IterMax) if verbose disp('Newton-Taubin will not converge'); end xnew = 0; end if (xnew<0.) if verbose fprintf(1,'Newton-Taubin negative root: x=%f\n',xnew); end xnew = 0; end end % computing the circle parameters DET = xnew*xnew - xnew*Mz + Cov_xy; Center = [Mxz*(Myy-xnew)-Myz*Mxy , Myz*(Mxx-xnew)-Mxz*Mxy]/DET/2; Par = [Center+centroid , sqrt(Center*Center'+Mz)]; end matgeom-1.2.4/inst/geom3d/PaxHeaders/transformPoint3d.m0000644000000000000000000000013214576357161020031 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/transformPoint3d.m0000644000175000017500000001317014576357161021613 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = transformPoint3d(pts, transfo, varargin) %TRANSFORMPOINT3D Transform a point with a 3D affine transform. % % PT2 = transformPoint3d(PT1, TRANS); % PT2 = transformPoint3d(X1, Y1, Z1, TRANS); % where PT1 has the form [xp yp zp], and TRANS is a 3-by-3, 3-by-4, or % 4-by-4 matrix, returns the point transformed according to the affine % transform specified by TRANS. % % The function accepts transforms given using the following formats: % [a b c] , [a b c j] , or [a b c j] % [d e f] [d e f k] [d e f k] % [g h i] [g h i l] [g h i l] % [0 0 0 1] % % PT2 = transformPoint3d(PT1, TRANS) % also work when PT1 is a N-by-3-by-M-by-P-by-ETC array of double. In % this case, PT2 has the same size as PT1. % % PT2 = transformPoint3d(X1, Y1, Z1, TRANS); % also work when X1, Y1 and Z1 are 3 arrays with the same size. In this % case, PT2 will be a 1-by-3 cell containing {X Y Z} outputs of size(X1). % % [X2, Y2, Z2] = transformPoint3d(...); % returns the result in 3 different arrays the same size as the input. % This form can be useful when used with functions like meshgrid or warp. % % MESH2 = transformPoint3d(MESH, TRANS) % transforms the field 'vertices' of the struct MESH and returns the same % struct with the transformed vertices. % (It is recommended to use the function 'transformMesh', within the % "meshes3d" module). % % See also % points3d, transforms3d, transformMesh, createTranslation3d % createRotationOx, createRotationOy, createRotationOz, createScaling % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% Parse input arguments % Check special case: if first argument is a struct with a field named % 'vertices', then the output will be the same struct, but with the % transformed vertices. if nargin == 2 && isstruct(pts) && isfield(pts, 'vertices') mesh = pts; mesh.vertices = transformPoint3d(mesh.vertices, transfo); varargout = {mesh}; return; end % Parse x, y, and z coordinates of input points from input arguments if nargin == 2 % Point coordinates are given in a single N-by-3-by-M-by-etc argument. % Preallocate x, y, and z to size N-by-1-by-M-by-etc, then fill them in dim = size(pts); dim(2) = 1; [x, y, z] = deal(zeros(dim, class(pts))); x(:) = pts(:,1,:); y(:) = pts(:,2,:); z(:) = pts(:,3,:); elseif nargin == 4 % Point coordinates are given in 3 different arrays x = pts; y = transfo; z = varargin{1}; transfo = varargin{2}; dim = size(x); else error('MatGeom:geom3d:WrongInputArgumentNumber', ... 'Requires number of input arguments to be either 2 or 4'); end %% Process transformation matrix % extract the linear and the translation parts of the matrix linear = transfo(1:3, 1:3)'; trans = [0 0 0]; if size(transfo, 2) > 3 trans = transfo(1:3, 4)'; end %% Main processing % convert coordinates try % vectorial processing, if there is enough memory. % same as: % res = (transfo * [x(:) y(:) z(:) ones(NP, 1)]')'; res = bsxfun(@plus, [x(:) y(:) z(:)] * linear, trans); % Back-fill x,y,z with new result (saves calling costly reshape()) x(:) = res(:,1); y(:) = res(:,2); z(:) = res(:,3); catch ME disp(ME.message) % process each point one by one, writing in existing array NP = numel(x); for i = 1:NP res = [x(i) y(i) z(i)] * linear + trans; x(i) = res(1); y(i) = res(2); z(i) = res(3); end end % process output arguments if nargout <= 1 % results are stored in a unique array if length(dim) > 2 && dim(2) > 1 warning('geom3d:shapeMismatch',... 'Shape mismatch: Non-vector xyz input should have multiple x,y,z output arguments. Cell {x,y,z} returned instead.') varargout{1} = {x,y,z}; else varargout{1} = [x y z]; end elseif nargout == 3 % results are returned in three array with same size. varargout = {x, y, z}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/private0000644000000000000000000000013214576357160015773 xustar0030 mtime=1710874224.406194044 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/private/0000755000175000017500000000000014576357160017630 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/geom3d/private/PaxHeaders/localToGlobal3d.m0000644000000000000000000000013214576357161021174 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/private/localToGlobal3d.m0000644000175000017500000001040514576357161022754 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = localToGlobal3d(varargin) %LOCALTOGLOBAL3D Transformation matrix from local to global coordinate system. % % TRANS = localToGlobal3d(CENTER, THETA, PHI, PSI) % Compute the transformation matrix from a local (or modelling) % coordinate system to the global (or world) coordinate system. % This is a low-level function, used by several drawing functions. % % The transform is defined by: % - CENTER: the position of the local origin into the world coordinate % system % - THETA: colatitude, defined as the angle with the Oz axis (between 0 % and 180 degrees), positive in the direction of the of Oy axis. % - PHI: azimut, defined as the angle of the normal with the Ox axis, % between 0 and 360 degrees % - PSI: intrinsic rotation, corresponding to the rotation of the object % around the direction vector, between 0 and 360 degrees % % The resulting transform is obtained by applying (in that order): % - Rotation by PSI around the Z-axis % - Rotation by THETA around the Y-axis % - Rotation by PHI around the Z-axis % - Translation by vector CENTER % This corresponds to Euler ZYZ rotation, using angles PHI, THETA and % PSI. % % The 'eulerAnglesToRotation3d' function may better suit your needs as % it is more 'natural'. % % Example % localToGlobal3d % % See also % transforms3d, eulerAnglesToRotation3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-19, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % extract the components of the transform if nargin == 1 % all components are bundled in the first argument var = varargin{1}; center = var(1:3); theta = var(4); phi = var(5); psi = 0; if length(var) > 5 psi = var(6); end elseif nargin == 4 % arguments = center, then the 3 angles center = varargin{1}; theta = varargin{2}; phi = varargin{3}; psi = varargin{4}; elseif nargin > 4 % center is given in 3 arguments, then 3 angles center = [varargin{1} varargin{2} varargin{3}]; theta = varargin{4}; phi = varargin{5}; psi = 0; if nargin > 5 psi = varargin{6}; end end % conversion from degrees to radians k = pi / 180; % rotation around normal vector axis rot1 = createRotationOz(psi * k); % colatitude rot2 = createRotationOy(theta * k); % longitude rot3 = createRotationOz(phi * k); % shift center tr = createTranslation3d(center); % create final transform by concatenating transforms trans = tr * rot3 * rot2 * rot1; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawBox3d.m0000644000000000000000000000013214576357161016412 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawBox3d.m0000644000175000017500000001037514576357161020200 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawBox3d(box, varargin) %DRAWBOX3D Draw a 3D box defined by coordinate extents. % % drawBox3d(BOX); % Draw a box defined by its coordinate extents: % BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. % The function draws only the outline edges of the box. % % Example % % Draw bounding box of a cubeoctehedron % [v e f] = createCubeOctahedron; % box3d = boundingBox3d(v); % figure; hold on; % drawMesh(v, f); % drawBox3d(box3d); % set(gcf, 'renderer', 'opengl') % axis([-2 2 -2 2 -2 2]); % view(3) % % See also % boxes3d, boundingBox3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-02-22 % Copyright 2010-2023 INRA - TPV URPOI - BIA IMASTE % Parse and check inputs isBox3d = @(x) validateattributes(x,{'numeric'},... {'nonempty','nonnan','real','finite','size',[nan,6]}); defOpts.Color = 'b'; [hAx, box, varargin] = ... parseDrawInput(box, isBox3d, 'line', defOpts, varargin{:}); % box limits xmin = box(:,1); xmax = box(:,2); ymin = box(:,3); ymax = box(:,4); zmin = box(:,5); zmax = box(:,6); % save hold state holdState = ishold(hAx); hold(hAx, 'on'); nBoxes = size(box, 1); gh = zeros(nBoxes,1); for i = 1:nBoxes % lower face (z=zmin) sh(1) = drawEdge3d(hAx, [xmin(i) ymin(i) zmin(i) xmax(i) ymin(i) zmin(i)], varargin{:}); sh(2) = drawEdge3d(hAx, [xmin(i) ymin(i) zmin(i) xmin(i) ymax(i) zmin(i)], varargin{:}); sh(3) = drawEdge3d(hAx, [xmax(i) ymin(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); sh(4) = drawEdge3d(hAx, [xmin(i) ymax(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); % front face (y=ymin) sh(5) = drawEdge3d(hAx, [xmin(i) ymin(i) zmin(i) xmin(i) ymin(i) zmax(i)], varargin{:}); sh(6) = drawEdge3d(hAx, [xmax(i) ymin(i) zmin(i) xmax(i) ymin(i) zmax(i)], varargin{:}); sh(7) = drawEdge3d(hAx, [xmin(i) ymin(i) zmax(i) xmax(i) ymin(i) zmax(i)], varargin{:}); % left face (x=xmin) sh(8) = drawEdge3d(hAx, [xmin(i) ymax(i) zmin(i) xmin(i) ymax(i) zmax(i)], varargin{:}); sh(9) = drawEdge3d(hAx, [xmin(i) ymin(i) zmax(i) xmin(i) ymax(i) zmax(i)], varargin{:}); % the last 3 remaining edges sh(10) = drawEdge3d(hAx, [xmin(i) ymax(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); sh(11) = drawEdge3d(hAx, [xmax(i) ymax(i) zmin(i) xmax(i) ymax(i) zmax(i)], varargin{:}); sh(12) = drawEdge3d(hAx, [xmax(i) ymin(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); gh(i) = hggroup(hAx); set(sh, 'Parent', gh(i)) end % restore hold state if ~holdState hold(hAx, 'off'); end if nargout > 0 varargout = {gh}; end matgeom-1.2.4/inst/geom3d/PaxHeaders/fitEllipse3d.m0000644000000000000000000000013214576357161017104 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/fitEllipse3d.m0000644000175000017500000002672514576357161020700 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [fittedEllipse3d, TFM3D] = fitEllipse3d(points, varargin) %FITELLIPSE3D Fit an ellipse to a set of points. % % FITTEDELLIPSE3D = fitEllipse3d(POINTS) returns the 3D ellipse fitted to % a set of 3D points. % % Example % % Create 2D ellipse % n=randi([10,100]); % a=randi([30,50]); b=randi([5,25]); % [x, y] = ellipseToPolygon([0 0 a b 0 ], n); % % 3D and add some noise % points = [x, y, zeros(n,1)]; % points=points+(-1+2*rand(n,3)); % % Create a random transformation % center=-100+200*rand(1,3); % phi=randi([-180,180]); theta=randi([-180,180]); psi=randi([-180,180]); % TFM=eulerAnglesToRotation3d(phi, theta, psi, 'ZYZ'); TFM(1:3,4)=center'; % points = transformPoint3d(points, TFM); % % Fit ellipse % [fE, fTFM] = fitEllipse3d(points, 'vis', true); % % Plot reconstructed ellipse % [fx, fy] = ellipseToPolygon([0 0 fE(4), fE(5) 0 ], n); % fpoints = transformPoint3d([fx, fy, zeros(n,1)], fTFM); % drawEllipse3d(fE,'k') % % See also % drawEllipse3d, ellipseToPolygon % % Source % Nested functions are part of the quadfit toolbox by Levente Hunyadi % https://mathworks.com/matlabcentral/fileexchange/45356 % ------ % Author: oqilipo % E-mail: N/A % Created: 2017-08-11 % Copyright 2017-2023 parser = inputParser; addRequired(parser, 'points', @(x) validateattributes(x, {'numeric'},... {'ncols',3,'real','finite','nonnan'})); addOptional(parser,'visualization',false,@islogical); parse(parser,points,varargin{:}); points=parser.Results.points; % Mean of all points meanPoint = mean(points,1); % Center points around origin centeredPoints = bsxfun(@minus, points, meanPoint); % Transformation to x-y plane [~,~,R]=svd(centeredPoints); tfmPoints = transformPoint3d(centeredPoints, R'); % Fit ellipse parEllipse = ellipsefit_direct(tfmPoints(:,1),tfmPoints(:,2)); % Convert to explicit form [X, Y, A, B, phi2D] = ellipse_im2ex(parEllipse); % Transform to fitted 2d ellipse TFM2D = createRotationOz(phi2D); TFM2D(1:3,4)=[X; Y; 0]; % Transformation back to 3d space TFM3D = [inv(R'), meanPoint'; 0 0 0 1]*TFM2D; % Extract translation center = TFM3D(1:3,4)'; % Extract rotation TFM3D_ROT=TFM3D(1:3,1:3); % Convert to euler angles [PHI, THETA, PSI] = rotation3dToEulerAngles(TFM3D_ROT,'ZYZ'); % Test if psi is correct TFM3D_test = eulerAnglesToRotation3d(PHI, THETA, PSI,'ZYZ'); if ~all(all(ismembertol(TFM3D_test(1:3,1:3), TFM3D_ROT))) PSI=-1*PSI; end % matGeom format fittedEllipse3d=[center A B THETA PHI PSI]; %% Visualization if parser.Results.visualization figure('Color','w'); axis equal tight; hold on; view(3) xlabel('x'); ylabel('y'); zlabel('z'); % Input points scatter3(points(:,1),points(:,2),points(:,3), 'r', 'filled') % Centered points scatter3(centeredPoints(:,1),centeredPoints(:,2),centeredPoints(:,3), 'g', 'filled') % SVD points scatter3(tfmPoints(:,1),tfmPoints(:,2),tfmPoints(:,3), 'b', 'filled') % planeProps.FaceAlpha=0.25; % planeProps.FaceColor='b'; % drawPlane3d([0 0 0 1 0 0 0 1 0],planeProps) % Fitted ellipse drawEllipse3d(fittedEllipse3d) end %% Nested functions function p = ellipsefit_direct(x,y) % Direct least squares fitting of ellipses. % % Input arguments: % x,y; % x and y coodinates of 2D points % % Output arguments: % p: % a 6-parameter vector of the algebraic ellipse fit with % p(1)*x^2 + p(2)*x*y + p(3)*y^2 + p(4)*x + p(5)*y + p(6) = 0 % % References: % Andrew W. Fitzgibbon, Maurizio Pilu and Robert B. Fisher, "Direct Least % Squares Fitting of Ellipses", IEEE Trans. PAMI 21, 1999, pp476-480. % Copyright 2011 Levente Hunyadi narginchk(2,2); validateattributes(x, {'numeric'}, {'real','nonempty','vector'}); validateattributes(y, {'numeric'}, {'real','nonempty','vector'}); x = x(:); y = y(:); % normalize data mx = mean(x); my = mean(y); sx = (max(x)-min(x))/2; sy = (max(y)-min(y))/2; smax = max(sx,sy); sx = smax; sy = smax; x = (x-mx)/sx; y = (y-my)/sy; % build design matrix D = [ x.^2 x.*y y.^2 x y ones(size(x)) ]; % build scatter matrix S = D'*D; % build 6x6 constraint matrix C = zeros(6,6); C(1,3) = -2; C(2,2) = 1; C(3,1) = -2; if 1 p = ellipsefit_robust(S,-C); elseif 0 % solve eigensystem [gevec, geval] = eig(S,C); geval = diag(geval); % extract eigenvector corresponding to unique negative (nonpositive) eigenvalue p = gevec(:,geval < 0 & ~isinf(geval)); r = geval(geval < 0 & ~isinf(geval)); elseif 0 % formulation as convex optimization problem gamma = 0; %#ok<*UNRCH> cvx_begin sdp variable('gamma'); variable('lambda'); maximize(gamma); lambda >= 0; %#ok<*VUNUS> %[ S + lambda*C, zeros(size(S,1),1) ... %; zeros(1,size(S,2)), lambda - gamma ... %] >= 0; S + lambda*C >= 0; lambda - gamma >= 0; cvx_end % recover primal optimal values from dual [evec, eval] = eig(S + lambda*C); eval = diag(eval); [~,ix] = min(abs(eval)); p = evec(:,ix); end % unnormalize p(:) = ... [ p(1)*sy*sy ... ; p(2)*sx*sy ... ; p(3)*sx*sx ... ; -2*p(1)*sy*sy*mx - p(2)*sx*sy*my + p(4)*sx*sy*sy ... ; -p(2)*sx*sy*mx - 2*p(3)*sx*sx*my + p(5)*sx*sx*sy ... ; p(1)*sy*sy*mx*mx + p(2)*sx*sy*mx*my + p(3)*sx*sx*my*my - p(4)*sx*sy*sy*mx - p(5)*sx*sx*sy*my + p(6)*sx*sx*sy*sy ... ]; p = p ./ norm(p); end function p = ellipsefit_robust(R, Q) % Constrained ellipse fit by solving a modified eigenvalue problem. % The method is numerically stable. % % Input arguments: % R: % positive semi-definite data covariance matrix % Q: % constraint matrix in parameters x^2, xy, y^2, x, y and 1. % % Output arguments: % p: % estimated parameters (taking constraints into account) % References: % Radim Halir and Jan Flusser, "Numerically stable direct least squares fitting of % ellipses", 1998 % Copyright 2012 Levente Hunyadi validateattributes(R, {'numeric'}, {'real','2d','size',[6,6]}); validateattributes(Q, {'numeric'}, {'real','2d','size',[6,6]}); % check that constraint matrix has all zeros except in upper left block assert( nnz(Q(4:6,:)) == 0 ); assert( nnz(Q(:,4:6)) == 0 ); S1 = R(1:3,1:3); % quadratic part of the scatter matrix S2 = R(1:3,4:6); % combined part of the scatter matrix S3 = R(4:6,4:6); % linear part of the scatter matrix T = -(S3 \ S2'); % for getting a2 from a1 M = S1 + S2 * T; % reduced scatter matrix M = Q(1:3,1:3) \ M; % premultiply by inv(C1), e.g. M = [M(3,:)./2 ; -M(2,:) ; M(1,:)./2] for an ellipse [evec,~] = eig(M); % solve eigensystem % evaluate a'*C*a, e.g. cond = 4 * evec(1,:).*evec(3,:) - evec(2,:).^2 for an ellipse cond = zeros(1,size(evec,2)); for k = 1 : numel(cond) cond(k) = evec(:,k)'*Q(1:3,1:3)*evec(:,k); end % eigenvector for minimum positive eigenvalue evec = evec(:,cond > 0); cond = cond(cond > 0); [~,ix] = min(cond); p1 = evec(:,ix); % eigenvector for minimum positive eigenvalue % ellipse coefficients p = [p1 ; T * p1]; end function varargout = ellipse_im2ex(varargin) % Cast ellipse defined with implicit parameter vector to explicit form. % % Copyright 2011 Levente Hunyadi if nargin > 1 narginchk(6,6); for k = 1 : 6 validateattributes(varargin{k}, {'numeric'}, {'real','scalar'}); end [c1,c2,a,b,phi] = ellipse_explicit(varargin{:}); else narginchk(1,1); p = varargin{1}; validateattributes(p, {'numeric'}, {'real','vector'}); p = p(:); validateattributes(p, {'numeric'}, {'size',[6 1]}); [c1,c2,a,b,phi] = ellipse_explicit(p(1), 0.5*p(2), p(3), 0.5*p(4), 0.5*p(5), p(6)); end if nargout > 1 varargout = num2cell([c1,c2,a,b,phi]); else varargout{1} = [c1,c2,a,b,phi]; end function [c1,c2,semia,semib,phi] = ellipse_explicit(a,b,c,d,f,g) % Cast ellipse defined with explicit parameter vector to implicit form. % helper quantities N = 2*(a*f^2+c*d^2+g*b^2-2*b*d*f-a*c*g); D = b^2-a*c; S = realsqrt((a-c)^2+4*b^2); % semi-axes ap = realsqrt( N/(D*(S-(a+c))) ); bp = realsqrt( N/(D*(-S-(a+c))) ); semia = max(ap,bp); semib = min(ap,bp); % center c1 = (c*d-b*f)/D; c2 = (a*f-b*d)/D; % angle of tilt if b ~= 0 if abs(a) < abs(c) phi = 0.5*acot((a-c)/(2*b)); else phi = 0.5*pi+0.5*acot((a-c)/(2*b)); end else if abs(a) < abs(c) phi = 0; else % a > c phi = 0.5*pi; end end end end end matgeom-1.2.4/inst/geom3d/PaxHeaders/createRotation3dLineAngle.m0000644000000000000000000000013214576357161021546 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/createRotation3dLineAngle.m0000644000175000017500000000553514576357161023336 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function mat = createRotation3dLineAngle(line, theta) %CREATEROTATION3DLINEANGLE Create rotation around a line by an angle theta. % % MAT = createRotation3dLineAngle(LINE, ANGLE) % % Example % origin = [1 2 3]; % direction = [4 5 6]; % line = [origin direction]; % angle = pi/3; % rot = createRotation3dLineAngle(line, angle); % [axis angle2] = rotation3dAxisAndAngle(rot); % angle2 % angle2 = % 1.0472 % % See also % transforms3d, rotation3dAxisAndAngle, rotation3dToEulerAngles, % eulerAnglesToRotation3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-08-11, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % determine rotation center and direction center = [0 0 0]; if size(line, 2)==6 center = line(1:3); vector = line(4:6); else vector = line; end % normalize vector v = normalizeVector3d(vector); % compute projection matrix P and anti-projection matrix P = v'*v; Q = [0 -v(3) v(2) ; v(3) 0 -v(1) ; -v(2) v(1) 0]; I = eye(3); % compute vectorial part of the transform mat = eye(4); mat(1:3, 1:3) = P + (I - P)*cos(theta) + Q*sin(theta); % add translation coefficient mat = recenterTransform3d(mat, center); matgeom-1.2.4/inst/geom3d/PaxHeaders/polygonCentroid3d.m0000644000000000000000000000013214576357161020163 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/polygonCentroid3d.m0000644000175000017500000000630714576357161021751 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [centroid, area] = polygonCentroid3d(varargin) %POLYGONCENTROID3D Centroid (or center of mass) of a polygon. % % PTC = polygonCentroid3d(POLY) % Computes center of mass of a polygon defined by POLY. POLY is a N-by-3 % array of double containing coordinates of polygon vertices. The result % PTC is given as a 1-by-3 numeric array. % The algorithm assumes (1) that the vertices of the polygon are within % the same plane and (2) that the planar projection of the polygon (on % the embedding plane) do not self-intersect. % % PTC = polygonCentroid3d(VX, VY, VZ) % Specifies vertex coordinates as three separate arrays. % % Example % % compute centroid of a basic polygon % poly = [0 0 0; 10 0 10;10 10 20;0 10 10]; % centro = polygonCentroid3d(poly) % centro = % 5.0000 5.0000 10.0000 % % See also % polygons3d, polygonArea3d, polygonCentroid, planePosition, planePoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-09-18 % Copyright 2007-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if nargin == 1 % polygon is given as a single argument pts = varargin{1}; elseif nargin == 3 % polygon is given as 3 coordinate arrays px = varargin{1}; py = varargin{2}; pz = varargin{3}; pts = [px py pz]; end pts = parsePolygon(pts, 'repetition'); % create supporting plane plane = fitPlane(pts); % project points onto the plane pts = planePosition(pts, plane); % compute centroid in 2D [centro2d, area] = polygonCentroid(pts); % project back in 3D centroid = planePoint(plane, centro2d); matgeom-1.2.4/inst/geom3d/PaxHeaders/createRotationOz.m0000644000000000000000000000013214576357161020051 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/createRotationOz.m0000644000175000017500000000657214576357161021643 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createRotationOz(varargin) %CREATEROTATIONOZ Create the 4x4 matrix of a 3D rotation around z-axis. % % TRANS = createRotationOz(THETA); % Returns the transform matrix corresponding to a rotation by the angle % THETA (in radians) around the Oz axis. A rotation by an angle of PI/2 % would transform the vector [1 0 0] into the vector [0 1 0]. % % The returned matrix has the form: % [cos(THETA) -sin(THETA) 0 0] % [sin(THETA) cos(THETA) 0 0] % [ 0 0 1 0] % [ 0 0 0 1] % % TRANS = createRotationOz(ORIGIN, THETA); % TRANS = createRotationOz(X0, Y0, Z0, THETA); % Also specifies origin of rotation. The result is similar as performing % translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). % % % See also % transforms3d, transformPoint3d, createRotationOx, createRotationOy % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % default values dx = 0; dy = 0; dz = 0; theta = 0; % get input values if length(varargin) == 1 % only one argument -> rotation angle theta = varargin{1}; elseif length(varargin) == 2 % origin point (as array) and angle var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); theta = varargin{2}; elseif length(varargin) == 4 % origin (x and y) and angle dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; theta = varargin{4}; end % compute coefs cot = cos(theta); sit = sin(theta); % create transformation trans = [... cot -sit 0 0;... sit cot 0 0;... 0 0 1 0;... 0 0 0 1]; % add the translation part t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; trans = t * trans / t; matgeom-1.2.4/inst/geom3d/PaxHeaders/cart2cyl.m0000644000000000000000000000013214576357161016300 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/cart2cyl.m0000644000175000017500000000605014576357161020061 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cart2cyl(varargin) %CART2CYL Convert cartesian to cylindrical coordinates. % % CYL = cart2cyl(POINT) % convert the 3D cartesian coordinates of points POINT (given by [X Y Z] % where X, Y, Z have the same size) into cylindrical coordinates CYL, % given by [THETA R Z]. % THETA is the arctangent of the ratio Y/X (between 0 and 2*PI) % R can be computed using sqrt(X^2+Y^2) % Z keeps the same value. % The size of THETA, and R is the same as the size of X, Y and Z. % % CYL = cart2cyl(X, Y, Z) % provides coordinates as 3 different parameters % % Example % cart2cyl([-1 0 2]) % gives : 4.7124 1.0000 2.0000 % % See also % angles3d, cart2pol, cart2sph2 % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-03-23 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % process input parameters if length(varargin)==1 var = varargin{1}; x = var(:,1); y = var(:,2); z = var(:,3); elseif length(varargin)==3 x = varargin{1}; y = varargin{2}; z = varargin{3}; end % convert coordinates dim = size(x); theta = reshape(mod(atan2(y(:), x(:))+2*pi, 2*pi), dim); r = reshape(sqrt(x(:).*x(:) + y(:).*y(:)), dim); % process output parameters if nargout==0 ||nargout==1 if length(dim)>2 || dim(2)>1 varargout{1} = {theta r z}; else varargout{1} = [theta r z]; end elseif nargout==3 varargout{1} = theta; varargout{2} = r; varargout{3} = z; end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawArrow3d.m0000644000000000000000000000013214576357161016754 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawArrow3d.m0000644000175000017500000001755114576357161020545 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawArrow3d(varargin) %DRAWARROW3D Plot a quiver of 3D arrows. % % drawArrow3d(pos, vec) % Plots 3D arrows given the (pos)ition array [x1 y1 z1; x2 y2 z2; ...] % and the (vec)tor array [dx1 dy1 dz1; dx2 dy2 dz2; ...]. % % drawArrow3d(pos, vec, color) % Optional positional argument color conforms to 'ColorSpec.' % For example, 'r','red',[1 0 0] will all plot a quiver with all arrows % as red. This can also be in the form of Nx3 where 'N' is the number of % arrows and each column corresponds to the RGB values. Default color is % black. % % drawArrow3d(...,Name,Value) Optional name-value pair arguments: % 'stemRatio': Ratio of the arrow head (cone) to the arrow stem (cylinder) % For example, setting this value to 0.94 will produce arrows with % arrow stems 94% of the length and short, 6% cones as arrow heads. % Values above 0 and below 1 are valid. Default is 0.75. % 'arrowRadius': changes the radius of the arrowstem. Percentage of the % lenght of the arrow. Values between 0.01 and 0.3 are valid. % Default is 0.025. % Uses the 'patch' function to plot the arrows. 'patch' properties can be % used to control the appearance of the arrows. % % drawArrow3d(AX,...) plots into AX instead of GCA. % % H = drawArrow3d(...) returns the handles of the arrows. % % Example: % [X,Y] = meshgrid(1:5, -2:2); % Z = zeros(size(X)); % pos = [X(:),Y(:),Z(:)]; % vec = zeros(size(pos)); % vec(:,1) = 1; % drawArrow3d(pos, vec, 'g', 'stemRatio', 0.6); % view(3); lighting('phong'); camlight('head'); axis('equal') % % ------ % Authors: Shawn Arseneau, oqilipo % E-mail: N/A % Created: 2006-09-14, by Shawn Arseneau % Copyright 2006-2023 % extract handle of axis to draw on [ax, varargin] = parseAxisHandle(varargin{:}); % retrieve positions and vectors pos = varargin{1}; vec = varargin{2}; varargin(1:2) = []; numArrows = size(pos,1); if numArrows ~= size(vec,1) error(['Number of rows of position and magnitude inputs do not agree. ' ... 'Type ''help drawArrow3d'' for details']); end % Parsing p = inputParser; p.KeepUnmatched = true; isPointArray3d = @(x) validateattributes(x,{'numeric'},... {'nonempty','nonnan','real','finite','size',[nan,3]}); addRequired(p,'pos',isPointArray3d) addRequired(p,'vec',isPointArray3d); addOptional(p,'color', 'k', @(x) validateColor(x, numArrows)); isStemRatio = @(x) validateattributes(x,{'numeric'},{'vector','>', 0, '<', 1}); addParameter(p,'stemRatio', 0.75, isStemRatio); isArrowRadius = @(x) validateattributes(x,{'numeric'},{'scalar','>=', 0.01, '<=', 0.3}); addParameter(p,'arrowRadius',0.025, isArrowRadius); parse(p,pos,vec,varargin{:}); pos = p.Results.pos; vec = p.Results.vec; [~, color] = validateColor(p.Results.color, numArrows); stemRatio = p.Results.stemRatio; if numel(stemRatio) == 1; stemRatio = repmat(stemRatio,numArrows,1); end arrowRadius = p.Results.arrowRadius; if numel(arrowRadius) == 1; arrowRadius = repmat(arrowRadius,numArrows,1); end drawOptions = p.Unmatched; % save hold state holdState = ishold(ax); hold(ax, 'on'); %% Loop through all arrows and plot in 3D qHandle = gobjects(numArrows,1); for i = 1:numArrows qHandle(i) = drawSingleVector3d(ax, pos(i,:), vec(i,:), color(i,:), ... stemRatio(i), arrowRadius(i), drawOptions); end % restore hold state if ~holdState hold(ax, 'off'); end if nargout > 0 varargout = {qHandle}; end end function [valid, color] = validateColor(color, numArrows) valid = true; [arrowRow, arrowCol] = size(color); if arrowRow == 1 if ischar(color) %in ShortName or LongName color format color = repmat(color,numArrows,1); else if arrowCol ~= 3 error('color in RGBvalue must be of the form 1x3.'); end color = repmat(color, numArrows, 1); end elseif arrowRow ~= numArrows error('color in RGBvalue must be of the form Nx3.'); end end function arrowHandle = drawSingleVector3d(hAx, pos, vec, color, stemRatio, arrowRadius, drawOptions) %ARROW3D Plot a single 3D arrow with a cylindrical stem and cone arrowhead % % See header of drawArrow3d X = pos(1); Y = pos(2); Z = pos(3); [~, ~, srho] = cart2sph(vec(1), vec(2), vec(3)); %% CYLINDER == STEM cylinderRadius = srho*arrowRadius; cylinderLength = srho*stemRatio; [CX,CY,CZ] = cylinder(cylinderRadius); CZ = CZ.*cylinderLength; % lengthen % Rotate Cylinder [row, col] = size(CX); % initial rotation to coincide with x-axis newCyl = transformPoint3d([CX(:), CY(:), CZ(:)], createRotationVector3d([1 0 0],[0 0 -1])); CX = reshape(newCyl(:,1), row, col); CY = reshape(newCyl(:,2), row, col); CZ = reshape(newCyl(:,3), row, col); [row, col] = size(CX); newCyl = transformPoint3d([CX(:), CY(:), CZ(:)], createRotationVector3d([1 0 0],vec)); stemX = reshape(newCyl(:,1), row, col); stemY = reshape(newCyl(:,2), row, col); stemZ = reshape(newCyl(:,3), row, col); % Translate cylinder stemX = stemX + X; stemY = stemY + Y; stemZ = stemZ + Z; %% CONE == ARROWHEAD RADIUS_RATIO = 1.5; coneLength = srho*(1-stemRatio); coneRadius = cylinderRadius*RADIUS_RATIO; incr = 4; % Steps of cone increments coneincr = coneRadius/incr; [coneX, coneY, coneZ] = cylinder(cylinderRadius*2:-coneincr:0); % Cone coneZ = coneZ.*coneLength; % Rotate cone [row, col] = size(coneX); newCyl = transformPoint3d([coneX(:), coneY(:), coneZ(:)], createRotationVector3d([1 0 0], [0 0 -1])); coneX = reshape(newCyl(:,1), row, col); coneY = reshape(newCyl(:,2), row, col); coneZ = reshape(newCyl(:,3), row, col); newCyl = transformPoint3d([coneX(:), coneY(:), coneZ(:)], createRotationVector3d([1 0 0], vec)); headX = reshape(newCyl(:,1), row, col); headY = reshape(newCyl(:,2), row, col); headZ = reshape(newCyl(:,3), row, col); % Translate cone % centerline for cylinder: the multiplier is to set the cone 'on the rim' of the cylinder V = [0, 0, srho*stemRatio]; Vp = transformPoint3d(V, createRotationVector3d([1 0 0], [0 0 -1])); Vp = transformPoint3d(Vp, createRotationVector3d([1 0 0], vec)); headX = headX + Vp(1) + X; headY = headY + Vp(2) + Y; headZ = headZ + Vp(3) + Z; % Draw cylinder & cone hStem = patch(hAx, surf2patch(stemX, stemY, stemZ), 'FaceColor', color, 'EdgeColor', 'none', drawOptions); hHead = patch(hAx, surf2patch(headX, headY, headZ), 'FaceColor', color, 'EdgeColor', 'none', drawOptions); arrowHandle = hggroup(hAx); set([hStem, hHead], 'Parent', arrowHandle); end matgeom-1.2.4/inst/geom3d/PaxHeaders/orientedBox3d.m0000644000000000000000000000013214576357161017266 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/orientedBox3d.m0000644000175000017500000001071614576357161021053 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [box3d, rotMat] = orientedBox3d(pts) %ORIENTEDBOX3D Object-oriented bounding box of a set of 3D points. % % OOBB = orientedBox3d(PTS) % REturns the oriented bounding box of the collection of points in the % N-by-3 array PTS. The result is given as: % [XC YC ZC L W H PHI THETA PSI] % where (XC,YC,ZC) corresponds to the center of the box, (L,W,H) % corresponds to the length, width, and depth of the box, and (PHI, % THETA, PSI) is the orientation of the box as Euler angles. % % [OOBB, ROT] = orientedBox3d(PTS) % Also returns the rotation matrix of the point cloud, as a 3-by-3 % numeric array. % % Example % [v, f] = sphereMesh; % phi=-360+720*rand; theta=-360+720*rand; psi=-360+720*rand; % angles = [phi, theta, psi]; % rotMat = eulerAnglesToRotation3d(angles); % rotMat(1:3,4) = randi([-100,100],3,1); % scale = [randi([7,9],1,1), randi([4,6],1,1), randi([1,3],1,1)]; % pts = transformPoint3d(bsxfun(@times, v, scale), rotMat); % box3d = orientedBox3d(pts); % figure; drawPoint3d(pts, '.'); % axis equal; xlabel('x'); ylabel('y'); zlabel('z'); % drawCuboid(box3d, 'FaceColor', 'none'); % % See also % meshes3d, drawCuboid, rotation3dToEulerAngles % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-12-01, using Matlab 8.6.0.267246 (R2015b) % Copyright 2015-2023 INRA - Cepia Software Platform tri = convhulln(pts); nFaces = size(tri, 1); %% identify index of face with smallest width indMinBreadth = 0; minBreadth = Inf; for iFace = 1:nFaces faceInds = tri(iFace, :); plane = createPlane(pts(faceInds, :)); breadth = max(abs(distancePointPlane(pts, plane))); if breadth < minBreadth minBreadth = breadth; indMinBreadth = iFace; end end % compute projection on reference plane refPlane = createPlane(pts(tri(indMinBreadth, :), :)); pts2d = planePosition(projPointOnPlane(pts, refPlane), refPlane); % compute 2D OOBB for projected points box2d = orientedBox(pts2d); % extract reference points from planar OOBB: the center, and two direction % vectors center2d = box2d(1:2); L1 = box2d(3); L2 = box2d(4); markers2d = [0 0; L1/2 0; 0 L2/2]; % orient reference points to 2d basis theta2d = box2d(5); rot = createRotation(deg2rad(theta2d)); tra = createTranslation(center2d); transfo = tra * rot; markers2d = transformPoint(markers2d, transfo); % backprojection to 3D space markers3d = planePoint(refPlane, markers2d); % compute 3D vectors and center centerProj = markers3d(1,:); v1n = normalizeVector3d(markers3d(2,:) - centerProj); v2n = normalizeVector3d(markers3d(3,:) - centerProj); % compute rotation matrix and convert to Euler Angles v3n = crossProduct3d(v1n, v2n); rotMat = [v1n' v2n' v3n']; boxAngles = rotation3dToEulerAngles(rotMat); % create 3D object-oriented bounding box boxCenter3d = centerProj + v3n * minBreadth/2; box3d = [boxCenter3d L1 L2 minBreadth boxAngles]; matgeom-1.2.4/inst/geom3d/PaxHeaders/planePoint.m0000644000000000000000000000013214576357161016666 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/planePoint.m0000644000175000017500000000550414576357161020452 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function coord = planePoint(plane, point) %PLANEPOINT Compute 3D position of a point in a plane. % % POINT = planePoint(PLANE, POS) % PLANE is a 9 element row vector [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] % POS is the coordinate of a point in the plane basis, % POINT is the 3D coordinate in global basis. % % Example % plane = [10 20 30 1 0 0 0 1 1]; % pos2d = [3 4]; % pt = planePoint(plane, pos2d) % pt = % 13 24 34 % % See also % geom3d, planes3d, planePosition % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-09-18, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % size of input arguments npl = size(plane, 1); npt = size(point, 1); % check inputs have compatible sizes if npl ~= npt && npl > 1 && npt > 1 error('geom3d:planePoint:inputSize', ... 'plane and point should have same size, or one of them must have 1 row'); end % basis origin, eventually resized origin = plane(:, 1:3); if npl == 1 && npt > 1 origin = origin(ones(npt,1), :); end % compute 3D coordinate coord = origin + ... bsxfun(@times, plane(:,4:6), point(:,1)) + ... bsxfun(@times, plane(:,7:9), point(:,2)) ; matgeom-1.2.4/inst/geom3d/PaxHeaders/drawSurfPatch.m0000644000000000000000000000013214576357161017332 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawSurfPatch.m0000644000175000017500000000566014576357161021121 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function drawSurfPatch(varargin) %DRAWSURFPATCH Draw a 3D surface patch, with 2 parametrized surfaces. % % usage: % drawSurfPatch(u, v, zuv) % where u, v, and zuv are three matrices the same size, u and % corresponding to each parameter, and zuv being equal to a function of u % and v. % % drawSurfPatch(u, v, zuv, p0) % If p0 is specified, two lines with u(p0(1)) and v(p0(2)) are drawn on % the surface, and corresponding tangent are also shown. % % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-24 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); u = varargin{1}; v = varargin{2}; z = varargin{3}; varargin(1:3) = []; % prepare figure hold(hAx, 'on'); % draw the surface interior surf(hAx, u, v, z, 'FaceColor', 'g', 'EdgeColor', 'none'); % draw the surface boundaries drawPolyline3d(hAx, u(1,:), v(1,:), z(1,:)) drawPolyline3d(hAx, u(end,:), v(end,:), z(end,:)) drawPolyline3d(hAx, u(:,end), v(:,end), z(:,end)) drawPolyline3d(hAx, u(:,1), v(:,1), z(:,1)) % eventually draw two perpendicular lines on the surface if ~isempty(varargin) pos = varargin{1}; drawPolyline3d(hAx, u(pos(1),:), v(pos(1),:), z(pos(1),:)); drawPolyline3d(hAx, u(:,pos(2)), v(:,pos(2)), z(:,pos(2))); end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawLine3d.m0000644000000000000000000000013214576357161016551 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawLine3d.m0000644000175000017500000000651714576357161020342 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function h = drawLine3d(lin, varargin) %DRAWLINE3D Draw a 3D line clipped by the current axes. % % drawLine3d(LINE) draws the line LINE on the current axis, by clipping % with the current axis. % % drawLine3d(LINE, PARAM, VALUE) accepts parameter/value pairs, like % for plot function. Color of the line can also be given as a single % parameter. % % drawLine3d(AX,...) plots into AX instead of GCA. % % H = drawLine3d(...) returns a handle to the created line object. % If the line is not clipped by the axis, function returns -1. % % Example % % draw a sphere together with the three main axes % figure; hold on; % drawSphere([40 30 20 30]); % view(3); axis equal; axis([-20 80 -20 80 -20 80]) % drawLine3d([0 0 0 1 0 0], 'k'); % drawLine3d([0 0 0 0 1 0], 'k'); % drawLine3d([0 0 0 0 0 1], 'k'); % light; % % % See also % lines3d, createLine3d, clipLine3d, drawRay3d, drawEdge3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-17 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % Parse and check inputs isLine3d = @(x) validateattributes(x,{'numeric'},... {'nonempty','nonnan','real','finite','size',[nan,6]}); defOpts.Color = 'b'; [hAx, lin, varargin] = ... parseDrawInput(lin, isLine3d, 'line', defOpts, varargin{:}); % extract limits of the bounding box box = [get(hAx, 'xlim') get(hAx, 'ylim') get(hAx, 'zlim')]; % clip the line with the limits of the current axis edge = clipLine3d(lin, box); % draw the clipped line if sum(isnan(edge)) == 0 hh = drawEdge3d(hAx, edge); if ~isempty(varargin) set(hh, varargin{:}); end else hh = []; end % process output if nargout > 0 h = hh; end matgeom-1.2.4/inst/geom3d/PaxHeaders/points3d.m0000644000000000000000000000013214576357161016320 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/points3d.m0000644000175000017500000000427314576357161020106 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points3d(varargin) %POINTS3D Description of functions operating on 3D points. % % Points are represented by their 3 Cartesian coordinates: % P = [X Y Z]; % % Arrays of points consist in N*3 arrays, each row being a point. % % See also % isCoplanar, distancePoints, boundingBox3d % anglePoints3d, angleSort3d, sphericalAngle % sph2cart2, cart2sph2, cart2cyl, cyl2cart % transformPoint3d, clipPoints3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/geom3d/PaxHeaders/intersectLinePolygon3d.m0000644000000000000000000000013214576357161021164 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/intersectLinePolygon3d.m0000644000175000017500000000742214576357161022751 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [inter, inside]= intersectLinePolygon3d(line, poly) %INTERSECTLINEPOLYGON3D Intersection point of a 3D line and a 3D polygon. % % INTER = intersectLinePolygon3d(LINE, POLY) % Compute coordinates of intersection point between the 3D line LINE and % the 3D polygon POLY. LINE is a 1-by-6 row vector containing origin and % direction vector of the line, POLY is a Np-by-3 array containing % coordinates of 3D polygon vertices. % INTER is a 1-by-3 row vector containing coordinates of intersection % point, or [NaN NaN NaN] if line and polygon do not intersect. % % INTERS = intersectLinePolygon3d(LINES, POLY) % If LINES is a N-by-6 array representing several lines, the result % INTERS is a N-by-3 array containing coordinates of intersection of each % line with the polygon. % % [INTER INSIDE] = intersectLinePolygon3d(LINE, POLY) % Also return a N-by-1 boolean array containing TRUE if the corresponding % polygon contains the intersection point. % % Example % % Compute intersection between a 3D line and a 3D triangle % pts3d = [3 0 0; 0 6 0;0 0 9]; % line1 = [0 0 0 3 6 9]; % inter = intersectLinePolygon3d(line1, pts3d) % inter = % 1 2 3 % % % keep only valid intersections with several lines % pts3d = [3 0 0; 0 6 0;0 0 9]; % lines = [0 0 0 1 2 3;10 0 0 1 2 3]; % [inter inside] = intersectLinePolygon3d(line1, pts3d); % inter(inside, :) % ans = % 1 2 3 % % See also % intersectLinePolygon, intersectRayPolygon3d, intersectLinePlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % supporting plane of polygon vertices plane = createPlane(poly(1:3, :)); % intersection of 3D line with the plane inter = intersectLinePlane(line, plane); % project all points on reference plane pts2d = planePosition(poly, plane); pInt2d = planePosition(inter, plane); % need to check polygon orientation inside = xor(isPointInPolygon(pInt2d, pts2d), polygonArea(pts2d) < 0); % intersection points outside the polygon are set to NaN inter(~inside, :) = NaN; matgeom-1.2.4/inst/geom3d/PaxHeaders/transformVector3d.m0000644000000000000000000000013214576357161020202 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/transformVector3d.m0000644000175000017500000000604414576357161021766 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = transformVector3d(varargin) %TRANSFORMVECTOR3D Transform a vector with a 3D affine transform. % % V2 = transformVector3d(V1, TRANS); % Computes the vector obtained by transforming vector V1 with affine % transform TRANS. % V1 has the form [x1 y1 z1], and TRANS is a [3x3], [3x4], or [4x4] % matrix, with one of the forms: % [a b c] , [a b c j] , or [a b c j] % [d e f] [d e f k] [d e f k] % [g h i] [g h i l] [g h i l] % [0 0 0 1] % % V2 = transformVector3d(V1, TRANS) also works when V1 is a [Nx3xMxEtc] % array of double. In this case, V2 has the same size as V1. % % V2 = transformVector3d(X1, Y1, Z1, TRANS); % Specifies vectors coordinates in three arrays with same size. % % [X2 Y2 Z2] = transformVector3d(...); % Returns the coordinates of the transformed vector separately. % % % See also % vectors3d, transforms3d, transformPoint3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-11-25, from transformPoint3d % Copyright 2008-2023 INRA - TPV URPOI - BIA IMASTE if nargin~=2 && nargin~=4 error('Invalid number of input arguments. Type ''help transformVector3d'' for details.'); end % Extract only the linear part of the affine transform trans = varargin{end}; trans(1:4,4) = [0; 0; 0; 1]; % Call transformPoint3d using equivalent output arguments varargout = cell(1, max(1,nargout)); [varargout{:}] = transformPoint3d(varargin{1:end-1}, trans); matgeom-1.2.4/inst/geom3d/PaxHeaders/planesBisector.m0000644000000000000000000000013214576357161017532 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/planesBisector.m0000644000175000017500000000734114576357161021317 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function bis = planesBisector(plane1, plane2) %PLANESBISECTOR Bisector plane between two other planes. % % BIS = planesBisector(PLANE1, PLANE2); % Returns the planes that contains the intersection line between PLANE1 % and PLANE2 and that bisect the dihedral angle of PLANE1 and PLANE2. % Note that computing the bisector of PLANE2 and PLANE1 (in that order) % returns the same plane but with opposite orientation. % % Example % % Draw two planes together with their bisector % pl1 = createPlane([3 4 5], [1 2 3]); % pl2 = createPlane([3 4 5], [2 -3 4]); % % compute bisector % bis = planesBisector(pl1, pl2); % % setup display % figure; hold on; axis([0 10 0 10 0 10]); % set(gcf, 'renderer', 'opengl') % view(3); % % draw the planes % drawPlane3d(pl1, 'g'); % drawPlane3d(pl2, 'g'); % drawPlane3d(bis, 'b'); % % See also % planes3d, dihedralAngle, intersectPlanes % % ------ % Author: Ben X. Kang % E-mail: N/A % Created: ? % Copyright ? % Let the two planes be defined by equations % % a1*x + b1*y + c1*z + d1 = 0 % % and % % a2*x + b2*y + c2*z + d2 = 0 % % in which vectors [a1,b1,c1] and [a2,b2,c2] are normalized to be of unit % length (a^2+b^2+c^2 = 1). Then % % (a1+a2)*x + (b1+b2)*y + (c1+c2)*z + (d1+d2) = 0 % % is the equation of the desired plane which bisects the dihedral angle % between the two planes. These coefficients cannot be all zero because % the two given planes are not parallel. % % Notice that there is a second solution to this problem % % (a1-a2)*x + (b1-b2)*y + (c1-c2)*z + (d1-d2) = 0 % % which also is a valid plane and orthogonal to the first solution. One of % these planes bisects the acute dihedral angle, and the other the % supplementary obtuse dihedral angle, between the two given planes. p1 = plane1(1:3); % a point on the plane n1 = planeNormal(plane1); % the normal of the plane p2 = plane2(1:3); n2 = planeNormal(plane2); if ~isequal(p1(1:3), p2(1:3)) L = intersectPlanes(plane1, plane2); % intersection of the given two planes pt = L(1:3); % a point on the line intersection else pt = p1(1:3); end % use column-wise vector bis = createPlane(pt, n1 - n2); matgeom-1.2.4/inst/geom3d/PaxHeaders/clipPlane.m0000644000000000000000000000013214576357161016464 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/clipPlane.m0000644000175000017500000001124314576357161020245 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly = clipPlane(plane, box) %CLIPPLANE Compute the 3D polygon representing a clipped plane. % % POLY = clipPlane(PLANE, BOUNDS) % Computes the vertices of the 3D polygon that represents the result of % the clipping of the plane by the given BOUNDS. % PLANE is given as [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], % BOUNDS is given as [XMIN XMAX YMIN YMAX ZMIN ZMAX]. % The result POLY is given as N-by-3 numeric array representing the % coordinates of the polygon, or an emptyarray if the plane lies totally % outside of the bounds. % % % Example % plane = [5 5 5 1 0 0 0 1 0]; % bounds = [0 10 0 10 0 10]; % poly = clipPlane(plane, bounds) % poly = % 0 0 5 % 10 0 5 % 10 10 5 % 0 10 5 % % See also % planes3d, createPlane, drawPlane3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2021-11-09, using Matlab 9.10.0.1684407 (R2021a) Update 3 % Copyright 2021-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % retrieve min/max coords xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); zmin = box(5); zmax = box(6); % create lines corresponding to the edges of the bounding box lineX00 = [xmin ymin zmin 1 0 0]; lineX01 = [xmin ymin zmax 1 0 0]; lineX10 = [xmin ymax zmin 1 0 0]; lineX11 = [xmin ymax zmax 1 0 0]; lineY00 = [xmin ymin zmin 0 1 0]; lineY01 = [xmin ymin zmax 0 1 0]; lineY10 = [xmax ymin zmin 0 1 0]; lineY11 = [xmax ymin zmax 0 1 0]; lineZ00 = [xmin ymin zmin 0 0 1]; lineZ01 = [xmin ymax zmin 0 0 1]; lineZ10 = [xmax ymin zmin 0 0 1]; lineZ11 = [xmax ymax zmin 0 0 1]; % compute intersection point with each line piX00 = intersectLinePlane(lineX00, plane); piX01 = intersectLinePlane(lineX01, plane); piX10 = intersectLinePlane(lineX10, plane); piX11 = intersectLinePlane(lineX11, plane); piY00 = intersectLinePlane(lineY00, plane); piY01 = intersectLinePlane(lineY01, plane); piY10 = intersectLinePlane(lineY10, plane); piY11 = intersectLinePlane(lineY11, plane); piZ00 = intersectLinePlane(lineZ00, plane); piZ01 = intersectLinePlane(lineZ01, plane); piZ10 = intersectLinePlane(lineZ10, plane); piZ11 = intersectLinePlane(lineZ11, plane); % concatenate points into one array points = [... piX00;piX01;piX10;piX11; ... piY00;piY01;piY10;piY11; ... piZ00;piZ01;piZ10;piZ11;]; % check validity: keep only points inside window (with tolerance) ac = sqrt (eps); ivx = points(:,1) >= xmin-ac & points(:,1) <= xmax+ac; ivy = points(:,2) >= ymin-ac & points(:,2) <= ymax+ac; ivz = points(:,3) >= zmin-ac & points(:,3) <= zmax+ac; valid = ivx & ivy & ivz; points = unique(points(valid, :), 'rows'); % If there is no intersection point, escape. if size(points, 1) < 3 poly = []; return; end % the two spanning lines of the plane d1 = plane(:, [1:3 4:6]); d2 = plane(:, [1:3 7:9]); % position of intersection points in plane coordinates u1 = linePosition3d(points, d1); u2 = linePosition3d(points, d2); % reorder vertices in the correct order inds = convhull(u1, u2); inds = inds(1:end-1); % return the set of points that compose the polygon poly = points(inds, :); matgeom-1.2.4/inst/geom3d/PaxHeaders/rotation3dToEulerAngles.m0000644000000000000000000000013214576357161021275 xustar0030 mtime=1710874225.110193371 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/rotation3dToEulerAngles.m0000644000175000017500000002106314576357161023057 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = rotation3dToEulerAngles(mat, varargin) %ROTATION3DTOEULERANGLES Extract Euler angles from a rotation matrix. % % [PHI, THETA, PSI] = rotation3dToEulerAngles(MAT) % Computes Euler angles PHI, THETA and PSI (in degrees) from a 3D 4-by-4 % or 3-by-3 rotation matrix. % % ANGLES = rotation3dToEulerAngles(MAT) % Concatenates results in a single 1-by-3 row vector. This format is used % for representing some 3D shapes like ellipsoids. % % ... = rotation3dToEulerAngles(MAT, CONVENTION) % CONVENTION specifies the axis rotation sequence. Default is 'ZYX'. % Supported conventions are: % 'ZYX','ZXY','YXZ','YZX','XYZ','XZY' % 'ZYZ','ZXZ','YZY','YXY','XZX','XYX' % % Example % rotation3dToEulerAngles % % References % Code from '1994 - Shoemake - Graphics Gems IV: Euler Angle Conversion: % http://webdocs.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiv/euler_angle/EulerAngles.c % (see rotm2eul, that is part of MATLAB's Robotics System Toolbox) % Modified using explanations in: % http://www.gregslabaugh.net/publications/euler.pdf % https://www.geometrictools.com/Documentation/EulerAngles.pdf % % See also % transforms3d, rotation3dAxisAndAngle, createRotation3dLineAngle, % eulerAnglesToRotation3d % % ------ % Authors: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2010-08-11, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform p = inputParser; validStrings = {... 'ZYX','ZXY','YXZ','YZX','XYZ','XZY',... 'ZYZ','ZXZ','YZY','YXY','XZX','XYX'}; addOptional(p,'convention','ZYX',@(x) any(validatestring(x,validStrings))); logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addParameter(p,'IsRotation', 1, logParValidFunc); valTol = @(x) validateattributes(x,{'numeric'},{'scalar', '>=',eps(class(mat)), '<=',1}); addParameter(p,'tolerance', 1e-8, valTol); parse(p,varargin{:}); convention=p.Results.convention; isRotation = p.Results.IsRotation; tolerance = p.Results.tolerance; if isRotation if ~isTransform3d(mat(1:3,1:3), 'rotation', 1, 'tolerance', tolerance) warning(['Rotation matrix contains reflection or scaling ' ... 'tested with a tolerance of ' num2str(tolerance) '.' newline ... 'Calculation of euler angles might be incorrect.']) end end switch convention case 'ZYX' % extract |cos(theta)| cy = hypot(mat(1,1), mat(2,1)); % avoid dividing by 0 if cy > 16*eps % normal case: theta <> 0 phi = atan2( mat(2,1), mat(1,1)); theta = atan2(-mat(3,1), cy); psi = atan2( mat(3,2), mat(3,3)); else phi = 0; theta = atan2(-mat(3,1), cy); psi = atan2(-mat(2,3), mat(2,2)); end case 'ZXY' cy = hypot(mat(2,2), mat(1,2)); if cy > 16*eps phi = -atan2( mat(1,2), mat(2,2)); theta = -atan2(-mat(3,2), cy); psi = -atan2( mat(3,1), mat(3,3)); else phi = 0; theta = -atan2(-mat(3,2), cy); psi = -atan2(-mat(1,3), mat(1,1)); end case 'YXZ' cy = hypot(mat(3,3), mat(1,3)); if cy > 16*eps phi = atan2( mat(1,3), mat(3,3)); theta = atan2(-mat(2,3), cy); psi = atan2( mat(2,1), mat(2,2)); else phi = 0; theta = atan2(-mat(2,3), cy); psi = atan2(-mat(1,2), mat(1,1)); end case 'YZX' cy = hypot(mat(1,1), mat(3,1)); if cy > 16*eps phi = -atan2( mat(3,1), mat(1,1)); theta = -atan2(-mat(2,1), cy); psi = -atan2( mat(2,3), mat(2,2)); else phi = 0; theta = -atan2(-mat(2,1), cy); psi = -atan2(-mat(3,2), mat(3,3)); end case 'XYZ' cy = hypot(mat(3,3), mat(2,3)); if cy > 16*eps phi = -atan2( mat(2,3), mat(3,3)); theta = -atan2(-mat(1,3), cy); psi = -atan2( mat(1,2), mat(1,1)); else phi = 0; theta = -atan2(-mat(1,3), cy); psi = -atan2(-mat(2,1), mat(2,2)); end case 'XZY' cy = hypot(mat(2,2), mat(3,2)); if cy > 16*eps phi = atan2( mat(3,2), mat(2,2)); theta = atan2(-mat(1,2), cy); psi = atan2( mat(1,3), mat(1,1)); else phi = 0; theta = atan2(-mat(1,2), cy); psi = atan2(-mat(3,1), mat(3,3)); end case 'ZYZ' cy = hypot(mat(3,2), mat(3,1)); if cy > 16*eps phi = -atan2(mat(2,3), -mat(1,3)); theta = -atan2(cy, mat(3,3)); psi = -atan2(mat(3,2), mat(3,1)); else phi = 0; theta = -atan2(cy, mat(3,3)); psi = -atan2(-mat(2,1), mat(2,2)); end case 'ZXZ' cy = hypot(mat(3,2), mat(3,1)); if cy > 16*eps phi = atan2(mat(1,3), -mat(2,3)); theta = atan2(cy, mat(3,3)); psi = atan2(mat(3,1), mat(3,2)); else phi = 0; theta = atan2(cy, mat(3,3)); psi = atan2(-mat(1,2), mat(1,1)); end case 'YZY' cy = hypot(mat(2,3), mat(2,1)); if cy > 16*eps phi = atan2(mat(3,2), -mat(1,2)); theta = atan2(cy, mat(2,2)); psi = atan2(mat(2,3), mat(2,1)); else phi = 0; theta = atan2(cy, mat(2,2)); psi = atan2(-mat(3,1), mat(3,3)); end case 'YXY' cy = hypot(mat(2,3), mat(2,1)); if cy > 16*eps phi = -atan2(mat(1,2), -mat(3,2)); theta = -atan2(cy, mat(2,2)); psi = -atan2(mat(2,1), mat(2,3)); else phi = 0; theta = -atan2(cy, mat(2,2)); psi = -atan2(-mat(1,3), mat(1,1)); end case 'XZX' cy = hypot(mat(1,3), mat(1,2)); if cy > 16*eps phi = -atan2(mat(3,1), -mat(2,1)); theta = -atan2(cy, mat(1,1)); psi = -atan2(mat(1,3), mat(1,2)); else phi = 0; theta = -atan2(cy, mat(1,1)); psi = -atan2(-mat(3,2), mat(3,3)); end case 'XYX' cy = hypot(mat(1,2), mat(1,3)); if cy > 16*eps phi = atan2(mat(2,1), -mat(3,1)); theta = atan2(cy, mat(1,1)); psi = atan2(mat(1,2), mat(1,3)); else phi = 0; theta = atan2(cy, mat(1,1)); psi = atan2(-mat(2,3), mat(2,2)); end end % format output arguments if nargout <= 1 % one array varargout{1} = rad2deg([phi theta psi]); else % three separate arrays varargout = cellfun(@rad2deg, {phi theta psi},'uni',0); end matgeom-1.2.4/inst/geom3d/PaxHeaders/drawPolygon3d.m0000644000000000000000000000013214576357161017311 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.110193371 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom3d/drawPolygon3d.m0000644000175000017500000001020114576357161021063 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawPolygon3d(varargin) %DRAWPOLYGON3D Draw a 3D polygon specified by a list of vertex coords. % % drawPolygon3d(POLY); % packs coordinates in a single N-by-3 array. % % drawPolygon3d(PX, PY, PZ); % specifies coordinates in separate numeric vectors (either row or % columns) % % drawPolygon3d(..., PARAM, VALUE); % Specifies style options to draw the polyline, see plot for details. % % H = drawPolygon3d(...); % also returns a handle to the list of created line objects. % % Example % t = linspace(0, 2*pi, 100)'; % xt = 10 * cos(t); % yt = 5 * sin(t); % zt = zeros(100,1); % pol = [xt yt zt]; % figure; hold on; axis equal; % fillPolygon3d(pol, 'c'); % drawPolygon3d(pol, 'linewidth', 2, 'color', 'k'); % % See also % polygons3d, fillPolygon3d, drawPolyline3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-08-17, from drawPolyline3d, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Process input arguments % extract handle of axis to draw on [hAx, varargin] = parseAxisHandle(varargin{:}); % check case we want to draw several curves, stored in a cell array var1 = varargin{1}; if iscell(var1) hold on; nPolys = length(var1); h = gobjects(1, nPolys); for i = 1:length(var1(:)) h(i) = drawPolygon3d(hAx, var1{i}, varargin{2:end}); end if nargout > 0 varargout{1} = h; end return; end %% extract polygon coordinates if min(size(var1)) == 1 % if first argument is a vector (either row or column), then assumes % first argument contains x coords, second argument contains y coords % and third one the z coords px = var1; if length(varargin) < 3 error('geom3d:drawPolygon3d:Wrong number of arguments in fillPolygon3d'); end py = varargin{2}; pz = varargin{3}; varargin = varargin(4:end); else % first argument contains both coordinate px = var1(:, 1); py = var1(:, 2); pz = var1(:, 3); varargin = varargin(2:end); end if any(isnan(px)) varargout{1} = drawPolygon3d(splitPolygons([px py pz]), varargin{:}); return; end %% draw the polygon % check that the polygon is closed if px(1) ~= px(end) || py(1) ~= py(end) || pz(1) ~= pz(end) px = [px(:); px(1)]; py = [py(:); py(1)]; pz = [pz(:); pz(1)]; end % draw the closed curve h = plot3(hAx, px, py, pz, varargin{:}); %% Format output if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/PaxHeaders/__matgeom_package_register__.m0000644000000000000000000000013214576357161021203 xustar0030 mtime=1710874225.178193307 30 atime=1710874225.178193307 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/__matgeom_package_register__.m0000644000175000017500000000377614576357161023000 0ustar00juanpijuanpi00000000000000## Copyright (C) 2016 Carnë Draug ## ## This program is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 3 of the ## License, or (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see ## . ## -*- texinfo -*- ## @deftypefn {} {} __matgeom_package_register__ () ## Undocumented internal function of matgeom package. ## @end deftypefn ## PKG_ADD: __matgeom_package_register__ (1); ## PKG_DEL: __matgeom_package_register__ (-1); function subdir_paths = __matgeom_package_register__ (loading = 0) subdirlist = {"utils", "geom2d", "polygons2d", "graphs",... "geom3d","meshes3d","polynomialCurves2d"}; ## Get full path, with luck we can retreive the package name from here base_pkg_path = fileparts (make_absolute_filename (mfilename ("fullpath"))); subdir_paths = fullfile (base_pkg_path, subdirlist); if (loading > 0) ## Disable dummy verLessThan.m if compare_versions (version, '6.0.0', '>=') ## Check if this package still has varLessThan pkgverchecker = fullfile (base_pkg_path, 'verLessThan.'); if exist ([pkgverchecker, 'm'], 'file') warning ('Octave:deprecated-function', 'Permanently renaming verLessThan.m since it is already present'); ## The change is permanent and done only once ## Means that if testing in older version of Octave, needs re-install rename([pkgverchecker, 'm'], [pkgverchecker, 'deprecated']); endif endif addpath (subdir_paths{:}); elseif (loading < 0) rmpath (subdir_paths{:}); endif endfunction matgeom-1.2.4/inst/PaxHeaders/verLessThan.m0000644000000000000000000000013214576357161015635 xustar0030 mtime=1710874225.178193307 30 atime=1710874225.178193307 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/verLessThan.m0000644000175000017500000000221214576357161017412 0ustar00juanpijuanpi00000000000000## Copyright (C) 2019 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## Author: Juan Pablo Carbajal ## Created: 2019-11-20 ## -*- texinfo -*- ## @defun {@var{x} =} verLessThan () ## Dummy function that retunrs true to all Matlab version queries. ## ## This function assumes that octave can cope with code written for the latest ## matlab version. ## ## It will be removed when Octave 6.0.0 is released as verLessThan in shipped ## with it. ## ## @end defun function tf = verLessThan () tf = false; endfunction matgeom-1.2.4/inst/PaxHeaders/geom2d0000644000000000000000000000013214576357161014321 xustar0030 mtime=1710874225.046193433 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/0000755000175000017500000000000014576357161016156 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/geom2d/PaxHeaders/isPointOnLine.m0000644000000000000000000000013214576357161017306 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPointOnLine.m0000644000175000017500000000550214576357161021070 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointOnLine(point, line, varargin) %ISPOINTONLINE Test if a point belongs to a line. % % B = isPointOnLine(POINT, LINE) % with POINT being [xp yp], and LINE being [x0 y0 dx dy]. % Returns 1 if point lies on the line, 0 otherwise. % % If POINT is an N-by-2 array of points, B is a N-by-1 array of booleans. % % If LINE is a N-by-4 array of line, B is a 1-by-N array of booleans. % % B = isPointOnLine(POINT, LINE, TOL) % Specifies the tolerance used for testing location on 3D line. Default value is 1e-14. % % See also % lines2d, points2d, isPointOnEdge, isPointOnRay, isLeftOriented % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % test if lines are colinear, using third coordinate of 3D cross-product % same test as: % b = abs((xp-x0).*dy-(yp-y0).*dx)./hypot(dx, dy).^2 < tol; b = bsxfun(... @rdivide, abs(... bsxfun(@times, bsxfun(@minus, point(:,1), line(:,1)'), line(:,4)') - ... bsxfun(@times, bsxfun(@minus, point(:,2), line(:,2)'), line(:,3)')), ... (line(:,3).^2 + line(:,4).^2)') < tol; matgeom-1.2.4/inst/geom2d/PaxHeaders/mergeBoxes.m0000644000000000000000000000013214576357161016654 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/mergeBoxes.m0000644000175000017500000000500214576357161020431 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = mergeBoxes(box1, box2) %MERGEBOXES Merge two boxes, by computing their greatest extent. % % BOX = mergeBoxes(BOX1, BOX2); % % Example % box1 = [5 20 5 30]; % box2 = [0 15 0 15]; % mergeBoxes(box1, box2) % ans = % 0 20 0 30 % % % See also % boxes2d, drawBox, intersectBoxes % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % unify sizes of data if size(box1,1) == 1 box1 = repmat(box1, size(box2,1), 1); elseif size(box2, 1) == 1 box2 = repmat(box2, size(box1,1), 1); elseif size(box1,1) ~= size(box2,1) error('Bad size for inputs'); end % compute extreme coords mini = min(box1(:,[1 3]), box2(:,[1 3])); maxi = max(box1(:,[2 4]), box2(:,[2 4])); % concatenate result into a new box structure box = [mini(:,1) maxi(:,1) mini(:,2) maxi(:,2)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/rotateVector.m0000644000000000000000000000013214576357161017235 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/rotateVector.m0000644000175000017500000000433514576357161021022 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vr = rotateVector(v, angle) %ROTATEVECTOR Rotate a vector by a given angle. % % VR = rotateVector(V, THETA) % Rotate the vector V by an angle THETA, given in radians. % % Example % rotateVector([1 0], pi/2) % ans = % 0 1 % % See also % vectors2d, transformVector, createRotation % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-04-14, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % precomputes angles cot = cos(angle); sit = sin(angle); % compute rotated coordinates vr = [cot * v(:,1) - sit * v(:,2) , sit * v(:,1) + cot * v(:,2)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/isPointOnRay.m0000644000000000000000000000013214576357161017152 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPointOnRay.m0000644000175000017500000000657014576357161020742 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointOnRay(point, ray, varargin) %ISPOINTONRAY Test if a point belongs to a ray. % % B = isPointOnRay(PT, RAY); % Returns 1 if point PT belongs to the ray RAY. % PT is given by [x y] and RAY by [x0 y0 dx dy]. % % If PT is a N-by-2 array, and RAY is a M-by-4 array, then the result is % a N-by-M array containing the result of each pair-wise test. % % B = isPointOnRay(PT, RAY, TOL); % Specifies the tolerance to use for testing if point is on the ray. % % Example % ray = [10 20 3 4]; % % test for a point on the ray % p1 = [16 28]; % isPointOnRay(p1, ray) % ans = % logical % 0 % % test for a point on the supporting line but "before" the origin % p2 = [7 16]; % isPointOnRay(p1, ray) % ans = % logical % 0 % % See also % rays2d, points2d, isPointOnLine, isPointOnEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % number of rays and points Nr = size(ray, 1); Np = size(point, 1); % if several rays or several points, adapt sizes of arrays x0 = repmat(ray(:,1)', Np, 1); y0 = repmat(ray(:,2)', Np, 1); dx = repmat(ray(:,3)', Np, 1); dy = repmat(ray(:,4)', Np, 1); xp = repmat(point(:,1), 1, Nr); yp = repmat(point(:,2), 1, Nr); % test if points belongs to the supporting line b1 = abs((xp-x0).*dy - (yp-y0).*dx) ./ (dx.*dx + dy.*dy) < tol; % check if points lie the good direction on the rays ind = abs(dx) > abs(dy); t = zeros(size(b1)); t(ind) = (xp(ind) - x0(ind)) ./ dx(ind); t(~ind) = (yp(~ind) - y0(~ind)) ./ dy(~ind); % combine the two tests b = b1 & (t >= 0); matgeom-1.2.4/inst/geom2d/PaxHeaders/isPointInTriangle.m0000644000000000000000000000013214576357161020156 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPointInTriangle.m0000644000175000017500000000712314576357161021741 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointInTriangle(point, p1, p2, p3) %ISPOINTINTRIANGLE Test if a point is located inside a triangle. % % B = isPointInTriangle(POINT, V1, V2, V3) % POINT is a 1-by-2 row vector containing coordinates of the test point, % V1, V2 and V3 are 1-by-2 row vectors containing coordinates of triangle % vertices. The function returns 1 is the point is inside or on the % boundary of the triangle, and 0 otherwise. % % B = isPointInTriangle(POINT, VERTICES) % Specifiy the coordinates of vertices as a 3-by-2 array. % % If POINT contains more than one row, the result B has as many rows as % the input POINT. % % % Example % % vertices of the triangle % p1 = [0 0]; % p2 = [10 0]; % p3 = [5 10]; % tri = [p1;p2;p3]; % % check if points are inside % isPointInTriangle([0 0], tri) % ans = % 1 % isPointInTriangle([5 5], tri) % ans = % 1 % isPointInTriangle([10 5], tri) % ans = % 0 % % check for an array of points % isPointInTriangle([0 0;1 0;0 1], tri) % ans = % 1 % 1 % 0 % % See also % polygons2d, isPointInPolygon, isCounterClockwise % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-16, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % if triangle vertices are given as a single array, extract vertices if nargin == 2 p2 = p1(2, :); p3 = p1(3, :); p1 = p1(1, :); end % check triangle orientation isDirect = isCounterClockwise(p1, p2, p3); % check location of point with respect to each side if isDirect b12 = isCounterClockwise(p1, p2, point) >= 0; b23 = isCounterClockwise(p2, p3, point) >= 0; b31 = isCounterClockwise(p3, p1, point) >= 0; else b12 = isCounterClockwise(p1, p2, point) <= 0; b23 = isCounterClockwise(p2, p3, point) <= 0; b31 = isCounterClockwise(p3, p1, point) <= 0; end % combines the 3 results b = b12 & b23 & b31; matgeom-1.2.4/inst/geom2d/PaxHeaders/ellipseArea.m0000644000000000000000000000013214576357161017002 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/ellipseArea.m0000644000175000017500000000465414576357161020573 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function area = ellipseArea(elli) %ELLIPSEAREA Area of an ellipse. % % AREA = ellipseArea(ELLI) % Computes he area of the ellipse ELLI, by taking the product of the semi % axis length and multiplying by PI: % AREA = PI * RA * RB % % Example % % area of a simple ellipse % elli = [50 50 40 20 30]; % ellipseArea(elli) % ans = % 2.5133e+03 % % when scaling by K, area is scaled by K^2: % transfo = createScaling(.2); % elliT = transformEllipse(elli, transfo); % ellipseArea(elliT) % ans = % 100.5310 % % % See also % ellipses2d, ellipsePerimeter, ellipseToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-09-09, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) area = elli(:,3) .* elli(:,4) * pi; matgeom-1.2.4/inst/geom2d/PaxHeaders/fitPolynomialTransform2d.m0000644000000000000000000000013214576357161021524 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/fitPolynomialTransform2d.m0000644000175000017500000000607514576357161023314 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function coeffs = fitPolynomialTransform2d(pts, ptsRef, degree) %FITPOLYNOMIALTRANSFORM2D Coefficients of polynomial transform between two point sets. % % COEFFS = fitPolynomialTransform2d(PTS, PTSREF, DEGREE) % % Example % % See also % polynomialTransform2d, fitAffineTransform2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-11-05, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform %% Extract data % ensure degree is valid if nargin < 3 degree = 3; end % polygon coordinates xi = pts(:,1); yi = pts(:,2); nCoords = size(pts, 1); % check inputs have same size if size(ptsRef, 1) ~= nCoords error('fitPolynomialTransform2d:sizeError', ... 'input arrays must have same number of points'); end %% compute coefficient matrix % number of coefficients of polynomial transform nCoeffs = prod(degree + [1 2]) / 2; % initialize matrix A1 = zeros(nCoords, nCoeffs); % iterate over degrees iCoeff = 0; for iDegree = 0:degree % iterate over binomial coefficients of a given degree for k = 0:iDegree iCoeff = iCoeff + 1; A1(:, iCoeff) = ones(nCoords, 1) .* power(xi, iDegree-k) .* power(yi, k); end end % concatenate matrix for both coordinates A = kron(A1, [1 0;0 1]); %% solve linear system that minimizes least squares % create the vector of expected values b = ptsRef'; b = b(:); % solve the system coeffs = (A \ b)'; matgeom-1.2.4/inst/geom2d/PaxHeaders/boxToPolygon.m0000644000000000000000000000013214576357161017217 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/boxToPolygon.m0000644000175000017500000000466614576357161021013 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly = boxToPolygon(box) %BOXTOPOLYGON Convert a bounding box to a square polygon. % % poly = boxToPolygon(box) % Utility function that convert box data in [XMIN XMAX YMIN YMAX] format % to polygon data corresponding to the box boundary. The resulting POLY % is a 4-by-2 array. % % % Example % box = [ 10 50 20 40]; % poly = boxToPolygon(box) % poly = % 10 20 % 50 20 % 50 40 % 10 40 % % See also % boxes2d, polygons2d, boxToRect % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-09-10, using Matlab 8.6.0.267246 (R2015b) % Copyright 2017-2023 INRA - Cepia Software Platform % extreme coordinates xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % convert to polygon poly = [... xmin ymin; ... xmax ymin; ... xmax ymax; ... xmin ymax]; matgeom-1.2.4/inst/geom2d/PaxHeaders/drawBox.m0000644000000000000000000000013214576357161016162 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawBox.m0000644000175000017500000000620114576357161017741 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawBox(box, varargin) %DRAWBOX Draw a box defined by coordinate extents. % % drawBox(BOX) % Draws a box defined by its extent: BOX = [XMIN XMAX YMIN YMAX]. % % drawBox(..., NAME, VALUE) % Specifies drawing parameters using parameter name and value. See plot % function for syntax. % % drawBox(AX, ...) % Specifies the handle of the axis to draw on. % % Example % % define some points, compute their box, display everything % points = [10 30; 20 50; 20 20; 30 10;40 30;50 20]; % box = pointSetBounds(points); % figure; hold on; % drawPoint(points, 's'); % drawBox(box); % axis([0 60 0 60]); % % See also % drawOrientedBox, drawRect % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-12-10 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on if isAxisHandle(box) ax = box; box = varargin{1}; varargin(1) = []; else ax = gca; end % default values xmin = box(:,1); xmax = box(:,2); ymin = box(:,3); ymax = box(:,4); nBoxes = size(box, 1); r = zeros(nBoxes, 1); % iterate on boxes for i = 1:nBoxes % exract min and max values tx(1) = xmin(i); ty(1) = ymin(i); tx(2) = xmax(i); ty(2) = ymin(i); tx(3) = xmax(i); ty(3) = ymax(i); tx(4) = xmin(i); ty(4) = ymax(i); tx(5) = xmin(i); ty(5) = ymin(i); % display polygon r(i) = plot(ax, tx, ty, varargin{:}); end % format output if nargout > 0 varargout = {r}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/createRotation90.m0000644000000000000000000000013214576357161017710 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createRotation90.m0000644000175000017500000000733314576357161021476 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function mat = createRotation90(varargin) %CREATEROTATION90 Matrix of a rotation for 90 degrees multiples. % % MAT = createRotation90 % Returns the 3-by-3 matrix corresponding to a rotation by 90 degrees. % As trigonometric functions are explicitley converted to +1 or -1, the % resulting matrix obtained with this function is more precise than % the one obtained with createRotation. % % MAT = createRotation90(NUM) % Specifies the number of rotations to performs. NUM should be an integer % (possibly negative). % % Example % poly = [10 0;20 0;10 10]; % rot = createRotation90; % poly2 = transformPoint(poly, rot); % figure; hold on; axis equal; % drawPolygon(poly); % drawPolygon(poly2, 'm'); % legend('original', 'rotated'); % % % specify number of rotations, and center % rot = createRotation90(2, [10 10]); % poly3 = transformPoint(poly, rot); % drawPolygon(poly3, 'g'); % % See also % transforms2d, createRotation % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-06-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % default values num = 1; center = [0 0]; % process input arguments while ~isempty(varargin) var = varargin{1}; if isnumeric(var) && isscalar(var) % extract number of rotations num = mod(mod(var, 4) + 4, 4); elseif isnumeric(var) && length(var) == 2 % extract rotation center center = var; else % unknown argument error('MatGeom:createRotation90', ... 'Unable to parse input arguments'); end varargin(1) = []; end % determine rotation parameters switch num case 0 ct = 1; st = 0; case 1 ct = 0; st = 1; case 2 ct = -1; st = 0; case 3 ct = 0; st = -1; end % compute transform matrix mat = [ ... ct -st 0; ... st ct 0; ... 0 0 1]; % change center if needed if sum(center ~= [0 0]) > 0 tra = createTranslation(center); mat = tra * mat / tra; end matgeom-1.2.4/inst/geom2d/PaxHeaders/lineAngle.m0000644000000000000000000000013214576357161016452 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/lineAngle.m0000644000175000017500000000512414576357161020234 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = lineAngle(varargin) %LINEANGLE Computes angle between two straight lines. % % A = lineAngle(LINE); % Returns the angle between horizontal, right-axis and the given line. % Angle is given in radians, between 0 and 2*pi, in counter-clockwise % direction. % % A = lineAngle(LINE1, LINE2); % Returns the directed angle between the two lines. Angle is given in % radians between 0 and 2*pi, in counter-clockwise direction. % % See also % lines2d, angles2d, createLine, normalizeAngle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE nargs = length(varargin); if nargs == 1 % angle of one line with horizontal line = varargin{1}; theta = mod(atan2(line(:,4), line(:,3)) + 2*pi, 2*pi); elseif nargs==2 % angle between two lines theta1 = lineAngle(varargin{1}); theta2 = lineAngle(varargin{2}); theta = mod(bsxfun(@minus, theta2, theta1)+2*pi, 2*pi); end matgeom-1.2.4/inst/geom2d/PaxHeaders/drawOrientedBox.m0000644000000000000000000000013214576357161017654 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawOrientedBox.m0000644000175000017500000001065014576357161021436 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawOrientedBox(varargin) %DRAWORIENTEDBOX Draw centered oriented rectangle. % % Syntax % drawOrientedBox(BOX) % drawOrientedBox(BOX, 'PropertyName', propertyvalue, ...) % % Description % drawOrientedBox(OBOX) % Draws an oriented rectangle (or bounding box) on the current axis. % OBOX is a 1-by-5 row vector containing box center, dimension (length % and width) and orientation (in degrees): % OBOX = [CX CY LENGTH WIDTH THETA]. % % When OBOX is a N-by-5 array, the N boxes are drawn. % % drawOrientedBox(AX, ...) % Specifies the axis to draw to point in. AX should be a handle to a axis % object. By default, display on current axis. % % HB = drawOrientedBox(...) % Returns a handle to the created graphic object(s). Object style can be % modified using syntaw like: % set(HB, 'color', 'g', 'linewidth', 2); % % Example % % draw an ellipse together with its oriented box % elli = [30 40 60 30 20]; % figure; % drawEllipse(elli, 'linewidth', 2, 'color', 'g'); % hold on % box = [30 40 120 60 20]; % drawOrientedBox(box, 'color', 'k'); % axis equal; % % See also % orientedBox, drawPolygon, drawRect, drawBox, drawCenteredEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Parses input arguments % extract handle of axis to draw on [ax, varargin] = parseAxisHandle(varargin{:}); % extract shape primitive box = varargin{1}; varargin(1) = []; if length(varargin) > 4 && sum(cellfun(@isnumeric, varargin(1:4))) == 4 % input given as separate arguments cx = box; cy = varargin{1}; hl = varargin{2} / 2; hw = varargin{3} / 2; theta = varargin{4}; varargin = varargin(5:end); else % input given as packed array cx = box(:,1); cy = box(:,2); hl = box(:,3) / 2; hw = box(:,4) / 2; theta = box(:,5); end %% Pre-processing % allocate memory for graphical handle hr = zeros(length(cx), 1); % save hold state holdState = ishold(ax); hold(ax, 'on'); %% Draw each box % iterate on oriented boxes for i = 1:length(cx) % pre-compute angle data cot = cosd(theta(i)); sit = sind(theta(i)); % x and y shifts lc = hl(i) * cot; ls = hl(i) * sit; wc = hw(i) * cot; ws = hw(i) * sit; % coordinates of box vertices vx = cx(i) + [-lc + ws; lc + ws ; lc - ws ; -lc - ws ; -lc + ws]; vy = cy(i) + [-ls - wc; ls - wc ; ls + wc ; -ls + wc ; -ls - wc]; % draw polygons hr(i) = plot(ax, vx, vy, varargin{:}); end %% Post-processing % restore hold state if ~holdState hold(ax, 'off'); end % Format output if nargout > 0 varargout = {hr}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/transformVector.m0000644000000000000000000000013214576357161017752 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/transformVector.m0000644000175000017500000000625714576357161021544 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = transformVector(varargin) %TRANSFORMVECTOR Transform a vector with an affine transform. % % VECT2 = transformVector(VECT1, TRANS); % where VECT1 has the form [xv yv], and TRANS is a [2*2], [2*3] or [3*3] % matrix, returns the vector transformed with affine transform TRANS. % % Format of TRANS can be one of : % [a b] , [a b c] , or [a b c] % [d e] [d e f] [d e f] % [0 0 1] % % VECT2 = transformVector(VECT1, TRANS); % Also works when PTA is a [N*2] array of double. In this case, VECT2 has % the same size as VECT1. % % [vx2 vy2] = transformVector(vx1, vy1, TRANS); % Also works when vx1 and vy1 are arrays the same size. The function % transform each couple of (vx1, vy1), and return the result in % (vx2, vy2), which is the same size as (vx1 vy1). % % % See also % vectors2d, transforms2d, rotateVector, transformPoint % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-03-12 % Copyright 2007-2023 INRA - TPV URPOI - BIA IMASTE if length(varargin)==2 var = varargin{1}; vx = var(:,1); vy = var(:,2); trans = varargin{2}; elseif length(varargin)==3 vx = varargin{1}; vy = varargin{2}; trans = varargin{3}; else error('wrong number of arguments in "transformVector"'); end % compute new position of vector vx2 = vx*trans(1,1) + vy*trans(1,2); vy2 = vx*trans(2,1) + vy*trans(2,2); % format output if nargout==0 || nargout==1 varargout{1} = [vx2 vy2]; elseif nargout==2 varargout{1} = vx2; varargout{2} = vy2; end matgeom-1.2.4/inst/geom2d/PaxHeaders/fitAffineTransform2d.m0000644000000000000000000000013214576357161020571 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/fitAffineTransform2d.m0000644000175000017500000000727314576357161022362 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = fitAffineTransform2d(ref, src) %FITAFFINETRANSFORM2D Compute the affine transform that best register two point sets. % % TRANSFO = fitAffineTransform2d(REF, SRC) % Returns the affine transform matrix that minimizes the distance between % the reference point set REF and the point set SRC after transformation. % Both REF and SRC must by N-by-2 arrays with the same number of rows, % and the points must be in correspondence. % The function minimizes the sum of the squared distances: % CRIT = sum(distancePoints(REF, transformPoint(PTS, TRANSFO)).^2); % % Example % % computes the transform the register two ellipses % % create the reference poitn set % elli = [50 50 40 20 30]; % poly = resamplePolygonByLength(ellipseToPolygon(elli, 200), 5); % figure; axis equal; axis([0 100 0 100]); hold on; % drawPoint(poly, 'kx') % % create the point set to fit on the reference % trans0 = createRotation([20 60], -pi/8); % poly2 = transformPoint(poly, trans0); % poly2 = poly2 + randn(size(poly)) * 2; % drawPoint(poly2, 'b+'); % % compute the transform that project poly2 onto poly. % transfo = fitAffineTransform2d(poly, poly2); % poly2t = transformPoint(poly2, transfo); % drawPoint(poly2t, 'mo') % legend('Reference', 'Initial', 'Transformed'); % % See also % transforms2d, transformPoint, transformVector, % fitPolynomialTransform2d, registerICP, fitAffineTransform3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-07-31, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRAE - Cepia Software Platform % check number of points are equal N = size(src, 1); if size(ref, 1) ~= N error('Requires the same number of points for both arrays'); end % main matrix of the problem A = [... src(:,1) src(:,2) ones(N,1) zeros(N, 3) ; ... zeros(N, 3) src(:,1) src(:,2) ones(N,1) ]; % conditions initialisations B = [ref(:,1) ; ref(:,2)]; % compute coefficients using least square coefs = A\B; % format to a matrix trans = [coefs(1:3)' ; coefs(4:6)'; 0 0 1]; matgeom-1.2.4/inst/geom2d/PaxHeaders/circleToPolygon.m0000644000000000000000000000013214576357161017670 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/circleToPolygon.m0000644000175000017500000000677114576357161021463 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = circleToPolygon(circle, varargin) %CIRCLETOPOLYGON Convert a circle into a series of points. % % PTS = circleToPolygon(CIRC, N); % Converts the circle CIRC into a N-by-2 numeric array, containing the x % and y positions of vertices. % CIRC is given as [x0 y0 r], where x0 and y0 are coordinate of center, % and r is the radius. % % If CIRC is a N-by-4 array, the fourth value is used as the angle (with % respect to the x axis) of the first vertex, in radians. Default value % is 0, corresponding to initial vertex with right-most position. % % % P = circleToPolygon(CIRC); % uses a default value of N=64 vertices. % % Example % % simple example % poly = circleToPolygon([30 20 15], 16); % figure; hold on; % axis equal;axis([0 50 0 50]); % drawPolygon(poly, 'b'); % drawPoint(poly, 'bo'); % % % add a rotation angle to the first vertex position % figure; hold on; axis equal; axis([-12 12 -12 12]); % poly = circleToPolygon([0 0 10 pi/4], 10); % drawPolygon(poly, 'b'); drawVertices(poly); % % See also % circles2d, polygons2d, circleArcToPolyline, ellipseToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-04-06 % Copyright 2005-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % check input size if size(circle, 1) > 1 error('require circle to be 1-by-3 numeric array'); end % determines number of points N = 64; if ~isempty(varargin) N = varargin{1}; end % angular shift for initial vertex t0 = 0; if size(circle, 2) > 3 t0 = circle(1, 4); end % create circle t = linspace(0, 2*pi, N+1)' + t0; t(end) = []; % coordinates of circle points x = circle(1) + circle(3) * cos(t); y = circle(2) + circle(3) * sin(t); % format output if nargout == 1 varargout{1} = [x y]; elseif nargout == 2 varargout{1} = x; varargout{2} = y; end matgeom-1.2.4/inst/geom2d/PaxHeaders/orientedBoxToPolygon.m0000644000000000000000000000013214576357161020711 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/orientedBoxToPolygon.m0000644000175000017500000000554614576357161022503 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [tx, ty] = orientedBoxToPolygon(obox) %ORIENTEDBOXTOPOLYGON Convert an oriented box to a polygon (set of vertices). % % POLY = orientedBoxToPolygon(OBOX); % Converts the oriented box OBOX given either as [XC YC W H] or as % [XC YC W H THETA] into a 4-by-2 array of double, containing coordinates % of box vertices. % XC and YC are center of the box. W and H are the width and the height % (dimension in the main directions), and THETA is the orientation, in % degrees between 0 and 360. % % Example % OBOX = [20 10 40 20 0]; % RECT = orientedBoxToPolygon(OBOX) % RECT = % -20 -10 % 20 -10 % 20 10 % -20 10 % % % See also % polygons2d, orientedBox, drawOrientedBox, rectToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-04-06 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract box parameters theta = 0; x = obox(1); y = obox(2); w = obox(3) / 2; % easier to compute with w and h divided by 2 h = obox(4) / 2; if length(obox) > 4 theta = obox(5); end v = [cosd(theta); sind(theta)]; M = bsxfun (@times, [-1 1; 1 1; 1 -1; -1 -1], [w h]); tx = x + M * v; ty = y + M(4:-1:1,[2 1]) * v; if nargout <= 1 tx = [tx ty]; end matgeom-1.2.4/inst/geom2d/PaxHeaders/transforms2d.m0000644000000000000000000000013214576357161017200 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/transforms2d.m0000644000175000017500000000556414576357161020772 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function transforms2d(varargin) %TRANSFORMS2D Description of functions operating on transforms. % % By 'transform' we mean an affine transform. A planar affine transform % can be represented by a 3x3 matrix. % % Example % % create a translation by the vector [10 20]: % T = createTranslation([10 20]) % T = % 1 0 10 % 0 1 20 % 0 0 1 % % % apply a rotation on a polygon % poly = [0 0; 30 0;30 10;10 10;10 20;0 20]; % trans = createRotation([10 20], pi/6); % polyT = transformPoint(poly, trans); % % display the original and the rotated polygons % figure; hold on; axis equal; axis([-10 40 -10 40]); % drawPolygon(poly, 'k'); % drawPolygon(polyT, 'b'); % % % See also % createTranslation, createRotation, createRotation90, createScaling % createHomothecy, createLineReflection, createBasisTransform % transformPoint, transformVector, transformLine, transformEdge % rotateVector, principalAxesTransform, fitAffineTransform2d % polynomialTransform2d, fitPolynomialTransform2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('transforms2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/cubicBezierToPolyline.m0000644000000000000000000000013214576357161021021 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/cubicBezierToPolyline.m0000644000175000017500000000752114576357161022606 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cubicBezierToPolyline(points, varargin) %CUBICBEZIERTOPOLYLINE Compute equivalent polyline from bezier curve control. % % POLY = cubicBezierToPolyline(POINTS, N) % Creates a polyline with N edges from the coordinates of the 4 control % points stored in POINTS. % POINTS is either a 4-by-2 array (vertical concatenation of point % coordinates), or a 1-by-8 array (horizontal concatenation of point % coordinates). % The result is a (N-1)-by-2 array. % % POLY = cubicBezierToPolyline(POINTS) % Assumes N = 64 edges as default. % % [X Y] = cubicBezierToPolyline(...) % Returns the result in two separate arrays for X and Y coordinates. % % % Example % poly = cubicBezierToPolyline([0 0;5 10;10 5;10 0], 100); % drawPolyline(poly, 'linewidth', 2, 'color', 'g'); % % See also % drawBezierCurve, drawPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-10-06, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % default number of discretization steps N = 64; % check if discretization step is specified if ~isempty(varargin) var = varargin{1}; if length(var) == 1 && isnumeric(var) N = round(var); end end % parametrization variable for bezier (use N+1 points to have N edges) t = linspace(0, 1, N+1)'; % rename points if size(points, 2)==2 % case of points given as a 4-by-2 array p1 = points(1,:); c1 = points(2,:); c2 = points(3,:); p2 = points(4,:); else % case of points given as a 1-by-8 array, [X1 Y1 CX1 CX2..] p1 = points(1:2); c1 = points(3:4); c2 = points(5:6); p2 = points(7:8); end % compute coefficients of Bezier Polynomial, using polyval ordering coef(4, 1) = p1(1); coef(4, 2) = p1(2); coef(3, 1) = 3 * c1(1) - 3 * p1(1); coef(3, 2) = 3 * c1(2) - 3 * p1(2); coef(2, 1) = 3 * p1(1) - 6 * c1(1) + 3 * c2(1); coef(2, 2) = 3 * p1(2) - 6 * c1(2) + 3 * c2(2); coef(1, 1) = p2(1) - 3 * c2(1) + 3 * c1(1) - p1(1); coef(1, 2) = p2(2) - 3 * c2(2) + 3 * c1(2) - p1(2); % compute position of vertices x = polyval(coef(:, 1), t); y = polyval(coef(:, 2), t); if nargout <= 1 varargout = {[x y]}; else varargout = {x, y}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/circles2d.m0000644000000000000000000000013214576357161016426 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/circles2d.m0000644000175000017500000000530714576357161020213 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function circles2d(varargin) %CIRCLES2D Description of functions operating on circles. % % Circles are represented by their center and their radius: % C = [xc yc r]; % One sometimes considers orientation of circle, by adding an extra % boolean value in 4-th position, with value TRUE for direct (i.e. % turning Counter-clockwise) circles. % % Circle arcs are represented by their center, their radius, the starting % angle and the angle extent, both in degrees: % CA = [xc yc r theta0 dtheta]; % % Ellipses are represented by their center, their 2 semi-axis length, and % their angle (in degrees) with Ox direction. % E = [xc yc A B theta]; % % See also % ellipses2d, createCircle, createDirectedCircle, % isPointInCircle, isPointOnCircle, enclosingCircle, circumCircle % intersectLineCircle, intersectCircles, radicalAxis % circleToPolygon, circleArcToPolyline % drawCircle, drawCircleArc % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - Cepia Software Platform help('circles2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/centeredEdgeToEdge.m0000644000000000000000000000013214576357161020222 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/centeredEdgeToEdge.m0000644000175000017500000000500214576357161021777 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = centeredEdgeToEdge(cedge) %CENTEREDEDGETOEDGE Convert a centered edge to a two-points edge. % % EDGE = centeredEdgeToEdge(CEDGE) % Converts an edge represented using center, length and orientation to an % edge represented using coordinates of end points. % % Example % % example of conversion on a 'pythagorean' edge % cedge = [30 40 50 atand(3/4)]; % centeredEdgeToEdge(cedge) % ans = % 10 25 50 55 % % % See also % edges2d, drawCenteredEdge, drawOrientedBox % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-07-31, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % length and orientation len = cedge(:,3); ori = cedge(:,4); % x and y shifts around center dx = len * cosd(ori) / 2; dy = len * sind(ori) / 2; % coordinates of extremities edge = [cedge(:,1:2)-[dx dy] cedge(:,1:2)+[dx dy]]; matgeom-1.2.4/inst/geom2d/PaxHeaders/equivalentEllipse.m0000644000000000000000000000013214576357161020247 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/equivalentEllipse.m0000644000175000017500000000677314576357161022044 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ell = equivalentEllipse(points) %EQUIVALENTELLIPSE Equivalent ellipse of a set of points. % % ELL = equivalentEllipse(PTS); % Computes the ellips with the same moments up to the second order as the % set of points specified by the N-by-2 array PTS. % % The result has the following form: % ELL = [XC YC A B THETA], % with XC and YC being the center of mass of the point set, A and B being % the lengths of the equivalent ellipse (see below), and THETA being the % angle of the first principal axis with the horizontal (counted in % degrees between 0 and 180 in counter-clockwise direction). % A and B are the standard deviations of the point coordinates when % ellipse is aligned with the principal axes. % % Example % pts = randn(100, 2); % pts = transformPoint(pts, createScaling(5, 2)); % pts = transformPoint(pts, createRotation(pi/6)); % pts = transformPoint(pts, createTranslation(3, 4)); % ell = equivalentEllipse(pts); % figure(1); clf; hold on; % drawPoint(pts); % drawEllipse(ell, 'linewidth', 2, 'color', 'r'); % % See also % ellipses2d, drawEllipse, equivalentEllipsoid, principalAxes, % principalAxesTransform % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-02-21, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % ellipse center xc = mean(points(:,1)); yc = mean(points(:,2)); % recenter points x = points(:,1) - xc; y = points(:,2) - yc; % number of points n = size(points, 1); % equivalent parameters Ixx = sum(x.^2) / n; Iyy = sum(y.^2) / n; Ixy = sum(x.*y) / n; % compute ellipse semi-axis lengths common = sqrt( (Ixx - Iyy)^2 + 4 * Ixy^2); ra = sqrt(2) * sqrt(Ixx + Iyy + common); rb = sqrt(2) * sqrt(Ixx + Iyy - common); % compute ellipse angle in degrees theta = atan2(2 * Ixy, Ixx - Iyy) / 2; theta = rad2deg(theta); % create the resulting equivalent ellipse ell = [xc yc ra rb theta]; matgeom-1.2.4/inst/geom2d/PaxHeaders/drawCircle.m0000644000000000000000000000013214576357161016633 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawCircle.m0000644000175000017500000001062414576357161020416 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCircle(varargin) %DRAWCIRCLE Draw a circle on the current axis. % % drawCircle(X0, Y0, R); % Draw the circle with center (X0,Y0) and the radius R. If X0, Y0 and R % are column vectors of the same length, draw each circle successively. % % drawCircle(CIRCLE); % Concatenate all parameters in a Nx3 array, where N is the number of % circles to draw. % % drawCircle(CENTER, RADIUS); % Specify CENTER as Nx2 array, and radius as a Nx1 array. % % drawCircle(..., NSTEP); % Specify the number of edges that will be used to draw the circle. % Default value is 72, creating an approximation of one point for each 5 % degrees. % % drawCircle(..., NAME, VALUE); % Specifies plotting options as pair of parameters name/value. See plot % documentation for details. % % drawCircle(AX, ...) % Specifies the handle of the axis to draw on. % % H = drawCircle(...); % return handles to each created curve. % % Example % figure; % hold on; % drawCircle([10 20 30]); % drawCircle([15 15 40], 'color', 'r', 'linewidth', 2); % axis equal; % % See also % circles2d, drawCircleArc, drawEllipse, circleToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% Parse input arguments % extract handle of axis to draw on [ax, varargin] = parseAxisHandle(varargin{:}); % process input parameters var = varargin{1}; if size(var, 2) == 1 x0 = varargin{1}; y0 = varargin{2}; r = varargin{3}; varargin(1:3) = []; elseif size(var, 2) == 2 x0 = var(:,1); y0 = var(:,2); r = varargin{2}; varargin(1:2) = []; elseif size(var, 2) == 3 x0 = var(:,1); y0 = var(:,2); r = var(:,3); varargin(1) = []; else error('bad format for input in drawCircle'); end % default number of discretization steps N = 72; % check if discretization step is specified if ~isempty(varargin) var = varargin{1}; if isnumeric(var) && isscalar(var) N = round(var); varargin(1) = []; end end %% Pre-processing % ensure each parameter is column vector x0 = x0(:); y0 = y0(:); r = r(:); % parametrization variable for circle (use N+1 as first point counts twice) t = linspace(0, 2*pi, N+1); cot = cos(t); sit = sin(t); % empty array for graphic handles h = zeros(size(x0)); % save hold state holdState = ishold(ax); hold(ax, 'on'); %% Display each circle % compute discretization of each circle for i = 1:length(x0) xt = x0(i) + r(i) * cot; yt = y0(i) + r(i) * sit; h(i) = plot(ax, xt, yt, varargin{:}); end %% Post-processing % restore hold state if ~holdState hold(ax, 'off'); end if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/parallelLine.m0000644000000000000000000000013214576357161017160 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/parallelLine.m0000644000175000017500000000576514576357161020755 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = parallelLine(line, point) %PARALLELLINE Create a line parallel to another one. % % RES = parallelLine(LINE, POINT); % Returns the line with same direction vector than LINE and going through % the point given by POINT. % LINE is given as [x0 y0 dx dy] and POINT is [xp yp]. % % % RES = parallelLine(LINE, DIST); % Uses relative distance to specify position. The new line will be % located at distance DIST, counted positive in the right side of LINE % and negative in the left side. % % Examples % P1 = [20 30]; P2 = [50 10]; % L1 = createLine([50 10], [20 30]); % figure; hold on; axis equal; axis([0 60 0 50]); % drawPoint([P1; P2], 'ko'); % drawLine(L1, 'k'); % P = [30 40]; % drawPoint(P, 'ko'); % L2 = parallelLine(L1, P); % drawLine(L2, 'Color', 'b'); % % See also % lines2d, orthogonalLine, distancePointLine, parallelEdge % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE if size(point, 2) == 1 % use a distance. Compute position of point located at distance DIST on % the line orthogonal to the first one. point = pointOnLine([line(:,1) line(:,2) line(:,4) -line(:,3)], point); end % normal case: compute line through a point with given direction res = zeros(size(line, 1), 4); res(:, 1:2) = point; res(:, 3:4) = line(:, 3:4); matgeom-1.2.4/inst/geom2d/PaxHeaders/boxes2d.m0000644000000000000000000000013214576357161016122 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/boxes2d.m0000644000175000017500000000430214576357161017701 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function boxes2d(varargin) %BOXES2D Description of functions operating on bounding boxes. % % A box is represented as a set of limits in each direction: % BOX = [XMIN XMAX YMIN YMAX]. % % Boxes are used as result of computation for bounding boxes, and to clip % shapes. % % See also % boundingBox, clipPoints, clipLine, clipEdge, clipRay % mergeBoxes, intersectBoxes, randomPointInBox, boxToRect, boxToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - Cepia Software Platform help('boxes2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/createTranslation.m0000644000000000000000000000013214576357161020236 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createTranslation.m0000644000175000017500000000477014576357161022026 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createTranslation(varargin) %CREATETRANSLATION Create the 3*3 matrix of a translation. % % TRANS = createTranslation(DX, DY); % Returns the translation corresponding to DX and DY. % The returned matrix has the form : % [1 0 TX] % [0 1 TY] % [0 0 1] % % TRANS = createTranslation(VECTOR); % Returns the matrix corresponding to a translation by the vector [x y]. % % % See also % transforms2d, transformPoint, createRotation, createScaling % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % process input arguments if isempty(varargin) tx = 0; ty = 0; elseif length(varargin)==1 var = varargin{1}; tx = var(1); ty = var(2); else tx = varargin{1}; ty = varargin{2}; end % create the matrix representing the translation trans = [1 0 tx ; 0 1 ty ; 0 0 1]; matgeom-1.2.4/inst/geom2d/PaxHeaders/triangleGrid.m0000644000000000000000000000013214576357161017167 xustar0030 mtime=1710874225.114193368 30 atime=1710874225.114193368 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/triangleGrid.m0000644000175000017500000000473614576357161020761 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = triangleGrid(bounds, origin, size, varargin) %TRIANGLEGRID Generate triangular grid of points in the plane. % % usage % PTS = triangleGrid(BOUNDS, ORIGIN, SIZE) % generate points, lying in the window defined by BOUNDS, given in form % [xmin ymin xmax ymax], starting from origin with a constant step equal % to size. % SIZE is constant and is equals to the length of the sides of each % triangles. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-08-06 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE dx = size(1); dy = size(1)*sqrt(3); % consider two square grids with different centers pts1 = squareGrid(bounds, origin, [dx dy], varargin{:}); pts2 = squareGrid(bounds, origin + [dx dy]/2, [dx dy], varargin{:}); % gather points pts = [pts1;pts2]; % process output if nargout > 0 varargout{1} = pts; end matgeom-1.2.4/inst/geom2d/PaxHeaders/crackPattern2.m0000644000000000000000000000013214576357161017257 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/crackPattern2.m0000644000175000017500000001242714576357161021045 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges = crackPattern2(box, points, alpha, varargin) %CRACKPATTERN2 Create a (bounded) crack pattern tessellation. % % E = crackPattern2(BOX, POINTS, ALPHA) % create a crack propagation pattern wit following parameters : % - pattern is bounded by area BOX which is a polygon. % - each crack originates from points given in POINTS % - directions of each crack is given by a [NxM] array ALPHA, where M is % the number of rays emanating from each seed/ % - a crack stop when it reaches another already created crack. % - all cracks stop when they reach the border of the frame, given by box % (a serie of 4 points). % The result is a collection of edges, in the form [x1 y1 x2 y2]. % % E = crackPattern2(BOX, POINTS, ALPHA, SPEED) % Also specify speed of propagation of each crack. % % % See the result with : % figure; % drawEdge(E); % % See also drawEdge % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-25 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if ~isempty(varargin) speed = varargin{1}; else speed = ones(size(points, 1), 1); end % Compute line equations for each initial crack. % The 'Inf' at the end correspond to the position of the limit. % If an intersection point is found with another line, but whose position % is after this value, this means that another crack stopped it before it % reach the intersection point. NP = size(points, 1); lines = zeros(0, 5); for i = 1:size(alpha, 2) lines = [lines; points speed.*cos(alpha(:,i)) speed.*sin(alpha(:,i)) Inf*ones(NP, 1)]; %#ok end NL = size(lines, 1); % initialize lines for borders, but assign a very high speed, to be sure % borders will stop all cracks. dx = (box([2 3 4 1],1)-box([1 2 3 4],1))*max(speed)*5; dy = (box([2 3 4 1],2)-box([1 2 3 4],2))*max(speed)*5; % add borders to the lines set lines = [lines ; createLine(box, dx, dy) Inf*ones(4,1)]; edges = zeros(0, 4); while true modif = 0; % try to update each line for i=1:NL % initialize first point of edge edges(i, 1:2) = lines(i, 1:2); % compute intersections with all other lines pi = intersectLines(lines(i,:), lines); % compute position of all intersection points on the current line pos = linePosition(pi, lines(i,:)); % consider points to the right (positive position), and sort them indr = find(pos>1e-12 & pos~=Inf); [posr, indr2] = sort(pos(indr)); % look for the closest intersection to the right for i2=1:length(indr2) % index of intersected line il = indr(indr2(i2)); % position of point relative to intersected line pos2 = linePosition(pi(il, :), lines(il, :)); % depending on the sign of position, tests if the line2 can % stop the current line, or if it was stopped before if pos2>0 if pos2 0 varargout = {h}; end function h = drawEdge_2d(ax, edge, options) h = -1 * ones(size(edge, 1), 1); for i = 1:size(edge, 1) if isnan(edge(i,1)) continue; end h(i) = plot(ax, edge(i, [1 3]), edge(i, [2 4]), options{:}); end function h = drawEdge_3d(ax, edge, options) h = -1 * ones(size(edge, 1), 1); for i = 1:size(edge, 1) if isnan(edge(i,1)) continue; end h(i) = plot3(ax, edge(i, [1 4]), edge(i, [2 5]), edge(i, [3 6]), options{:}); end function [ax, edge, options] = parseInputArguments(varargin) % extract handle of axis to draw on [ax, varargin] = parseAxisHandle(varargin{:}); % find the number of arguments defining edges nbVal = 0; for i = 1:length(varargin) if isnumeric(varargin{i}) nbVal = nbVal+1; else % stop at the first non-numeric value break; end end % extract drawing options options = varargin(nbVal+1:end); % ensure drawing options have correct format if length(options) == 1 options = [{'color'}, options]; end % extract edges characteristics switch nbVal case 1 % all parameters in a single array edge = varargin{1}; case 2 % parameters are two points, or two arrays of points, of size N*2. p1 = varargin{1}; p2 = varargin{2}; edge = [p1 p2]; case 4 % parameters are 4 parameters of the edge : x1 y1 x2 and y2 edge = [varargin{1} varargin{2} varargin{3} varargin{4}]; case 6 % parameters are 6 parameters of the edge : x1 y1 z1 x2 y2 and z2 edge = [varargin{1} varargin{2} varargin{3} varargin{4} varargin{5} varargin{6}]; otherwise error('drawEdge:WrongNumberOfParameters', 'Wrong number of parameters'); end matgeom-1.2.4/inst/geom2d/PaxHeaders/isPointInCircle.m0000644000000000000000000000013214576357161017612 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPointInCircle.m0000644000175000017500000000501214576357161021370 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointInCircle(point, circle, varargin) %ISPOINTINCIRCLE Test if a point is located inside a given circle. % % B = isPointInCircle(POINT, CIRCLE) % Returns true if point is located inside the circle, i.e. if distance to % circle center is lower than the circle radius. % % B = isPointInCircle(POINT, CIRCLE, TOL) % Specifies the tolerance value % % Example: % isPointInCircle([1 0], [0 0 1]) % isPointInCircle([0 0], [0 0 1]) % returns true, whereas % isPointInCircle([1 1], [0 0 1]) % return false % % See also % circles2d, isPointOnCircle, isPointInEllipse, isPointOnline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-07 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); b = d-circle(:,3)<=tol; matgeom-1.2.4/inst/geom2d/PaxHeaders/drawEllipseArc.m0000644000000000000000000000013214576357161017455 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawEllipseArc.m0000644000175000017500000001272214576357161021241 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipseArc(varargin) %DRAWELLIPSEARC Draw an ellipse arc on the current axis. % % drawEllipseArc(ARC) % draw ellipse arc specified by ARC. ARC has the format: % ARC = [XC YC A B THETA T1 T2] % or: % ARC = [XC YC A B T1 T2] (isothetic ellipse) % with center (XC, YC), main axis of half-length A, second axis of % half-length B, and ellipse arc running from t1 to t2 (both in degrees, % in Counter-Clockwise orientation). % % Parameters can also be arrays. In this case, all arrays are suposed to % have the same size... % % drawEllipseArc(..., NAME, VALUE) % Specifies one or more parameters name-value pairs, as in the plot % function. % % drawEllipseArc(AX, ...) % Sepcifies the handle of theaxis to draw on. % % H = drawEllipseArc(...) % Returns handle(s) of the created graphic objects. % % Example % % draw an ellipse arc: center = [10 20], radii = 50 and 30, theta = 45 % arc = [10 20 50 30 45 -90 270]; % figure; % axis([-50 100 -50 100]); axis equal; % hold on % drawEllipseArc(arc, 'color', 'r') % % % draw another ellipse arc, between angles -60 and 70 % arc = [10 20 50 30 45 -60 (60+70)]; % figure; % axis([-50 100 -50 100]); axis equal; % hold on % drawEllipseArc(arc, 'LineWidth', 2); % ray1 = createRay([10 20], deg2rad(-60+45)); % drawRay(ray1) % ray2 = createRay([10 20], deg2rad(70+45)); % drawRay(ray2) % % See also % ellipses2d, drawEllipse, drawEllipseAxes, drawCircleArc % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-12-12 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% Extract input arguments % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % extract dawing style strings styles = {}; for i = 1:length(varargin) if ischar(varargin{i}) styles = varargin(i:end); varargin(i:end) = []; break; end end if length(varargin) == 1 ellipse = varargin{1}; x0 = ellipse(:,1); y0 = ellipse(:,2); a = ellipse(:,3); b = ellipse(:,4); if size(ellipse, 2)>6 theta = ellipse(:,5); start = ellipse(:,6); extent = ellipse(:,7); else theta = zeros(size(x0)); start = ellipse(:,5); extent = ellipse(:,6); end elseif length(varargin)>=6 x0 = varargin{1}; y0 = varargin{2}; a = varargin{3}; b = varargin{4}; if length(varargin)>6 theta = varargin{5}; start = varargin{6}; extent = varargin{7}; else theta = zeros(size(x0)); start = varargin{5}; extent = varargin{6}; end else error('drawEllipseArc: please specify center x, center y and radii a and b'); end %% Initialisation % allocate memory for handles h = zeros(size(x0)); % save hold state holdState = ishold(ax); hold(ax, 'on'); %% Drawing for i = 1:length(x0) % start and end angles t1 = deg2rad(start(i)); t2 = t1 + deg2rad(extent(i)); % vertices of ellipse t = linspace(t1, t2, 60); % convert angles to ellipse parametrisation sup = cos(t) > 0; t(sup) = atan(a(i) / b(i) * tan(t(sup))); t(~sup) = atan2(a(i) / b(i) * tan(2*pi - t(~sup)), -1); t = mod(t, 2*pi); % precompute cos and sin of theta (given in degrees) cot = cosd(theta(i)); sit = sind(theta(i)); % compute position of points xt = x0(i) + a(i)*cos(t)*cot - b(i)*sin(t)*sit; yt = y0(i) + a(i)*cos(t)*sit + b(i)*sin(t)*cot; h(i) = plot(ax, xt, yt, styles{:}); end %% Post-processing % restore hold state if ~holdState hold(ax, 'off'); end % process output argument if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/boundingBox.m0000644000000000000000000000013214576357161017032 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/boundingBox.m0000644000175000017500000000610314576357161020612 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = boundingBox(points) %BOUNDINGBOX Bounding box of a set of points. % % BOX = boundingBox(POINTS) % Returns the bounding box of the set of points POINTS. POINTS can be % either a N-by-2 or N-by-3 array. The result BOX is a 1-by-4 or 1-by-6 % array, containing: % [XMIN XMAX YMIN YMAX] (2D point sets) % [XMIN XMAX YMIN YMAX ZMIN ZMAX] (3D point sets) % % Example % % Draw the bounding box of a set of random points % points = rand(30, 2); % figure; hold on; % drawPoint(points, '.'); % box = boundingBox(points); % drawBox(box, 'r'); % % % Draw bounding box of a cubeoctehedron % [v e f] = createCubeOctahedron; % box3d = boundingBox(v); % figure; hold on; % drawMesh(v, f); % drawBox3d(box3d); % set(gcf, 'renderer', 'opengl') % axis([-2 2 -2 2 -2 2]); % view(3) % % See also % polygonBounds, drawBox % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-04-01, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % compute extreme x and y values xmin = min(points(:,1)); xmax = max(points(:,1)); ymin = min(points(:,2)); ymax = max(points(:,2)); if size(points, 2) > 2 % process case of 3D points zmin = min(points(:,3)); zmax = max(points(:,3)); % format as box 3D data structure box = [xmin xmax ymin ymax zmin zmax]; else % format as box data structure box = [xmin xmax ymin ymax]; end matgeom-1.2.4/inst/geom2d/PaxHeaders/createRay.m0000644000000000000000000000013214576357161016473 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createRay.m0000644000175000017500000000572714576357161020266 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ray = createRay(varargin) %CREATERAY Create a ray (half-line), from various inputs. % % RAY = createRay(POINT, ANGLE) % POINT is a N*2 array giving starting point of the ray, and ANGLE is the % orientation of the ray. % % RAY = createRay(X0, Y0, ANGLE) % Specify ray origin with 2 input arguments. % % RAY = createRay(P1, P2) % Create a ray starting from point P1 and going in the direction of point % P2. % % Ray is represented in a parametric form: [x0 y0 dx dy] % x = x0 + t*dx % y = y0 + t*dy; % for all t>0 % % Example % origin = [3 4]; % theta = pi/6; % ray = createRay(origin, theta); % figure(1); clf; hold on; % axis([0 10 0 10]); % drawRay(ray); % % See also % rays2d, createLine, points2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-18 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas if length(varargin)==2 p0 = varargin{1}; arg = varargin{2}; if size(arg, 2)==1 % second input is the ray angle ray = [p0 cos(arg) sin(arg)]; else % second input is another point ray = [p0 arg-p0]; end elseif length(varargin)==3 x = varargin{1}; y = varargin{2}; theta = varargin{3}; ray = [x y cos(theta) sin(theta)]; else error('Wrong number of arguments in ''createRay'' '); end matgeom-1.2.4/inst/geom2d/PaxHeaders/drawArrow.m0000644000000000000000000000013214576357161016524 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawArrow.m0000644000175000017500000001245614576357161020314 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawArrow(varargin) %DRAWARROW Draw an arrow on the current axis. % % drawArrow(x1, y1, x2, y2) % draws an arrow between the points (x1 y1) and (x2 y2). % % drawArrow([x1 y1 x2 y2]) % gives argument as a single array. % % drawArrow(..., L, W) % specifies length and width of the arrow. % % drawArrow(..., L, W, TYPE) % also specifies arrow type. TYPE can be one of the following : % 0: draw only two strokes % 1: fill a triangle % 0.5: draw a half arrow (try it to see ...) % % Arguments can be single values or array of size N-by-1. In this case, % the function draws multiple arrows. % % H = drawArrow(...) % return handle(s) to created arrow elements. % The handles are returned in a structure with the fields % 'body', 'wing' and 'head' containing the handles to the different % parts of the arrow(s). % % Example % t = linspace(0, 2*pi, 200); % figure; hold on; % plot(t, sin(t)); % drawArrow([2 -1 pi 0], .1, .05, .5) % % See also % drawEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-11-11, from drawEdge % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end if isempty (varargin) error ('should specify at least one argument'); end % parse arrow coordinates var = varargin{1}; if size (var, 2) == 4 x1 = var(:,1); y1 = var(:,2); x2 = var(:,3); y2 = var(:,4); varargin = varargin(2:end); elseif length (varargin) > 3 x1 = varargin{1}; y1 = varargin{2}; x2 = varargin{3}; y2 = varargin{4}; varargin = varargin(5:end); else error ('MatGeom:drawArrow:invalidArgumentNumber', ... 'wrong number of arguments, please read the doc'); end N = size (x1, 1); % default values l = 10 * ones (N, 1); % Body length w = 5 * ones (N, 1); % Head width r = 0.1 * ones (N, 1); % Head to body ratio h = zeros (N, 1); % Head type if ~isempty (varargin) % Parse parameters k = length (varargin); vartxt = 'lwrh'; cmd = ['%s = varargin{%d}; %s = %s(:);' ... 'if length (%s) < N; %s = %s(1) * ones (N , 1); end']; for i = 1:k v = vartxt(i); eval (sprintf (cmd, v, i, v, v, v, v, v)); end end hold on; oldHold = ishold(ax); if ~oldHold hold on; end axis equal; % angle of the edge theta = atan2(y2-y1, x2-x1); rl = r .* l; rh = r .* h; cT = cos (theta); sT = sin (theta); % point on the 'left' xa1 = x2 - rl .* cT - w .* sT / 2; ya1 = y2 - rl .* sT + w .* cT / 2; % point on the 'right' xa2 = x2 - rl .* cT + w .* sT / 2; ya2 = y2 - rl .* sT - w .* cT / 2; % point on the middle of the arrow xa3 = x2 - rh .* cT; ya3 = y2 - rh .* sT; % draw main edge tmp = line(ax, [x1.'; x2.'], [y1.'; y2.'], 'color', [0 0 1]); handle.body = tmp; % draw only 2 wings ind = find (h == 0); if ~isempty (ind) tmp = line ([xa1(ind).'; x2(ind).'], [ya1(ind).'; y2(ind).'], ... 'color', [0 0 1]); handle.wing(:,1) = tmp; tmp = line ([xa2(ind).'; x2(ind).'], [ya2(ind).'; y2(ind).'], ... 'color', [0 0 1]); handle.wing(:,2) = tmp; end % draw a full arrow ind = find (h ~= 0); if ~isempty(ind) tmp = patch (ax, ... [x2(ind) xa1(ind) xa3(ind) xa2(ind) x2(ind)].', ... [y2(ind) ya1(ind) ya3(ind) ya2(ind) y2(ind)].', [0 0 1]); handle.head = tmp; end % format output arguments if nargout > 0 varargout{1} = handle; end if ~oldHold hold off; end matgeom-1.2.4/inst/geom2d/PaxHeaders/isPointOnCircle.m0000644000000000000000000000013214576357161017620 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPointOnCircle.m0000644000175000017500000000466114576357161021407 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointOnCircle(point, circle, varargin) %ISPOINTONCIRCLE Test if a point is located on a given circle. % % B = isPointOnCircle(POINT, CIRCLE) % return true if point is located on the circle, i.e. if the distance to % the circle center equals the radius up to an epsilon value. % % B = isPointOnCircle(POINT, CIRCLE, TOL) % Specifies the tolerance value. % % Example: % isPointOnCircle([1 0], [0 0 1]) % returns true, whereas % isPointOnCircle([1 1], [0 0 1]) % return false % % See also % circles2d, isPointInCircle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-07 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); b = abs(d-circle(:,3))1 % arguments are POINTS, and MASS pts = var; mass = varargin{2}; else % arguments are PX and PY pts = [var varargin{2}]; end elseif nargin==3 % arguments are PX, PY, and MASS pts = [varargin{1} varargin{2}]; mass = varargin{3}; end %% compute centroid if isempty(mass) % no weight center = mean(pts); else % format mass to have sum equal to 1, and column format mass = mass(:)/sum(mass(:)); % compute weighted centroid center = sum(bsxfun(@times, pts, mass), 1); % equivalent to: % center = sum(pts .* mass(:, ones(1, size(pts, 2)))); end matgeom-1.2.4/inst/geom2d/PaxHeaders/drawBezierCurve.m0000644000000000000000000000013214576357161017657 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawBezierCurve.m0000644000175000017500000000646514576357161021452 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawBezierCurve(varargin) %DRAWBEZIERCURVE Draw a cubic bezier curve defined by 4 control points. % % drawBezierCurve(POINTS) % Draw the Bezier curve defined by the 4 control points stored in POINTS. % POINTS is either a 4-by-2 array (vertical concatenation of control % points coordinates), or a 1-by-8 array (horizontal concatenation of % control point coordinates). % % drawBezierCurve(..., PARAM, VALUE) % Specifies additional drawing parameters, see the line function for % details. % % drawBezierCurve(AX, ...); % Spcifies the handle of the axis to draw on. % % H = drawBezierCurve(...); % Return a handle to the created graphic object. % % % Example % drawBezierCurve([0 0;5 10;10 5;10 0]); % drawBezierCurve([0 0;5 10;10 5;10 0], 'linewidth', 2, 'color', 'g'); % % See also % drawPolyline, cubicBezierToPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-03-16, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end points = varargin{1}; varargin(1) = []; % default number of discretization steps N = 64; % check if discretization step is specified if ~isempty(varargin) var = varargin{1}; if length(var) == 1 && isnumeric(var) N = round(var); varargin(1) = []; end end % convert control coordinates to polyline poly = cubicBezierToPolyline(points, N); % draw the curve h = drawPolyline(ax, poly, varargin{:}); % eventually return a handle to the created object if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/distancePointEdge.m0000644000000000000000000000013214576357161020145 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/distancePointEdge.m0000644000175000017500000001010614576357161021723 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [dist, pos] = distancePointEdge(point, edge) %DISTANCEPOINTEDGE Minimum distance between a point and an edge. % % DIST = distancePointEdge(POINT, EDGE); % Return the euclidean distance between edge EDGE and point POINT. % EDGE has the form: [x1 y1 x2 y2], and POINT is [x y]. % % If EDGE is N-by-4 array, result is 1-by-4 array computed for each edge. % If POINT is a N-by-2 array, the result is a N-by-1 array. % If both POINT and EDGE are array, the result is computed for each % point-edge couple, and stored into a NP-by-NE array. % % [DIST POS] = distancePointEdge(POINT, EDGE); % Also returns the position of closest point on the edge. POS is % comprised between 0 (first point) and 1 (last point). % % Eaxmple % % Distance between a point and an edge % distancePointEdge([3 4], [0 0 10 0]) % ans = % 4 % % % Distance between several points and one edge % points = [10 15; 15 10; 30 10]; % edge = [10 10 20 10]; % distancePointEdge(points, edge) % ans = % 5 % 0 % 10 % % % Distance between a point a several edges % point = [14 33]; % edges = [10 30 20 30; 20 30 20 40;20 40 10 40;10 40 10 30]; % distancePointEdge(point, edges) % ans = % 3 6 7 4 % % % See also % edges2d, points2d, distancePoints, distancePointLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-07 % Copyright 2004-2023 INRA - BIA-BIBS % direction vector of each edge (row vectors) vx = (edge(:, 3) - edge(:,1))'; vy = (edge(:, 4) - edge(:,2))'; % squared length of edges, with a check of validity delta = vx .* vx + vy .* vy; invalidEdges = delta < eps; delta(invalidEdges) = 1; % difference of coordinates between point and edge first vertex % (NP-by-NE arrays) dx = bsxfun(@minus, point(:, 1), edge(:, 1)'); dy = bsxfun(@minus, point(:, 2), edge(:, 2)'); % compute position of points projected on the supporting line, by using % normalised dot product (NP-by-NE array) pos = bsxfun(@rdivide, bsxfun(@times, dx, vx) + bsxfun(@times, dy, vy), delta); % ensure degenerated edges are correclty processed (consider the first % vertex is the closest) pos(:, invalidEdges) = 0; % change position to ensure projected point is located on the edge pos(pos < 0) = 0; pos(pos > 1) = 1; % compute distance between point and its projection on the edge dist = hypot(bsxfun(@times, pos, vx) - dx, bsxfun(@times, pos, vy) - dy); matgeom-1.2.4/inst/geom2d/PaxHeaders/fitEllipse.m0000644000000000000000000000013214576357161016654 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/fitEllipse.m0000644000175000017500000001216414576357161020440 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function elli = fitEllipse(varargin) %FITELLIPSE Fit an ellipse to a set of 2D points. % % ELLI = fitEllipse(PTS) % % Example % elli = [50 40 30 10 20]; % pts = ellipseToPolygon(elli, 60) + randn(60,2); % figure; hold on; drawPoint(pts, 'ko'); % axis equal; axis([0 100 0 100]); % ellFit = fitEllipse(pts); % drawEllipse(ellFit, 'b') % % This is a rewrite of an original function from the authors cited below. % Changes from original submission include: % * convert angle of result ellipse to degrees (to comply with MatGeom % convention) % * update comments % % Authors: % Andrew Fitzgibbon, Maurizio Pilu, Bob Fisher % Reference: "Direct Least Squares Fitting of Ellipses", IEEE T-PAMI, 1999 % % https://fr.mathworks.com/matlabcentral/fileexchange/3215-fit_ellipse % % @Article{Fitzgibbon99, % author = "Fitzgibbon, A.~W.and Pilu, M. and Fisher, R.~B.", % title = "Direct least-squares fitting of ellipses", % journal = pami, % year = 1999, % volume = 21, % number = 5, % month = may, % pages = "476--480" % } % % See also % geom2d, ellipses2d, createEllipse, equivalentEllipse, fitLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-07-16, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Process input arguments if nargin==1 var = varargin{1}; X = var(:,1); Y = var(:,2); else X = varargin{1}; Y = varargin{2}; end %% Normalize data % recenter and reduce range mx = mean(X); my = mean(Y); sx = (max(X) - min(X)) / 2; sy = (max(Y) - min(Y)) / 2; x = (X-mx) / sx; y = (Y-my) / sy; % Force to column vectors x = x(:); y = y(:); %% Main processing % Build design matrix D = [ x.*x x.*y y.*y x y ones(size(x)) ]; % Build scatter matrix S = D' * D; % Build 6x6 constraint matrix C(6,6) = 0; C(1,3) = -2; C(2,2) = 1; C(3,1) = -2; % Solve eigensystem % Break into blocks tmpA = S(1:3,1:3); tmpB = S(1:3,4:6); tmpC = S(4:6,4:6); tmpD = C(1:3,1:3); tmpE = tmpC \ tmpB'; [evec_x, eval_x] = eig(tmpD \ (tmpA - tmpB*tmpE)); % Find the positive (as det(tmpD) < 0) eigenvalue I = real(diag(eval_x)) < 1e-8 & ~isinf(diag(eval_x)); % Extract eigenvector corresponding to negative eigenvalue A = real(evec_x(:,I)); % Recover the bottom half... evec_y = -tmpE * A; A = [A; evec_y]; % re-calibrate par = [ A(1)*sy*sy, ... A(2)*sx*sy, ... A(3)*sx*sx, ... -2*A(1)*sy*sy*mx - A(2)*sx*sy*my + A(4)*sx*sy*sy, ... -A(2)*sx*sy*mx - 2*A(3)*sx*sx*my + A(5)*sx*sx*sy, ... A(1)*sy*sy*mx*mx + A(2)*sx*sy*mx*my + A(3)*sx*sx*my*my ... - A(4)*sx*sy*sy*mx - A(5)*sx*sx*sy*my ... + A(6)*sx*sx*sy*sy ... ]'; %% Identify parameters % rotation angle theta = 0.5 * atan2(par(2), par(1) - par(3)); % pre-comptute trigonometrics cost = cos(theta); sint = sin(theta); sin2 = sint .* sint; cos2 = cost .* cost; cos_sin = sint .* cost; % Ao = par(6); Au = par(4) .* cost + par(5) .* sint; Av = -par(4) .* sint + par(5) .* cost; Auu = par(1) .* cos2 + par(3) .* sin2 + par(2) .* cos_sin; Avv = par(1) .* sin2 + par(3) .* cos2 - par(2) .* cos_sin; % ROTATED = [Ao Au Av Auu Avv] tuCentre = - Au./(2.*Auu); tvCentre = - Av./(2.*Avv); wCentre = Ao - Auu.*tuCentre.*tuCentre - Avv.*tvCentre.*tvCentre; uCentre = tuCentre .* cost - tvCentre .* sint; vCentre = tuCentre .* sint + tvCentre .* cost; Ru = -wCentre ./ Auu; Rv = -wCentre ./ Avv; Ru = sqrt(abs(Ru)) .* sign(Ru); Rv = sqrt(abs(Rv)) .* sign(Rv); % create row vector representing ellipse elli = [uCentre, vCentre, Ru, Rv, rad2deg(theta)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/hexagonalGrid.m0000644000000000000000000000013214576357161017330 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/hexagonalGrid.m0000644000175000017500000000754514576357161021123 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = hexagonalGrid(bounds, origin, size, varargin) %HEXAGONALGRID Generate hexagonal grid of points in the plane. % % usage: % PTS = hexagonalGrid(BOUNDS, ORIGIN, SIZE) % generate points, lying in the window defined by BOUNDS (=[xmin ymin % xmax ymax]), starting from origin with a constant step equal to size. % SIZE is constant and is equals to the length of the sides of each % hexagon. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-08-06 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE size = size(1); dx = 3*size; dy = size*sqrt(3); % consider two rectangular grids with shifted centers pts1 = squareGrid(bounds, origin + [0 0], [dx dy], varargin{:}); pts2 = squareGrid(bounds, origin + [dx/3 0], [dx dy], varargin{:}); pts3 = squareGrid(bounds, origin + [dx/2 dy/2], [dx dy], varargin{:}); pts4 = squareGrid(bounds, origin + [-dx/6 dy/2], [dx dy], varargin{:}); % gather points pts = [pts1;pts2;pts3;pts4]; % eventually compute also edges, clipped by bounds if nargout > 1 edges = zeros([0 4]); x0 = origin(1); y0 = origin(2); % find all x coordinate x1 = bounds(1) + mod(x0-bounds(1), dx); x2 = bounds(3) - mod(bounds(3)-x0, dx); lx = (x1:dx:x2)'; % horizontal edges: first find y's y1 = bounds(2) + mod(y0-bounds(2), dy); y2 = bounds(4) - mod(bounds(4)-y0, dy); ly = (y1:dy:y2)'; % number of points in each coord, and total number of points ny = length(ly); nx = length(lx); if bounds(1)-x1+dx < size disp('intersect bounding box'); end if bounds(3)-x2 < size disp('intersect 2'); edges = [edges;repmat(x2, [ny 1]) ly repmat(bounds(3), [ny 1]) ly]; x2 = x2-dx; lx = (x1:dx:x2)'; nx = length(lx); end for i = 1:length(ly) ind = (1:nx)'; tmpEdges = zeros(length(ind), 4); tmpEdges(ind, 1) = lx; tmpEdges(ind, 2) = ly(i); tmpEdges(ind, 3) = lx+size; tmpEdges(ind, 4) = ly(i); edges = [edges; tmpEdges]; %#ok end end % process output arguments if nargout > 0 varargout{1} = pts; if nargout > 1 varargout{2} = edges; end end matgeom-1.2.4/inst/geom2d/PaxHeaders/triangleArea.m0000644000000000000000000000013214576357161017152 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/triangleArea.m0000644000175000017500000000545514576357161020743 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function area = triangleArea(pt1, pt2, pt3) %TRIANGLEAREA Signed area of a triangle. % % AREA = triangleArea(P1, P2, P3) % Computes area of the triangle whose vertices are given by P1, P2 and % P3. Each vertex is a 1-by-2 row vector. % % AREA = triangleArea(PTS) % Concatenates vertex coordinates in a 3-by-2 array. Each row of the % array contains coordinates of one vertex. % % % Example % % Compute area of a Counter-Clockwise (CCW) oriented triangle % triangleArea([10 10], [30 10], [10 40]) % ans = % 300 % % % Compute area of a Clockwise (CW) oriented triangle % triangleArea([10 40], [30 10], [10 10]) % ans = % -300 % % See also % polygonArea, triangleArea3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-08-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % if data is given as one array, split vertices if nargin == 1 pt2 = pt1(2,:); pt3 = pt1(3,:); pt1 = pt1(1,:); end % compute individual vectors v12 = bsxfun(@minus, pt2, pt1); v13 = bsxfun(@minus, pt3, pt1); % compute area from cross product area = (v13(:,2) .* v12(:,1) - v13(:,1) .* v12(:,2)) / 2; matgeom-1.2.4/inst/geom2d/PaxHeaders/rectToBox.m0000644000000000000000000000013214576357161016465 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/rectToBox.m0000644000175000017500000000426414576357161020253 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = rectToBox(rect) %RECTTOBOX Convert rectangle data to box data. % % RECT = rectToBox(BOX) % Converts from rectangle representation to box representation. % BOX is given by [XMIN XMAX YMIN YMAX]. % RECT is given by [X0 Y0 WIDTH HEIGHT], with WIDTH and HEIGHT > 0 % % Example % rectToBox % % See also % boxToRect, drawBox, drawRect % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-08-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform box = [rect(:,1) rect(:,1)+rect(:,3) rect(:,2) rect(:,2)+rect(:,4)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/boxToRect.m0000644000000000000000000000013214576357161016465 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/boxToRect.m0000644000175000017500000000422414576357161020247 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function rect = boxToRect(box) %BOXTORECT Convert box data to rectangle data. % % RECT = boxToRect(BOX) % Converts from boxrepresentation to rectangle representation. % BOX is given by [XMIN XMAX YMIN YMAX]. % RECT is given by [X0 Y0 WIDTH HEIGHT], with WIDTH and HEIGHT > 0 % % See also % boxes2d, boxToPolygon, drawBox % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-08-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform rect = [box(:,1) box(:,3) box(:,2)-box(:,1) box(:,4)-box(:,3)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/midPoint.m0000644000000000000000000000013214576357161016337 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/midPoint.m0000644000175000017500000000621714576357161020125 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = midPoint(varargin) %MIDPOINT Middle point of two points or of an edge. % % MID = midPoint(P1, P2) % Compute the middle point of the two points P1 and P2. % % MID = midPoint(EDGE) % Compute the middle point of the edge given by EDGE. % EDGE has the format: [X1 Y1 X2 Y2], and MID has the format [XMID YMID], % with XMID = (X1+X2)/2, and YMID = (Y1+Y2)/2. % % [MIDX MIDY] = midPoint(...) % Return the result as two separate variables or arrays. % % Works also when EDGE is a N-by-4 array, in this case the result is a % N-by-2 array containing the midpoint of each edge. % % % Example % P1 = [10 20]; % P2 = [30 40]; % midPoint([P1 P2]) % ans = % 20 30 % % See also % edges2d, points2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-08-06, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform if nargin == 1 % input is an edge edge = varargin{1}; mid = [mean(edge(:, [1 3]), 2) mean(edge(:, [2 4]), 2)]; elseif nargin == 2 % input are two points p1 = varargin{1}; p2 = varargin{2}; % assert inputs are equal n1 = size(p1, 1); n2 = size(p2, 1); if n1~=n2 && min(n1, n2)>1 error('geom2d:midPoint', ... 'Inputs must have same size, or one must have length 1'); end % compute middle point mid = bsxfun(@plus, p1, p2) / 2; end % process output arguments if nargout<=1 varargout{1} = mid; else varargout = {mid(:,1), mid(:,2)}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/circumCircle.m0000644000000000000000000000013214576357161017160 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/circumCircle.m0000644000175000017500000000467214576357161020751 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = circumCircle(varargin) %CIRCUMCIRCLE Circumscribed circle of three points. % % CIRC = circumCircle(TRI) % CIRC = circumCircle(P1, P2, P3) % Compute circumcircle of a triangle given by 3 points. % % Example % T = [10 20; 70 20; 30 70]; % C = circumCircle(T); % figure; drawPolygon(T, 'linewidth', 2); % hold on; drawCircle(C); % axis equal; axis([0 100 0 100]); % % See also % circles2d, enclosingCircle, circumCenter % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-01, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % extract the three points [a, b, c] = parseThreePoints(varargin{:}); % circle center center = circumCenter(a, b, c); % radius r = distancePoints(center, a); % format output varargout = {[center r]}; matgeom-1.2.4/inst/geom2d/PaxHeaders/squareGrid.m0000644000000000000000000000013214576357161016662 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/squareGrid.m0000644000175000017500000000543614576357161020452 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = squareGrid(bounds, origin, size) %SQUAREGRID Generate equally spaces points in plane. % % usage % PTS = squareGrid(BOUNDS, ORIGIN, SIZE) % Generate points, lying in the window defined by BOUNDS (=[xmin ymin % xmax ymax]), starting from origin with a constant step equal to size. % % Example % PTS = squareGrid([0 0 10 10], [3 3], [4 2]) % will return points : % [3 1;7 1;3 3;7 3;3 5;7 5;3 7;7 7;3 9;7 9]; % % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-08-06 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % find all x coordinate x1 = bounds(1) + mod(origin(1)-bounds(1), size(1)); x2 = bounds(3) - mod(bounds(3)-origin(1), size(1)); lx = (x1:size(1):x2)'; % find all y coordinate y1 = bounds(2) + mod(origin(2)-bounds(2), size(2)); y2 = bounds(4) - mod(bounds(4)-origin(2), size(2)); ly = (y1:size(2):y2)'; % number of points in each coord, and total number of points ny = length(ly); nx = length(lx); np = nx*ny; % create points pts = zeros(np, 2); for i = 1:ny pts( (1:nx)'+(i-1)*nx, 1) = lx; pts( (1:nx)'+(i-1)*nx, 2) = ly(i); end % process output if nargout > 0 varargout{1} = pts; end matgeom-1.2.4/inst/geom2d/PaxHeaders/orientedBox.m0000644000000000000000000000013214576357161017036 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/orientedBox.m0000644000175000017500000001307014576357161020617 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function obox = orientedBox(points) %ORIENTEDBOX Minimum-width oriented bounding box of a set of points. % % OBOX = orientedBox(PTS) % Computes the oriented bounding box of a set of points. Oriented box is % defined by a center, two dimensions (the length and the width), and the % orientation of the length axis. Orientation is counted in degrees, % counter-clockwise. % % Example % % Draw oriented bounding box of an ellipse % elli = [30 40 40 20 30]; % pts = ellipseToPolygon(elli, 120); % obox = orientedBox(pts); % figure; hold on; % drawEllipse(elli); % drawOrientedBox(obox, 'm'); % % See also % drawOrientedBox, orientedBoxToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-03-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform %% initialisations % first, compute convex hull of the polygon inds = convhull(points(:,1), points(:,2)); hull = points(inds, :); % if first and last points are the same, remove the last one if inds(1) == inds(end) hull = hull(1:end-1, :); end % compute convex hull centroid, that corresponds to approximate % location of rectangle center center = mean(hull, 1); hull = bsxfun(@minus, hull, center); % number of hull vertices nV = size(hull, 1); % default values rotatedAngle = 0; minWidth = inf; minAngle = 0; % avoid degenerated cases if nV < 3 return; end % indices of vertices in extreme y directions [tmp, indA] = min(hull(:, 2)); %#ok [tmp, indB] = max(hull(:, 2)); %#ok caliperA = [ 1 0]; % Caliper A points along the positive x-axis caliperB = [-1 0]; % Caliper B points along the negative x-axis %% Find the direction with minimum width (rotating caliper algorithm) while rotatedAngle < pi % compute the direction vectors corresponding to each edge indA2 = mod(indA, nV) + 1; vectorA = hull(indA2, :) - hull(indA, :); indB2 = mod(indB, nV) + 1; vectorB = hull(indB2, :) - hull(indB, :); % Determine the angle between each caliper and the next adjacent edge % in the polygon angleA = vectorAngle(caliperA, vectorA); angleB = vectorAngle(caliperB, vectorB); % Determine the smallest of these angles angleIncrement = min(angleA, angleB); % Rotate the calipers by the smallest angle caliperA = rotateVector(caliperA, angleIncrement); caliperB = rotateVector(caliperB, angleIncrement); rotatedAngle = rotatedAngle + angleIncrement; % compute current width, and update opposite vertex if angleA < angleB line = createLine(hull(indA, :), hull(indA2, :)); width = distancePointLine(hull(indB, :), line); indA = mod(indA, nV) + 1; else line = createLine(hull(indB, :), hull(indB2, :)); width = distancePointLine(hull(indA, :), line); indB = mod(indB, nV) + 1; end % update minimum width and corresponding angle if needed if width < minWidth minWidth = width; minAngle = rotatedAngle; end end %% Compute box dimensions % orientation of the main axis theta = rad2deg(minAngle); % pre-compute trigonometric functions cot = cos(minAngle); sit = sin(minAngle); % elongation in direction of rectangle length x = hull(:,1); y = hull(:,2); x2 = x * cot + y * sit; y2 = - x * sit + y * cot; % compute extension along main directions xmin = min(x2); xmax = max(x2); ymin = min(y2); ymax = max(y2); % position of the center with respect to the centroid compute before dl = (xmax + xmin)/2; dw = (ymax + ymin)/2; % change coordinate from rectangle to user-space dx = dl * cot - dw * sit; dy = dl * sit + dw * cot; % coordinates of oriented box center center = center + [dx dy]; % size of the rectangle rectLength = xmax - xmin; rectWidth = ymax - ymin; % concatenate rectangle data obox = [center rectLength rectWidth theta]; matgeom-1.2.4/inst/geom2d/PaxHeaders/principalAxes.m0000644000000000000000000000013214576357161017356 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/principalAxes.m0000644000175000017500000000654714576357161021152 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = principalAxes(points) %PRINCIPALAXES Principal axes of a set of ND points. % % [CENTER, ROTMAT] = principalAxes(PTS) % [CENTER, ROTMAT, SCALES] = principalAxes(PTS) % Computes the principal axes of a set of points given in a N-by-ND array % and returns the result in two or three outputs: % CENTER is the centroid of the points, as a 1-by-ND row vector % ROTMAT represents the orientation of the point cloud, as a ND-by-ND % rotation matrix % SCALES is the scaling factor along each dimension, as a 1-by-ND row % vector. % % Example % pts = randn(100, 2); % pts = transformPoint(pts, createScaling(5, 2)); % pts = transformPoint(pts, createRotation(pi/6)); % pts = transformPoint(pts, createTranslation(3, 4)); % [center, rotMat] = principalAxes(pts); % % See also % equivalentEllipse, equivalentEllipsoid, principalAxesTransform % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-08-12, using Matlab 9.6.0.1072779 (R2019a) % Copyright 2019-2023 INRAE - Cepia Software Platform % compute centroid of points to estimate center center = mean(points); % compute the covariance matrix covPts = cov(points); % perform a principal component analysis to extract principal axes [rotMat, S] = svd(covPts); % extract length of each semi axis radii = sqrt(diag(S)); % sort axes from greater to lower [radii, ind] = sort(radii, 'descend'); radii = radii'; % format U to ensure first axis points to positive x direction rotMat = rotMat(ind, :); if rotMat(1,1) < 0 && size(points, 2) > 2 rotMat = -rotMat; % keep matrix determinant positive rotMat(:,3) = -rotMat(:,3); end % format output if nargout == 2 varargout = {center, rotMat}; elseif nargout == 3 varargout = {center, rotMat, radii}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/vectorAngle.m0000644000000000000000000000013214576357161017025 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/vectorAngle.m0000644000175000017500000001015614576357161020610 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function alpha = vectorAngle(v1, varargin) %VECTORANGLE Horizontal angle of a vector, or angle between 2 vectors. % % A = vectorAngle(V); % Returns angle between Ox axis and vector direction, in radians, in % counter-clockwise orientation. % The result is normalised between 0 and 2*PI. % % A = vectorAngle(V1, V2); % Returns the angle from vector V1 to vector V2, in counter-clockwise % order, in radians. % % A = vectorAngle(..., 'midAngle', MIDANGLE); % Specifies convention for angle interval. MIDANGLE is the center of the % 2*PI interval containing the result. See normalizeAngle for details. % % Example: % rad2deg(vectorAngle([2 2])) % ans = % 45 % rad2deg(vectorAngle([1 sqrt(3)])) % ans = % 60 % rad2deg(vectorAngle([0 -1])) % ans = % 270 % % See also % vectors2d, angles2d, normalizeAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-18 % Copyright 2007-2023 INRA - Cepia Software Platform %% Initializations % default values v2 = []; midAngle = pi; % normalize angles between 0 and 2*PI % process input arguments while ~isempty(varargin) var = varargin{1}; if isnumeric(var) && isscalar(var) % argument is normalization constant midAngle = varargin{1}; varargin(1) = []; elseif isnumeric(var) && size(var, 2) == 2 % argument is second vector v2 = varargin{1}; varargin(1) = []; elseif ischar(var) && length(varargin) >= 2 % argument is option given as string + value if strcmpi(var, 'cutAngle') || strcmpi(var, 'midAngle') midAngle = varargin{2}; varargin(1:2) = []; else error(['Unknown option: ' var]); end else error('Unable to parse inputs'); end end %% Case of one vector % If only one vector is provided, computes its angle if isempty(v2) % compute angle and format result in a 2*pi interval alpha = atan2(v1(:,2), v1(:,1)); % normalize within a 2*pi interval alpha = normalizeAngle(alpha + 2*pi, midAngle); return; end %% Case of two vectors % compute angle of each vector alpha1 = mod(atan2(v1(:,2), v1(:,1)), 2*pi); alpha2 = mod(atan2(v2(:,2), v2(:,1)), 2*pi); % difference alpha = bsxfun(@minus, alpha2, alpha1); % normalize within a 2*pi interval alpha = normalizeAngle(alpha + 2*pi, midAngle); matgeom-1.2.4/inst/geom2d/PaxHeaders/transformEllipse.m0000644000000000000000000000013214576357161020105 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/transformEllipse.m0000644000175000017500000000636414576357161021676 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = transformEllipse(elli, transfo) %TRANSFORMELLIPSE Apply an affine transformation to an ellipse. % % ELLI2 = transformEllipse(ELLI, TRANSFO) % % Example % % apply an arbitrary transform to a simple ellipse % elli = [5 4 3 2 0]; % rot = createRotation(pi/6); % sca = createScaling([2.5 1.5]); % tra = createTranslation([4 3]); % transfo = sca * rot * tra; % elli2 = transformEllipse(elli, transfo); % % display original and transformed ellipses % figure; hold on; axis equal; axis([0 20 0 20]); % drawEllipse(elli, 'k'); % drawEllipse(elli2, 'b'); % % Compare with transform on polygonal approximation % poly = ellipseToPolygon(elli, 100); % drawPolygon(transformPoint(poly, transfo), 'm'); % % Reference % https://math.stackexchange.com/questions/3076317/what-is-the-equation-for-an-ellipse-in-standard-form-after-an-arbitrary-matrix-t % % See also % ellipses2d, transforms2d, transformPoint % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-09-05, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % first extract coefficients of cartesian representation coeffs = ellipseCartesianCoefficients(elli); % writing the matrix of the general conic equation x^t * Q * x = 0 Q = [... coeffs(1) coeffs(2)/2 coeffs(4)/2; ... coeffs(2)/2 coeffs(3) coeffs(5)/2; ... coeffs(4)/2 coeffs(5)/2 coeffs(6)]; % compute the matrix form of the transformed ellipse Minv = inv(transfo); Q2 = Minv' * Q * Minv; coeffs2 = [Q2(1,1) 2*Q2(1,2) Q2(2,2) 2*Q2(1,3) 2*Q2(2,3) Q2(3,3)]; res = createEllipse('CartesianCoefficients', coeffs2); matgeom-1.2.4/inst/geom2d/PaxHeaders/drawLabels.m0000644000000000000000000000013214576357161016634 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawLabels.m0000644000175000017500000001004114576357161020410 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawLabels(varargin) %DRAWLABELS Draw labels at specified positions. % % drawLabels(X, Y, LBL) % Draws labels LBL at positions given by X and Y. % LBL can be either a string array, or a number array. In this case, % string are created by using sprintf function, using the '%.2f' format. % % drawLabels(POS, LBL) % Draws labels LBL at position specified by POS, where POS is a N-by-2 % numeric array. % % drawLabels(..., NUMBERS, FORMAT) % Creates labels using sprintf function, with the mask given by FORMAT % (e.g. '%03d' or '5.3f'), and the corresponding values. % % drawLabels(..., PNAME, PVALUE) % Specifies additional parameters to the created labels. See 'text' % properties for available values. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-12-15 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % check if enough inputs are given if isempty(varargin) error('wrong number of arguments in drawLabels'); end % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % process input parameters var = varargin{1}; if size(var, 2) == 1 % coordinates given as separate arguments if length(varargin) < 3 error('wrong number of arguments in drawLabels'); end px = var; py = varargin{2}; lbl = varargin{3}; varargin(1:3) = []; else % parameters given as a packed array if length(varargin) < 2 error('wrong number of arguments in drawLabels'); end px = var(:,1); py = var(:,2); lbl = varargin{2}; varargin(1:2) = []; end % format for displaying numeric values format = '%.2f'; if ~isempty(varargin) var1 = varargin{1}; if ischar(var1) && var1(1) == '%' format = varargin{1}; varargin(1) = []; end end if size(format, 1) == 1 && size(px, 1) > 1 format = repmat(format, size(px, 1), 1); end % compute the strings that have to be displayed labels = cell(length(px), 1); if isnumeric(lbl) for i = 1:length(px) labels{i} = sprintf(format(i,:), lbl(i)); end elseif ischar(lbl) for i = 1:length(px) labels{i} = lbl(i,:); end elseif iscell(lbl) labels = lbl; end labels = char(labels); % display the text h = text(px, py, labels, 'parent', ax, varargin{:}); % format output if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/createVector.m0000644000000000000000000000013214576357161017202 xustar0030 mtime=1710874225.118193365 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createVector.m0000644000175000017500000000454114576357161020766 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vect = createVector(p1, p2) %CREATEVECTOR Create a vector from two points. % % V12 = createVector(P1, P2) % Creates the vector V12, defined as the difference between coordinates % of points P1 and P2. % P1 and P2 are row vectors with ND elements, ND being the space % dimension. % % If one of the inputs is a N-by-Nd array, the other input is % automatically repeated, and the result is N-by-Nd. % % If both inputs have the same size, the result also have the same size. % % % Example % % See also % vectors2d, vectors3d, points2d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-12-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform vect = bsxfun(@minus, p2, p1); matgeom-1.2.4/inst/geom2d/PaxHeaders/minDistancePoints.m0000644000000000000000000000013214576357161020207 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.118193365 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/minDistancePoints.m0000644000175000017500000002014014576357161021764 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = minDistancePoints(p1, varargin) %MINDISTANCEPOINTS Minimal distance between several points. % % DIST = minDistancePoints(PTS) % Returns the minimum distance between all pairs of points in PTS. PTS % is a N-by-D array of values, N being the number of points and D the % dimension of the points. % % DIST = minDistancePoints(PTS1, PTS2) % Computes for each point in PTS1 the minimal distance to every point of % PTS2. PTS1 and PTS2 are N-by-D arrays, where N is the number of points, % and D is the dimension. Dimension must be the same for both arrays, but % number of points can be different. % The result is an array the same length as PTS1. % % % DIST = minDistancePoints(..., NORM) % Uses a user-specified norm. NORM=2 means euclidean norm (the default), % NORM=1 is the Manhattan (or "taxi-driver") distance. % Increasing NORM growing up reduces the minimal distance, with a limit % to the biggest coordinate difference among dimensions. % % % [DIST, I, J] = minDistancePoints(PTS) % Returns indices I and J of the 2 points which are the closest. DIST % verifies relation: % DIST = distancePoints(PTS(I,:), PTS(J,:)); % % [DIST, J] = minDistancePoints(PTS1, PTS2, ...) % Also returns the indices of points which are the closest. J has the % same size as DIST. It verifies relation: % DIST(I) = distancePoints(PTS1(I,:), PTS2(J,:)); % for I comprised between 1 and the number of rows in PTS1. % % Examples: % % minimal distance between random planar points % points = rand(20,2)*100; % minDist = minDistancePoints(points); % % % minimal distance between random space points % points = rand(30,3)*100; % [minDist ind1 ind2] = minDistancePoints(points); % minDist % distancePoints(points(ind1, :), points(ind2, :)) % % results should be the same % % % minimal distance between 2 sets of points % points1 = rand(30,2)*100; % points2 = rand(30,2)*100; % [minDists inds] = minDistancePoints(points1, points2); % minDists(10) % distancePoints(points1(10, :), points2(inds(10), :)) % % results should be the same % % % Find the (approximated) orthogonal projection onto an ellipse % elli = [50 50 40 20 30]; % poly = ellipseToPolygon(elli, 200); % figure; axis equal; axis([0 100 0 100]); hold on; % drawPolygon(poly, 'k') % pts = [20 20; 50 20; 80 30]; % [dists, inds] = minDistancePoints(pts, poly); % drawPoint(pts, 'bo'); % drawPoint(poly(inds,:), 'ko'); % drawEdge([pts poly(inds,:)], 'k') % % % See also % points2d, distancePoints, nndist, findClosestPoint, hausdorffDistance % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-15 % Copyright 2004-2023 INRAE - Cepia Software Platform %% Initialisations % default norm (euclidean) n = 2; % a single array is given one_array = true; % process input variables if nargin == 1 % specify only one array of points, not the norm p2 = p1; elseif nargin == 2 if isscalar(varargin{1}) % specify array of points and the norm n = varargin{1}; p2 = p1; else % specify two arrays of points p2 = varargin{1}; one_array = false; end elseif nargin == 3 % specify two array of points and the norm p2 = varargin{1}; n = varargin{2}; one_array = false; else error ('Wrong number of input arguments'); end % number of points in each array n1 = size(p1, 1); n2 = size(p2, 1); % dimensionality of points d = size(p1, 2); %% Computation of distances % allocate memory dist = zeros(n1, n2); % Compute difference of coordinate for each pair of point (n1-by-n2 array) % and for each dimension. -> dist is a n1-by-n2 array. % in 2D: dist = dx.*dx + dy.*dy; if n == inf % infinite norm corresponds to maximum absolute value of differences % in 2D: dist = max(abs(dx) + max(abs(dy)); for i = 1:d dist = max(dist, abs(bsxfun(@minus, p1(:,i), p2(:,i)'))); end else for i = 1:d dist = dist + abs(bsxfun(@minus, p1(:,i), p2(:,i)')).^n; end end % compute minimum distance, and indices if ~one_array % If two array of points where given [minSqDist, ind] = min(dist, [], 2); minDist = power(minSqDist, 1/n); [ind2, ind1] = ind2sub([n1 n2], ind); else % A single array was given dist = dist + diag(inf(n1,1)); % remove zeros from diagonal dist = dist(tril(true(n1, n1))); [minSqDist, ind] = min(dist); % index on packed lower triangular matrix minDist = power(minSqDist, 1/n); [ind2, ind1] = ind2sub_tril(n1, ind); ind2 = ind2(1); ind1 = ind1(1); ind = sub2ind([n1 n1], ind2, ind1); end %% format output parameters % format output depending on number of asked parameters if nargout <= 1 varargout{1} = minDist; elseif nargout == 2 % If two arrays are asked, 'ind' is an array of indices of p2, one for each % point in p1, corresponding to the result in minDist varargout{1} = minDist; varargout{2} = ind; elseif nargout == 3 % If only one array is asked, minDist is a scalar, ind1 and ind2 are 2 % indices corresponding to the closest points. varargout{1} = minDist; varargout{2} = ind1; varargout{3} = ind2; end end function [r, c] = ind2sub_tril (N, idx) % Convert a linear index to subscripts of a triangular matrix. % % [r, c] = ind2sub_tril (N, idx) % % An example of triangular matrix linearly indexed follows % % N = 4; % A = -repmat (1:N,N,1); % A = [A repmat (diagind, N,1) - A.']; % A = tril(A) % => A = % 1 0 0 0 % 2 5 0 0 % 3 6 8 0 % 4 7 9 10 % % The following example shows how to convert the linear index `6' in % the 4-by-4 matrix of the example into a subscript. % % [r, c] = ind2sub_tril (4, 6) % => r = 3 % c = 2 % % when idx is a row or column matrix of linear indeces then r and % c have the same shape as idx. % endOfRow = 0.5 * (1:N) .* (2*N:-1:N + 1); c = zeros(size(endOfRow)); for i = 1:length(endOfRow) ind = find(endOfRow <= idx - 1, 1, 'last') + 1; if isempty(ind) ind = 1; end c(i) = ind; end r = N - endOfRow(c) + idx ; end matgeom-1.2.4/inst/geom2d/PaxHeaders/crackPattern.m0000644000000000000000000000013214576357161017175 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/crackPattern.m0000644000175000017500000001555014576357161020763 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges = crackPattern(box, points, alpha, varargin) %CRACKPATTERN Create a (bounded) crack pattern tessellation. % % E = crackPattern(BOX, POINTS, ALPHA) % create a crack propagation pattern wit following parameters : % - pattern is bounded by area BOX given by [xmin xmax ymin ymax]. % - each crack originates from points given in POINTS % - direction of each crack is given by array ALPHA % - a crack stop when it reaches another already created crack. % - all cracks stop when they reach the border of the frame, given by box % (a serie of 4 points). % The result is a collection of edges, in the form [x1 y1 x2 y2]. % % E = crackPattern(BOX, POINTS, ALPHA, SPEED) % Also specify speed of propagation of each crack. % % % See the result with : % figure; % drawEdge(E); % % See also % drawEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-25 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if ~isempty(varargin) speed = varargin{1}; else speed = ones(size(points, 1), 1); end % Compute line equations for each initial crack. % The two 'Inf' at the end correspond to the position of the limit. % If an intersection point is found with another line, but whose position % is after this value, this means that another crack stopped it before it % reach the intersection point. % There is one 'end position' for each side of the crack. lines = [points speed.*cos(alpha) speed.*sin(alpha) Inf*ones(size(points, 1), 2)]; % initialize lines for borders, but assign a very high speed, to be sure % borders will stop all cracks. dx = (box([2 3 4 1],1)-box([1 2 3 4],1))*max(speed)*5; dy = (box([2 3 4 1],2)-box([1 2 3 4],2))*max(speed)*5; % add borders to the lines set lines = [lines ; createLine(box, dx, dy) Inf*ones(4,2)]; edges = zeros(0, 4); while true modif = 0; % try to update each line for i=1:size(points, 1) % compute intersections with all other lines pi = intersectLines(lines(i,:), lines); % compute position of all intersection points on the current line pos = linePosition(pi, lines(i,:)); % consider points to the right (positive position), and sort them indr = find(pos>=0 & pos~=Inf); [posr, indr2] = sort(pos(indr)); % look for the closest intersection to the right for i2=1:length(indr2) % index of intersected line il = indr(indr2(i2)); % position of point relative to intersected line pos2 = linePosition(pi(il, :), lines(il, :)); % depending on the sign of position, tests if the line2 can % stop the current line, or if it was stopped before if pos2>0 if pos20 if pos2 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/principalAxesTransform.m0000644000000000000000000000013214576357161021252 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/principalAxesTransform.m0000644000175000017500000000523214576357161023034 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = principalAxesTransform(pts) %PRINCIPALAXESTRANSFORM Align a set of points along its principal axes. % % TRANSFO = principalAxesTransform(PTS) % Computes the affine transform that will transform the input array PTS % such that its principal axes become aligned with main axes. % % [TRANSFO, PTS2] = principalAxesTransform(PTS) % Also returns the result of the transform applied to the points. % % Example % principalAxesTransform % % See also % principalAxes, equivalentEllipse, equivalentEllipsoid % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-03-06, using Matlab 8.6.0.267246 (R2015b) % Copyright 2020-2023 INRAE - Cepia Software Platform % computes principal axes [center, rotMat] = principalAxes(pts); % concatenate into affine matrix nd = size(pts, 2); transfo = inv([rotMat center'; zeros(1, nd) 1]); % format output if nargout < 2 varargout = transfo; else if nd == 2 pts2 = transformPoint(pts, transfo); else pts2 = transformPoint3d(pts, transfo); end varargout = {transfo, pts2}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/transformEdge.m0000644000000000000000000000013214576357161017354 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/transformEdge.m0000644000175000017500000000527014576357161021140 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dest = transformEdge(edge, trans) %TRANSFORMEDGE Transform an edge with an affine transform. % % EDGE2 = transformEdge(EDGE1, TRANS); % where EDGE1 has the form [x1 y1 x2 y1], and TRANS is a transformation % matrix, return the edge transformed with affine transform TRANS. % % Format of TRANS can be one of : % [a b] , [a b c] , or [a b c] % [d e] [d e f] [d e f] % [0 0 1] % % EDGE2 = transformEdge(EDGES, TRANS); % Also wotk when EDGES is a [N*4] array of double. In this case, EDGE2 % has the same size as EDGE. % % See also % edges2d, transforms2d, transformPoint, translation, rotation % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % allocate memory dest = zeros(size(edge)); % compute position for i=1:2 T = trans(i,1:2).'; dest(:,i) = edge(:,1:2) * T; dest(:,i+2) = edge(:,3:4) * T; end % add translation vector, if exist if size(trans, 2) > 2 dest = bsxfun (@plus, dest, trans([1:2 1:2],3).'); end matgeom-1.2.4/inst/geom2d/PaxHeaders/distancePointEllipse.m0000644000000000000000000000013214576357161020676 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/distancePointEllipse.m0000644000175000017500000000556314576357161022467 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [dist, proj] = distancePointEllipse(point, elli) %DISTANCEPOINTELLIPSE Distance from a point to an ellipse. % % DIST = distancePointEllipse(POINT, ELLI) % Computes the Euclidean distance between the point POINT and the ellipse % ELLI. % POINT may also be a N-by-2 array of point coordinates. In that case the % result is a N-by-1 array of distances. % % [DIST, PROJ] = distancePointEllipse(POINT, ELLI) % Also return the coordinates of the projection of the point onto the % ellipse. PROJ has same dimensions as the array POINT. % % Example % % create an ellipse % elli = [50 50 40 30 20]; % % generate points along a regular grid % [x, y] = meshgrid(1:100, 1:100); % pts = [x(:) y(:)]; % % compute distance map % distMap = reshape(distancePointEllipse(pts, elli), size(x)); % figure; imshow(distMap, []); colormap parula; % % % References: % https://blog.chatfield.io/simple-method-for-distance-to-ellipse/ % % See also % ellipses2d, projPointOnEllipse, distancePoints % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-07-17, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) proj = projPointOnEllipse(point, elli); dist = distancePoints(point, proj, 'diag'); matgeom-1.2.4/inst/geom2d/PaxHeaders/circleArcToPolyline.m0000644000000000000000000000013214576357161020462 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/circleArcToPolyline.m0000644000175000017500000000554714576357161022255 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = circleArcToPolyline(arc, N) %CIRCLEARCTOPOLYLINE Convert a circle arc into a series of points. % % P = circleArcToPolyline(ARC, N); % convert the circle ARC into a series of N points. % ARC is given in the format: [XC YC R THETA1 DTHETA] % where XC and YC define the center of the circle, R its radius, THETA1 % is the start of the arc and DTHETA is the angle extent of the arc. Both % angles are given in degrees. % N is the number of vertices of the resulting polyline, default is 65. % % The result is a N-by-2 array containing coordinates of the N points. % % [X Y] = circleArcToPolyline(ARC, N); % Return the result in two separate arrays with N lines and 1 column. % % % See also % circles2d, circleToPolygon, drawCircle, drawPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-05-22 % Copyright 2006-2023 INRA - Cepia Software Platform % default value for N if nargin < 2 N = 65; end % vector of positions t0 = deg2rad(arc(4)); t1 = t0 + deg2rad(arc(5)); t = linspace(t0, t1, N)'; % compute coordinates of vertices x = arc(1) + arc(3) * cos(t); y = arc(2) + arc(3) * sin(t); % format output if nargout <= 1 varargout = {[x y]}; else varargout = {x, y}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/polarPoint.m0000644000000000000000000000013214576357161016703 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/polarPoint.m0000644000175000017500000000571014576357161020466 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = polarPoint(varargin) %POLARPOINT Create a point from polar coordinates (rho + theta). % % POINT = polarPoint(RHO, THETA); % Creates a point using polar coordinate. THETA is angle with horizontal % (counted counter-clockwise, and in radians), and RHO is the distance to % origin. % % POINT = polarPoint(THETA) % Specify angle, radius RHO is assumed to be 1. % % POINT = polarPoint(POINT, RHO, THETA) % POINT = polarPoint(X0, Y0, RHO, THETA) % Adds the coordinate of the point to the coordinate of the specified % point. For example, creating a point with : % P = polarPoint([10 20], 30, 2*pi); % will give a result of [40 20]. % % % See also % points2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-03 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % default values x0 = 0; y0=0; rho = 1; theta =0; % process input parameters if length(varargin)==1 theta = varargin{1}; elseif length(varargin)==2 rho = varargin{1}; theta = varargin{2}; elseif length(varargin)==3 var = varargin{1}; x0 = var(:,1); y0 = var(:,2); rho = varargin{2}; theta = varargin{3}; elseif length(varargin)==4 x0 = varargin{1}; y0 = varargin{2}; rho = varargin{3}; theta = varargin{4}; end point = [x0 + rho.*cos(theta) , y0+rho.*sin(theta)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/createEllipse.m0000644000000000000000000000013214576357161017335 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createEllipse.m0000644000175000017500000000704114576357161021117 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function elli = createEllipse(type, varargin) %CREATEELLIPSE Create an ellipse, from various input types. % % ELLI = createEllipse('CartesianCoefficients', COEFFS) % ELLI = createEllipse(COEFFS) % Where COEFFS are the cartesian coefficients of the ellipse: % COEFFS = [A B C D E F] % such that the points on the ellipse follow: % A*X^2 + B*X*Y + C*Y^2 + D*X + E*Y + F = 0 % % % Example % elli = [30 20 40 20 30]; % coeffs = ellipseCartesianCoefficients(elli) % elli2 = createEllipse(coeffs) % elli2 = % 30.0000 20.0000 40.0000 20.0000 30.0000 % % % References % https://en.wikipedia.org/wiki/Ellipse#Standard_parametric_representation % % See also % ellipses2d, equivalentEllipse, fitEllipse, % ellipseCartesianCoefficients % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-09-05, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) if nargin == 1 && isnumeric(type) varargin = {type}; type = 'CartesianCoefficients'; end if strcmpi(type, 'CartesianCoefficients') % retrieve coefficients coeffs = varargin{1}; if ~isnumeric(coeffs) || any(size(coeffs) ~= [1 6]) error('Conversion from cartesian coefficients expects a 1-by-6 numeric array'); end % call coefficients with their usual names A = coeffs(1); B = coeffs(2); C = coeffs(3); D = coeffs(4); E = coeffs(5); F = coeffs(6); % retrieve center delta = B * B - 4 * A * C; xc = (2 * C * D - B * E) / delta; yc = (2 * A * E - B * D) / delta; % find orientation theta = 0.5 * atan(B / (A - C)); % retrieve length of semi-axes common = 2 * (A * E^2 + C * D^2 - B * D * E + delta * F); root = sqrt((A - C)^2 + B^2); a1 = -sqrt(common * ((A + C) + root)) / delta; a2 = -sqrt(common * ((A + C) - root)) / delta; elli = [xc yc a1 a2 rad2deg(theta)]; else error('Unknown representation type: ' + type); end matgeom-1.2.4/inst/geom2d/PaxHeaders/points2d.m0000644000000000000000000000013214576357161016316 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/points2d.m0000644000175000017500000000460614576357161020104 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points2d %POINTS2D Description of functions operating on points. % % A point is defined by its two cartesian coordinate, put into a row % vector of 2 elements: % P = [x y]; % % Several points are stored in a matrix with two columns, one for the % x-coordinate, one for the y-coordinate. % PTS = [x1 y1 ; x2 y2 ; x3 y3]; % % Example % P = [5 6]; % % See also % centroid, midPoint, boundingBox, polarPoint % distancePoints, minDistancePoints, nndist, circumCenter % isCounterClockwise, angle2Points, angle3Points, angleSort % transformPoint, clipPoints, drawPoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('points2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/parallelEdge.m0000644000000000000000000000013214576357161017135 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/parallelEdge.m0000644000175000017500000000537714576357161020731 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = parallelEdge(edge, dist) %PARALLELEDGE Edge parallel to another edge. % % EDGE2 = parallelEdge(EDGE, DIST) % Computes the edge parallel to the input edge EDGE and located at the % given signed distance DIST. % % Example % obox = [30 40 80 40 30]; % figure; hold on; axis equal; % drawOrientedBox(obox, 'LineWidth', 2); % edge1 = centeredEdgeToEdge(obox([1 2 3 5])); % edge2 = centeredEdgeToEdge(obox([1 2 4 5])+[0 0 0 90]); % drawEdge(edge1, 'LineWidth', 2, 'color', 'g'); % drawEdge(edge2, 'LineWidth', 2, 'color', 'g'); % drawEdge(parallelEdge(edge1, -30), 'LineWidth', 2, 'color', 'k'); % drawEdge(parallelEdge(edge2, -50), 'LineWidth', 2, 'color', 'k'); % % See also % edges2d, parallelLine, drawEdge, centeredEdgeToEdge, edgeToLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-07-31, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % compute the line parallel to the supporting line of edge line = parallelLine(edgeToLine(edge), dist); % result edge is given by line positions 0 and 1. res = [line(:, 1:2) line(:, 1:2)+line(:, 3:4)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/circumCenter.m0000644000000000000000000000013214576357161017177 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/circumCenter.m0000644000175000017500000000530314576357161020760 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = circumCenter(a, b, c) %CIRCUMCENTER Circumcenter of three points. % % CC = circumCenter(P1, P2, P3) % % Example % A = [10 10]; B = [30 10]; C = [10 20]; % circumCenter(A, B, C) % ans = % 20 15 % % % works also for multiple input points % circumCenter([A;A;A], [B;B;B], [C;C;C]) % ans = % 20 15 % 20 15 % 20 15 % % % See also % points2d, circles2d, circumCircle, centroid % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % pre-compute some terms ah = sum(a .^ 2, 2); bh = sum(b .^ 2, 2); ch = sum(c .^ 2, 2); dab = a - b; dbc = b - c; dca = c - a; % common denominator D = .5 ./ (a(:,1) .* dbc(:,2) + b(:,1) .* dca(:,2) + c(:,1) .* dab(:,2)); % center coordinates xc = (ah .* dbc(:,2) + bh .* dca(:,2) + ch .* dab(:,2) ) .* D; yc = -(ah .* dbc(:,1) + bh .* dca(:,1) + ch .* dab(:,1) ) .* D; if nargout <= 1 varargout = {[xc yc]}; else varargout = {xc, yc}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/isPointOnEdge.m0000644000000000000000000000013214576357161017263 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPointOnEdge.m0000644000175000017500000001322614576357161021047 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointOnEdge(point, edge, varargin) %ISPOINTONEDGE Test if a point belongs to an edge. % % Usage % B = isPointOnEdge(POINT, EDGE) % B = isPointOnEdge(POINT, EDGE, TOL) % % Description % B = isPointOnEdge(POINT, EDGE) % with POINT being [xp yp], and EDGE being [x1 y1 x2 y2], returns TRUE if % the point is located on the edge, and FALSE otherwise. % % B = isPointOnEdge(POINT, EDGE, TOL) % Specify an optilonal tolerance value TOL. The tolerance is given as a % fraction of the norm of the edge direction vector. Default is 1e-14. % % B = isPointOnEdge(POINTARRAY, EDGE) % B = isPointOnEdge(POINT, EDGEARRAY) % When one of the inputs has several rows, return the result of the test % for each element of the array tested against the single parameter. % % B = isPointOnEdge(POINTARRAY, EDGEARRAY) % When both POINTARRAY and EDGEARRAY have the same number of rows, % returns a column vector with the same number of rows. % When the number of rows are different and both greater than 1, returns % a Np-by-Ne matrix of booleans, containing the result for each couple of % point and edge. % % Examples % % create a point array % points = [10 10;15 10; 30 10]; % % create an edge array % vertices = [10 10;20 10;20 20;10 20]; % edges = [vertices vertices([2:end 1], :)]; % % % Test one point and one edge % isPointOnEdge(points(1,:), edges(1,:)) % ans = % 1 % isPointOnEdge(points(3,:), edges(1,:)) % ans = % 0 % % % Test one point and several edges % isPointOnEdge(points(1,:), edges)' % ans = % 1 0 0 1 % % % Test several points and one edge % isPointOnEdge(points, edges(1,:))' % ans = % 1 1 0 % % % Test N points and N edges % isPointOnEdge(points, edges(1:3,:))' % ans = % 1 0 0 % % % Test NP points and NE edges % isPointOnEdge(points, edges) % ans = % 1 0 0 1 % 1 0 0 0 % 0 0 0 0 % % % See also % edges2d, points2d, isPointOnLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % number of edges and of points nPoints = size(point, 1); nEdges = size(edge, 1); % adapt size of inputs if needed, and extract elements for computation if nPoints == nEdges % When the number of points and edges is the same, the one-to-one test % will be computed, so there is no need to repeat matrices dx = edge(:,3) - edge(:,1); dy = edge(:,4) - edge(:,2); lx = point(:,1) - edge(:,1); ly = point(:,2) - edge(:,2); elseif nPoints == 1 % one point, several edges dx = edge(:, 3) - edge(:, 1); dy = edge(:, 4) - edge(:, 2); lx = point(ones(nEdges, 1), 1) - edge(:, 1); ly = point(ones(nEdges, 1), 2) - edge(:, 2); elseif nEdges == 1 % several points, one edge dx = (edge(3) - edge(1)) * ones(nPoints, 1); dy = (edge(4) - edge(2)) * ones(nPoints, 1); lx = point(:, 1) - edge(1); ly = point(:, 2) - edge(2); else % Np points and Ne edges: % Create an array for each parameter, so that the result will be a % Np-by-Ne matrix of booleans (requires more memory, and uses repmat) x0 = repmat(edge(:, 1)', nPoints, 1); y0 = repmat(edge(:, 2)', nPoints, 1); dx = repmat(edge(:, 3)', nPoints, 1) - x0; dy = repmat(edge(:, 4)', nPoints, 1) - y0; lx = repmat(point(:, 1), 1, nEdges) - x0; ly = repmat(point(:, 2), 1, nEdges) - y0; end % test if point is located on supporting line b1 = abs(lx.*dy - ly.*dx) ./ (dx.*dx + dy.*dy) < tol; % compute position of point with respect to edge bounds % use different tests depending on line angle ind = abs(dx) > abs(dy); t = zeros(size(dx)); t(ind) = lx( ind) ./ dx( ind); t(~ind) = ly(~ind) ./ dy(~ind); % check if point is located between edge bounds b = t >- tol & t-1 < tol & b1; matgeom-1.2.4/inst/geom2d/PaxHeaders/registerICP.m0000644000000000000000000000013214576357161016734 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/registerICP.m0000644000175000017500000000577414576357161020531 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [trans, points] = registerICP(points, target, varargin) %REGISTERICP Fit affine transform by Iterative Closest Point algorithm. % % TRANS = registerICP(POINTS, TARGET) % Computes the affine transform that maps the shape defines by POINTS % onto the shape defined by the points TARGET. Both POINTS and TARGET are % N-by-2 array of point coordinates, not necessarily the same size. % The result TRANS is a 3-by-3 affine transform. % % TRANS = registerICP(POINTS, TARGET, NITER) % Specifies the number of iterations for the algorithm. % % [TRANS, POINTS2] = registerICP(...) % Also returns the set of transformed points. % % Example % registerICP % % See also % transforms2d, fitAffineTransform2d, registerPoints3dAffine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-02-24, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform nIter = 10; if ~isempty(varargin) nIter = varargin{1}; end % keep original points to transform them at each trans = [1 0 0;0 1 0;0 0 1]; for i = 1:nIter % identify target points for each source point inds = findClosestPoint(points, target); corrPoints = target(inds, :); % compute transform for current iteration trans_i = fitAffineTransform2d(points, corrPoints); % apply transform, and update cumulated transform points = transformPoint(points, trans_i); trans = trans_i * trans; end matgeom-1.2.4/inst/geom2d/PaxHeaders/drawEllipse.m0000644000000000000000000000013214576357161017027 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawEllipse.m0000644000175000017500000001160614576357161020613 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipse(varargin) %DRAWELLIPSE Draw an ellipse on the current axis. % % drawEllipse(ELLI); % Draws the ellipse ELLI in the form [XC YC RA RB THETA], with center % (XC, YC), with main axis of half-length RA and RB, and orientation % THETA in degrees counted counter-clockwise. % % drawEllipse(XC, YC, RA, RB); % drawEllipse(XC, YC, RA, RB, THETA); % Specifies ellipse parameters as separate arguments (old syntax). % % drawEllipse(..., NAME, VALUE); % Specifies drawing style of ellipse, see the help of plot function. % % H = drawEllipse(...); % Also returns handles to the created line objects. % % -> Parameters can also be arrays. In this case, all arrays are supposed % to have the same size. % % Example: % % Draw an ellipse centered in [50 50], with semi major axis length of % % 40, semi minor axis length of 20, and rotated by 30 degrees. % figure(1); clf; hold on; % drawEllipse([50 50 40 20 30]); % axis equal; axis([0 100 10 90]) % % % add another ellipse with different orientation and style % drawEllipse([50 50 40 20 -10], 'LineWidth', 2, 'Color', 'g'); % % % See also % ellipses2d, drawCircle, drawEllipseArc, drawEllipseAxes % fitEllipse, ellipseToPolygon, ellipsePoint, transformEllipse % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-12-11 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% Extract input arguments % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % extract dawing style strings styles = {}; for i = 1:length(varargin) if ischar(varargin{i}) styles = varargin(i:end); varargin(i:end) = []; break; end end % extract ellipse parameters if length(varargin) == 1 % ellipse is given in a single array ellipse = varargin{1}; x0 = ellipse(:, 1); y0 = ellipse(:, 2); a = ellipse(:, 3); b = ellipse(:, 4); if length(ellipse) > 4 theta = ellipse(:, 5); else theta = zeros(size(x0)); end elseif length(varargin) >= 4 % ellipse parameters given as separate arrays x0 = varargin{1}; y0 = varargin{2}; a = varargin{3}; b = varargin{4}; if length(varargin) > 4 theta = varargin{5}; else theta = zeros(size(x0)); end else error('drawEllipse: incorrect input arguments'); end %% Process drawing of a set of ellipses % angular positions of vertices t = linspace(0, 2*pi, 145); % empty array for graphic handles h = zeros(length(x0), 1); % save hold state holdState = ishold(ax); hold(ax, 'on'); %% Display each ellipse for i = 1:length(x0) % pre-compute rotation angles (given in degrees) cot = cosd(theta(i)); sit = sind(theta(i)); % compute position of points used to draw current ellipse xt = x0(i) + a(i) * cos(t) * cot - b(i) * sin(t) * sit; yt = y0(i) + a(i) * cos(t) * sit + b(i) * sin(t) * cot; % stores handle to graphic object h(i) = plot(ax, xt, yt, styles{:}); end %% post-processing % restore hold state if ~holdState hold(ax, 'off'); end % return handles if required if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/polynomialTransform2d.m0000644000000000000000000000013214576357161021061 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/polynomialTransform2d.m0000644000175000017500000000606114576357161022644 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = polynomialTransform2d(pts, coeffs) %POLYNOMIALTRANSFORM2D Apply a polynomial transform to a set of points. % % RES = polynomialTransform2d(PTS, COEFFS) % Transforms the input points PTS given as a N-by-2 array of coordinates % using the polynomial transform defined by PARAMS. % PARAMS given as [a0 b0 a1 b1 ... an bn] % % Example % coeffs = [0 0 1 0 0 1 0.1 0 0 0 0 0.1]; % % cte x y x^2 x*y y^2 % pts = rand(200, 2) * 2 - 1; % pts2 = polynomialTransform2d(pts, coeffs); % figure; hold on; % drawPoint(pts); % drawPoint(pts2, 'g'); % % See also % transformPoint, fitPolynomialTransform2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-09-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform x = pts(:,1); y = pts(:,2); nPoints = length(x); xCoeffs = coeffs(1:2:end); yCoeffs = coeffs(2:2:end); nCoeffs = length(xCoeffs); % allocate memory for result x2 = zeros(nPoints, 1); y2 = zeros(nPoints, 1); % degree from coefficient number degree = sqrt(9/4 - 4*(1 - nCoeffs)/2) - 1.5; % iterate over degrees iCoeff = 0; for iDegree = 0:degree % iterate over binomial coefficients of a given degree for k = 0:iDegree iCoeff = iCoeff + 1; tmp = power(x, iDegree-k) .* power(y, k); x2 = x2 + xCoeffs(iCoeff) .* tmp; y2 = y2 + yCoeffs(iCoeff) .* tmp; end end res = [x2 y2]; matgeom-1.2.4/inst/geom2d/PaxHeaders/drawVector.m0000644000000000000000000000013214576357161016674 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawVector.m0000644000175000017500000000631214576357161020456 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawVector(varargin) %DRAWVECTOR Draw vector at a given position. % % drawVector(POS, VECT) % Draws the 2D or 3D vector VECT at the position POS. % POS should be a N-by-2 or N-by-3 array containing position of vector % origins, and VECT should be a N-by-2 or N-by-3 array containing the % direction of the vectors. % % drawVector(POS, VECT, OPTS) % Specifies additional drawing options that will be provided to the % 'quiver' or 'quiver3' function. % % Example % figure; hold on; % drawVector([1 2], [3 2]); % drawVector([1 2], [-2 3]); % axis equal; % % See also % quiver, drawVector3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-03-18, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % retrieve position and direction of vector pos = varargin{1}; vect = varargin{2}; varargin(1:2) = []; % check input dimension nd = size(pos, 2); if size(vect, 2) ~= nd error('input vector and position must have same dimension'); end if nd == 2 % Display 2D vectors h = quiver(ax, pos(:, 1), pos(:, 2), vect(:, 1), vect(:, 2), 0, varargin{:}); elseif nd == 3 % Display 3D vectors h = quiver3(ax, pos(:, 1), pos(:, 2), pos(:, 3), ... vect(:, 1), vect(:, 2), vect(:, 3), 0, varargin{:}); else error('Can not display vectors of dimension > 3'); end % format output if nargout > 0 varargout{1} = h; end matgeom-1.2.4/inst/geom2d/PaxHeaders/distancePoints.m0000644000000000000000000000013214576357161017543 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/distancePoints.m0000644000175000017500000001203114576357161021320 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dist = distancePoints(p1, p2, varargin) %DISTANCEPOINTS Compute distance between two points. % % D = distancePoints(P1, P2) % Return the Euclidean distance between points P1 and P2. % % If P1 and P2 are two arrays of points, result is a N1-by-N2 array % containing distance between each point of P1 and each point of P2. % % D = distancePoints(P1, P2, NORM) % Compute distance using the specified norm. NORM=2 corresponds to usual % euclidean distance, NORM=1 corresponds to Manhattan distance, NORM=inf % is assumed to correspond to maximum difference in coordinate. Other % values (>0) can be specified. % % D = distancePoints(..., 'diag') % compute only distances between P1(i,:) and P2(i,:). % % See also % points2d, minDistancePoints, nndist, hausdorffDistance % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-02-24 % Copyright 2004-2023 INRA - Cepia Software Platform %% Setup options % default values diag = false; norm = 2; % check first argument: norm or diag if ~isempty(varargin) var = varargin{1}; if isnumeric(var) norm = var; elseif strncmp('diag', var, 4) diag = true; end varargin(1) = []; end % check last argument: diag if ~isempty(varargin) var = varargin{1}; if strncmp('diag', var, 4) diag = true; end end % number of points in each array and their dimension n1 = size(p1, 1); n2 = size(p2, 1); d = size(p1, 2); if diag % compute distance only for apparied couples of pixels dist = zeros(n1, 1); if norm == 2 % Compute euclidian distance. this is the default case % Compute difference of coordinate for each pair of point % and for each dimension. -> dist is a [n1*n2] array. for i = 1:d dist = dist + (p2(:,i)-p1(:,i)).^2; end dist = sqrt(dist); elseif norm == inf % infinite norm corresponds to maximal difference of coordinate for i = 1:d dist = max(dist, abs(p2(:,i)-p1(:,i))); end else % compute distance using the specified norm. for i = 1:d dist = dist + power((abs(p2(:,i)-p1(:,i))), norm); end dist = power(dist, 1/norm); end else % compute distance for all couples of pixels dist = zeros(n1, n2); if norm == 2 % Compute euclidian distance. This is the default case. % Compute difference of coordinate for each pair of point % and for each dimension. -> dist is a [n1*n2] array. for i = 1:d % equivalent to: % dist = dist + ... % (repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1])).^2; dist = dist + bsxfun (@minus, p1(:,i), p2(:, i)').^2; end dist = sqrt(dist); elseif norm == inf % infinite norm corresponds to maximal difference of coordinate for i = 1:d dist = max(dist, abs(bsxfun (@minus, p1(:,i), p2(:, i)'))); end else % compute distance using the specified norm. for i = 1:d % equivalent to: % dist = dist + power((abs(repmat(p1(:,i), [1 n2]) - ... % repmat(p2(:,i)', [n1 1]))), norm); dist = dist + power(abs(bsxfun(@minus, p1(:,i), p2(:, i)')), norm); end dist = power(dist, 1/norm); end end matgeom-1.2.4/inst/geom2d/PaxHeaders/intersectCircles.m0000644000000000000000000000013214576357161020061 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/intersectCircles.m0000644000175000017500000001063614576357161021647 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = intersectCircles(circle1, circle2) %INTERSECTCIRCLES Intersection points of two circles. % % POINTS = intersectCircles(CIRCLE1, CIRCLE2) % Computes the intersetion point of the two circles CIRCLE1 and CIRCLE1. % Both circles are given with format: [XC YC R], with (XC,YC) being the % coordinates of the center and R being the radius. % POINTS is a 2-by-2 array, containing coordinate of an intersection % point on each row. % In the case of tangent circles, the intersection is returned twice. It % can be simplified by using the 'unique' function. % % Example % % intersection points of two distant circles % c1 = [0 0 10]; % c2 = [10 0 10]; % pts = intersectCircles(c1, c2) % pts = % 5 -8.6603 % 5 8.6603 % % % intersection points of two tangent circles % c1 = [0 0 10]; % c2 = [20 0 10]; % pts = intersectCircles(c1, c2) % pts = % 10 0 % 10 0 % pts2 = unique(pts, 'rows') % pts2 = % 10 0 % % References % http://local.wasp.uwa.edu.au/~pbourke/geometry/2circle/ % http://mathworld.wolfram.com/Circle-CircleIntersection.html % % See also % circles2d, intersectLineCircle, radicalAxis % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-01-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % adapt sizes of inputs n1 = size(circle1, 1); n2 = size(circle2, 1); if n1 ~= n2 if n1 > 1 && n2 == 1 circle2 = repmat(circle2, n1, 1); elseif n2 > 1 && n1 == 1 circle1 = repmat(circle1, n2, 1); else error('Both input should have same number of rows'); end end % extract center and radius of each circle center1 = circle1(:, 1:2); center2 = circle2(:, 1:2); r1 = circle1(:,3); r2 = circle2(:,3); % allocate memory for result nPoints = length(r1); points = NaN * ones(2*nPoints, 2); % distance between circle centers d12 = distancePoints(center1, center2, 'diag'); % get indices of circle couples with intersections inds = d12 >= abs(r1 - r2) & d12 <= (r1 + r2); if sum(inds) == 0 return; end % angle of line from center1 to center2 angle = angle2Points(center1(inds,:), center2(inds,:)); % position of intermediate point, located at the intersection of the % radical axis with the line joining circle centers d1m = d12(inds) / 2 + (r1(inds).^2 - r2(inds).^2) ./ (2 * d12(inds)); tmp = polarPoint(center1(inds, :), d1m, angle); % distance between intermediate point and each intersection point h = sqrt(r1(inds).^2 - d1m.^2); % indices of valid intersections inds2 = find(inds)*2; inds1 = inds2 - 1; % create intersection points points(inds1, :) = polarPoint(tmp, h, angle - pi/2); points(inds2, :) = polarPoint(tmp, h, angle + pi/2); matgeom-1.2.4/inst/geom2d/PaxHeaders/createHomothecy.m0000644000000000000000000000013214576357161017677 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createHomothecy.m0000644000175000017500000000517414576357161021466 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function T = createHomothecy(point, ratio) %CREATEHOMOTHECY Create the the 3x3 matrix of an homothetic transform. % % TRANS = createHomothecy(POINT, K); % POINT is the center of the homothecy, K is its factor. % TRANS is a 3-by-3 matrix representing the homothetic transform in % homogeneous coordinates. % % Example: % % p = [0 0; 1 0; 0 1]; % s = [-0.5 0.4]; % T = createHomothecy (s, 1.5); % pT = transformPoint (p, T); % drawPolygon (p,'-b') % hold on; % drawPolygon (pT, '-r'); % % drawEdge (p(:,1), p(:,2), pT(:,1), pT(:,2), ... % 'color', 'k','linestyle','--') % hold off % axis tight equal % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-01-20 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE point = point(:); if length (point) > 2 error('Only one point accepted.'); end if length (ratio) > 1 error('Only one ratio accepted.'); end T = diag ([ratio ratio 1]); T(1:2,3) = point .* (1 - ratio); matgeom-1.2.4/inst/geom2d/PaxHeaders/angle2Points.m0000644000000000000000000000013214576357161017121 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/angle2Points.m0000644000175000017500000000517514576357161020711 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = angle2Points(varargin) %ANGLE2POINTS Compute horizontal angle between 2 points. % % ALPHA = angle2Points(P1, P2), % Pi are either [1*2] arrays, or [N*2] arrays, in this case ALPHA is a % [N*1] array. The angle computed is the horizontal angle of the line % (P1 P2) % Result is always given in radians, between 0 and 2*pi. % % See also % points2d, angles2d, angle3points, normalizeAngle, vectorAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-03-02 % Copyright 2007-2023 INRA - Cepia Software Platform % process input arguments if length(varargin)==2 p1 = varargin{1}; p2 = varargin{2}; elseif length(varargin)==1 var = varargin{1}; p1 = var(1,:); p2 = var(2,:); end % ensure data have correct size n1 = size(p1, 1); n2 = size(p2, 1); if n1~=n2 && min(n1, n2)>1 error('angle2Points: wrong size for inputs'); end % angle of line (P2 P1), between 0 and 2*pi. dp = bsxfun(@minus, p2, p1); theta = mod(atan2(dp(:,2), dp(:,1)) + 2*pi, 2*pi); matgeom-1.2.4/inst/geom2d/PaxHeaders/rays2d.m0000644000000000000000000000013214576357161015760 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/rays2d.m0000644000175000017500000000476414576357161017553 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function rays2d(varargin) %RAYS2D Description of functions operating on planar rays. % % A ray is defined by a point (its origin), and a vector (its % direction). The different parameters are bundled into a row vector: % RAY = [x0 y0 dx dy]; % % The ray contains all the points (x,y) such that: % x = x0 + t*dx % y = y0 + t*dy; % for all t>0 % % Contrary to a (straight) line, the points located before the origin do % not belong to the ray. % However, as rays and lines have the same representation, some functions % working on lines are also working on rays (like 'transformLine'). % % See also % points2d, vectors2d, lines2d % createRay, bisector, isPointOnRay % clipRay, drawRay % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('rays2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/medianLine.m0000644000000000000000000000013214576357161016621 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/medianLine.m0000644000175000017500000000737614576357161020416 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = medianLine(varargin) %MEDIANLINE Create a median line between two points. % % L = medianLine(P1, P2); % Create the median line of points P1 and P2, that is the line containing % all points located at equal distance of P1 and P2. % % L = medianLine(PTS); % Creates the median line of 2 points, given as a 2*2 array. Array has % the form: % [ [ x1 y1 ] ; [ x2 y2 ] ] % % L = medianLine(EDGE); % Creates the median of the edge. Edge is a 1*4 array, containing [X1 Y1] % coordinates of first point, and [X2 Y2], the coordinates of the second % point. % % Example % % Draw the median line of two points % P1 = [10 20]; % P2 = [30 50]; % med = medianLine(P1, P2); % figure; axis square; axis([0 100 0 100]); % drawEdge([P1 P2], 'linewidth', 2, 'color', 'k'); % drawLine(med) % % % Draw the median line of an edge % P1 = [50 60]; % P2 = [80 30]; % edge = createEdge(P1, P2); % figure; axis square; axis([0 100 0 100]); % drawEdge(edge, 'linewidth', 2) % med = medianLine(edge); % drawLine(med) % % % See also % lines2d, createLine, orthogonalLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE nargs = length(varargin); if nargs == 1 tab = varargin{1}; if size(tab, 2)==2 % input is an array of two points x0 = tab(1,1); y0 = tab(1,2); dx = tab(2,1)-x0; dy = tab(2,2)-y0; else % input is an edge x0 = tab(:, 1); y0 = tab(:, 2); dx = tab(:, 3) - tab(:, 1); dy = tab(:, 4) - tab(:, 2); end elseif nargs==2 % input is given as two points, or two point arrays p1 = varargin{1}; p2 = varargin{2}; x0 = p1(:, 1); y0 = p1(:, 2); dx = bsxfun(@minus, p2(:, 1), x0); dy = bsxfun(@minus, p2(:, 2), y0); else error('Too many input arguments'); end % compute median using middle point of the edge, and the direction vector % rotated by 90 degrees counter-clockwise line = [bsxfun(@plus, x0, dx/2), bsxfun(@plus, y0, dy/2), -dy, dx]; matgeom-1.2.4/inst/geom2d/PaxHeaders/lines2d.m0000644000000000000000000000013214576357161016114 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/lines2d.m0000644000175000017500000000540614576357161017701 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function lines2d(varargin) %LINES2D Description of functions operating on planar lines. % % The term 'line' refers to a planar straight line, which is an unbounded % curve. Line segments defined between 2 points, which are bounded, are % called 'edge', and are presented in file 'edges2d'. % % A straight line is defined by a point (its origin), and a vector (its % direction). The parameters are bundled into a 1-by-4 row vector: % LINE = [x0 y0 dx dy]; % % A line contains all points (x,y) such that: % x = x0 + t*dx % y = y0 + t*dy; % for all t between -infinity and +infinity. % % See also % points2d, vectors2d, edges2d, rays2d % createLine, cartesianLine, medianLine, edgeToLine, lineToEdge % orthogonalLine, parallelLine, bisector, radicalAxis, fitLine % lineAngle, linePosition, projPointOnLine % isPointOnLine, distancePointLine, isLeftOriented % intersectLines, intersectLineEdge, clipLine % reverseLine, transformLine, drawLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('lines2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/angles2d.m0000644000000000000000000000013214576357161016253 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/angles2d.m0000644000175000017500000000454614576357161020044 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function angles2d %ANGLES2D Description of functions for manipulating angles. % % Angles are normalized in an interval of width 2*PI. Most geom2d % functions return results in the [0 2*pi] interval, but it can be % convenient to consider the [-pi pi] interval as well. See the % normalizeAngle function to switch between conventions. % % Angles are usually oriented. The default orientation is the CCW % (Counter-Clockwise) orientation. % % See also % normalizeAngle, angleDiff, angleAbsDiff, angleSort % angle2Points, angle3Points, vectorAngle, lineAngle, edgeAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-03-31, using Matlab 7.4.0.287 (R2007a) % Copyright 2010-2023 INRA - Cepia Software Platform help('angles2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/findClosestPoint.m0000644000000000000000000000013214576357161020043 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/findClosestPoint.m0000644000175000017500000000520514576357161021625 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [index, minDist] = findClosestPoint(coord, points) %FINDCLOSESTPOINT Find index of closest point in an array. % % INDEX = findClosestPoint(POINT, POINTARRAY) % % [INDEX, MINDIST] = findClosestPoint(POINT, POINTARRAY) % Also returns the distance between POINT and closest point in % POINTARRAY. % % Example % pts = rand(10, 2); % findClosestPoint(pts(4, :), pts) % ans = % 4 % % See also % points2d, minDistancePoints, distancePoints % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-02-24, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform % number of points % number of point in first input to process np = size(coord, 1); % allocate memory for result index = zeros(np, 1); minDist = zeros(np, 1); for i = 1:np % compute squared distance between current point and all point in array dist = sum(bsxfun(@minus, coord(i,:), points) .^ 2, 2); % keep index of closest point [minDist(i), index(i)] = min(dist); end matgeom-1.2.4/inst/geom2d/PaxHeaders/fitLine.m0000644000000000000000000000013214576357161016146 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/fitLine.m0000644000175000017500000000741714576357161017737 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [line, res] = fitLine(varargin) %LINEFIT Fit a straight line to a set of points. % % LIN = lineFit(X, Y) % Computes parametric line minimizing square error of all points (X,Y). % Result is a 4*1 array, containing coordinates of a point of the line, % and the direction vector of the line, that is L=[x0 y0 dx dy]; % % LIN = lineFit(PTS) % Gives coordinats of points in a single array. % % LIN = lineFit(PT0, PTS); % LIN = lineFit(PT0, X, Y); % with PT0 = [x0 y0], imposes the line to contain point PT0. % % [LIN, RES] = lineFit(...) % Also returns the residual error. % % % Requires: % Optimization toolbox % % See also % lines2d, fitEllipse, polyfit, polyfit2, lsqlin % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-30 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE %% Extract input arguments if length(varargin)==1 % argument is an array of points var = varargin{1}; x = var(:,1); y = var(:,2); elseif length(varargin)==2 var = varargin{1}; if size(var, 1)==1 var = varargin{2}; x = var(:,1); y = var(:,2); else % two arguments : x and y x = var; y = varargin{2}; end elseif length(varargin)==3 % three arguments : ref point, x and y x = varargin{2}; y = varargin{3}; end %% Main algorithm % Initializations: N = size(x, 1); % main matrix of the problem X = [x y ones(N,1)]; % conditions initialisations A = zeros(0, 3); b = []; Aeq1 = [1 1 0]; beq1 = 1; Aeq2 = [1 -1 0]; beq2 = 1; % disable verbosity of optimisation opt = optimset('lsqlin'); opt.LargeScale = 'off'; opt.Display = 'off'; % compute line coefficients [a;b;c] , in the form a*x + b*y + c = 0 % using linear regression % Check for both a=1 and b=1, such that we keep the result with lowest % residual error [coef1, res1] = lsqlin(X, zeros(N, 1), A, b, Aeq1, beq1, [], [], [], opt); [coef2, res2] = lsqlin(X, zeros(N, 1), A, b, Aeq2, beq2, [], [], [], opt); % choose the regression model with lowest remaining residual error if res1 < res2 coef = coef1; res = res1; else coef = coef2; res = res2; end % convert coefficients to [X0 Y0 DX DY] format line = cartesianLine(coef'); matgeom-1.2.4/inst/geom2d/PaxHeaders/enclosingCircle.m0000644000000000000000000000013214576357161017657 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/enclosingCircle.m0000644000175000017500000000676214576357161021452 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function circle = enclosingCircle(pts) %ENCLOSINGCIRCLE Find the minimum circle enclosing a set of points. % % CIRCLE = enclosingCircle(POINTS); % computes the circle CIRCLE=[xc yc r] which encloses all the points POINTS % given as a N-by-2 array. % % % Rewritten from a file from % Yazan Ahed (yash78@gmail.com) % % which was rewritten from a Java applet by Shripad Thite: % http://heyoka.cs.uiuc.edu/~thite/mincircle/ % % See also % circles2d, points2d, boxes2d, circumCircle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-07-07 % Copyright 2005-2023 INRA - Cepia Software Platform % works on convex hull: it is faster pts = pts(convhull(pts(:,1), pts(:,2)), :); % call the recursive function circle = recurseCircle(size(pts, 1), pts, 1, zeros(3, 2)); function circ = recurseCircle(n, p, m, b) % n: number of points given % m: an argument used by the function. Always use 1 for m. % bnry: an argument (3x2 array) used by the function to set the points that % determines the circle boundry. You have to be careful when choosing this % array's values. I think the values should be somewhere outside your points % boundary. For my case, for example, I know the (x,y) I have will be something % in between (-5,-5) and (5,5), so I use bnry as: % [-10 -10 % -10 -10 % -10 -10] if m == 4 circ = createCircle(b(1,:), b(2,:), b(3,:)); return; end circ = [Inf Inf 0]; if m == 2 circ = [b(1,1:2) 0]; elseif m == 3 c = (b(1,:) + b(2,:))/2; circ = [c distancePoints(b(1,:), c)]; end for i = 1:n if distancePoints(p(i,:), circ(1:2)) > circ(3) if sum(b(:,1)==p(i,1) & b(:,2)==p(i,2)) == 0 b(m,:) = p(i,:); circ = recurseCircle(i, p, m+1, b); end end end matgeom-1.2.4/inst/geom2d/PaxHeaders/drawParabola.m0000644000000000000000000000013214576357161017153 xustar0030 mtime=1710874225.122193359 30 atime=1710874225.122193359 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawParabola.m0000644000175000017500000001134514576357161020737 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawParabola(varargin) %DRAWPARABOLA Draw a parabola on the current axis. % % drawParabola(PARABOLA); % Draws a vertical parabola, defined by its vertex and its parameter. % Such a parabola admits a vertical axis of symetry. % % The algebraic equation of parabola is given by: % (Y - YV) = A * (X - VX)^2 % Where XV and YV are vertex coordinates and A is parabola parameter. % % A parametric equation of parabola is given by: % x(t) = t + VX; % y(t) = A * t^2 + VY; % % PARABOLA can also be defined by [XV YV A THETA], with theta being the % angle of rotation of the parabola (in degrees and Counter-Clockwise). % % drawParabola(PARABOLA, T); % Specifies which range of 't' are used for drawing parabola. If T is an % array with only two values, the first and the last values are used as % interval bounds, and several values are distributed within this % interval. % % drawParabola(..., NAME, VALUE); % Can specify one or several graphical options using parameter name-value % pairs. % % drawParabola(AX, ...); % Specifies handle of the axis to draw on. % % H = drawParabola(...); % Returns an handle to the created graphical object. % % % Example: % figure(1); clf; hold on; % axis equal; axis([0 100 0 100]) % % draw parabola with default parameterization bounds % drawParabola([50 50 .2 30]); % % draw parabola with more specific bounds and drawing style % drawParabola([50 50 .2 30], [-3 3], 'color', 'r', 'linewidth', 2); % % % See also % drawCircle, drawEllipse % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-06-02 % Copyright 2006-2023 INRA - TPV URPOI - BIA IMASTE % Extract parabola if nargin < 1 error('MatGeom:geom2d:drawParabola:IllegalArgument', ... 'Please specify parabola representation'); end % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % input parabola is given as a packed array parabola = varargin{1}; varargin(1) = []; x0 = parabola(:,1); y0 = parabola(:,2); a = parabola(:,3); % check if parabola orientation is specified if size(parabola, 2) > 3 theta = parabola(:, 4); else theta = zeros(length(a), 1); end % extract parametrisation bounds bounds = [-100 100]; if ~isempty(varargin) var = varargin{1}; if isnumeric(var) bounds = var; varargin(1) = []; end end % create parametrisation array if length(bounds) > 2 t = bounds; else t = linspace(bounds(1), bounds(end), 100); end % create handle array (in the case of several parabola) h = zeros(size(x0)); % draw each parabola for i = 1:length(x0) % compute transformation trans = ... createTranslation(x0(i), y0(i)) * ... createRotation(deg2rad(theta(i))) * ... createScaling(1, a); % compute points on the parabola [xt, yt] = transformPoint(t(:), t(:).^2, trans); % draw it h(i) = plot(ax, xt, yt, varargin{:}); end % process output arguments if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/readme.txt0000644000000000000000000000013214576357160016373 xustar0030 mtime=1710874224.590193868 30 atime=1710874224.578193881 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/readme.txt0000644000175000017500000000307414576357160020157 0ustar00juanpijuanpi00000000000000Description of the geom2d library. The aim of geom2d library is to handle and visualize geometric primitives such as points, lines, circles and ellipses, polylines and polygons... It provides low-level functions for manipulating geometrical primitives, making easier the development of more complex geometric algorithms. Some features of the library are: - creation of various shapes (points, circles, lines, ellipses, polylines, polygons...) through an intuitive syntax. Ex: createCircle(p1, p2, p3) to create a circle through 3 points. - derivation of new shapes: intersection between 2 lines, between line and circle, between polylines... or point on a curve from its parametrisation - functions for polylines and polygons: compute centroid and area, expand, self-intersections, clipping with half-plane... - manipulation of planar transformation. Ex.: ROT = createRotation(CENTER, THETA); P2 = transformPoint(P1, ROT); - direct drawing of shapes with specialized functions. Clipping is performed automatically for infinite shapes such as lines or rays. Ex: drawCircle([50 50 25]); % draw circle with radius 25 and center [50 50] drawLine([X0 Y0 DX DY]); % clip and draw straight line - measure distances (between points, a point and a line, a point and a group of points), angle (of a line, between 3 points), or test geometry (point on a line, on a circle). Additional help is provided in geom/Contents.m file, as well as summary files like 'points2d.m' or 'lines2d.m'. matgeom-1.2.4/inst/geom2d/PaxHeaders/reverseEdge.m0000644000000000000000000000013214576357161017014 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/reverseEdge.m0000644000175000017500000000413214576357161020574 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = reverseEdge(edge) %REVERSEEDGE Intervert the source and target vertices of edge. % % REV = reverseEdge(EDGE); % Returns the opposite edge of EDGE. % EDGE has the format [X1 Y1 X2 Y2]. The resulting edge REV has value % [X2 Y2 X1 Y1]; % % See also % edges2d, createEdge, reverseLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-05-13, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform res = [edge(:,3:4) edge(:,1:2)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/createBasisTransform.m0000644000000000000000000000013214576357161020675 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createBasisTransform.m0000644000175000017500000001112314576357161022453 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function transfo = createBasisTransform(source, target) %CREATEBASISTRANSFORM Compute matrix for transforming a basis into another basis. % % TRANSFO = createBasisTransform(SOURCE, TARGET) % Both SOURCE and TARGET represent basis, in the following form: % [x0 y0 ex1 ey1 ex2 ey2] % [y0 y0] is the origin of the basis, [ex1 ey1] is the first direction % vector, and [ex2 ey2] is the second direction vector. % % The result TRANSFO is a 3-by-3 matrix such that a point expressed with % coordinates of the first basis will be represented by new coordinates % P2 = transformPoint(P1, TRANSFO) in the target basis. % % TRANSFO = createBasisTransform(TARGET) % Assumes the source is the standard (Oij) basis, with origin at (0,0), % first direction vector equal to (1,0) and second direction vector % equal to (0,1). % % % Example % % define source and target bases % src = [ 0 0 1 0 0 1]; % tgt = [20 0 .5 .5 -.5 .5]; % trans = createBasisTransform(src, tgt); % % create a polygon in source basis % poly = [10 10;30 10; 30 20; 20 20;20 40; 10 40]; % figure; % subplot(121); drawPolygon(poly, 'b'); axis equal; axis([-10 50 -10 50]); % hold on; drawLine([0 0 1 0], 'k'); drawLine([0 0 0 1], 'k'); % drawLine([20 0 1 1], 'r'); drawLine([20 0 -1 1], 'r'); % t = -1:5; plot(t*5+20, t*5, 'r.'); plot(-t*5+20, t*5, 'r.'); % % transform the polygon in target basis % poly2 = transformPoint(poly, trans); % subplot(122); drawPolygon(poly2, 'b'); axis equal; axis([-10 50 -10 50]); % hold on; drawLine([0 0 1 0], 'r'); drawLine([0 0 0 1], 'r'); % t = -1:5; plot(t*10, zeros(size(t)), 'r.'); plot(zeros(size(t)), t*10, 'r.'); % % See also % transforms2d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-12-03, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % init basis transform to identity t1 = eye(3); t2 = eye(3); if nargin == 2 % from source to reference basis t1(1:2, 1) = source(3:4); t1(1:2, 2) = source(5:6); t1(1:2, 3) = source(1:2); else % if only one input, use first input as target basis, and leave the % first matrix to identity target = source; end % from reference to target basis t2(1:2, 1) = target(3:4); t2(1:2, 2) = target(5:6); t2(1:2, 3) = target(1:2); % compute transform matrix transfo = zeros(3, 3); maxSz = 1; for i = 1:maxSz % coordinate of three reference points in source basis po = t1(1:2, 3, i)'; px = po + t1(1:2, 1, i)'; py = po + t1(1:2, 2, i)'; % express coordinates of reference points in the new basis t2i = inv(t2(:,:,i)); pot = transformPoint(po, t2i); pxt = transformPoint(px, t2i); pyt = transformPoint(py, t2i); % compute direction vectors in new basis vx = pxt - pot; vy = pyt - pot; % concatenate result in a 3-by-3 affine transform matrix transfo(:,:,i) = [vx' vy' pot' ; 0 0 1]; end matgeom-1.2.4/inst/geom2d/PaxHeaders/createLine.m0000644000000000000000000000013214576357161016627 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createLine.m0000644000175000017500000001423614576357161020415 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = createLine(varargin) %CREATELINE Create a straight line from 2 points, or from other inputs. % % Line is represented in a parametric form : [x0 y0 dx dy] % x = x0 + t*dx % y = y0 + t*dy; % % % L = createLine(p1, p2); % Returns the line going through the two given points. % % L = createLine(x0, y0, dx, dy); % Returns the line going through point (x0, y0) and with direction % vector(dx, dy). % % L = createLine(LINE); % where LINE is an array of 4 values, creates the line going through the % point (LINE(1) LINE(2)), and with direction given by vector (LINE(3) % LINE(4)). % % L = createLine(THETA); % Create a polar line originated at (0,0) and with angle THETA in radians. % % L = createLine(p, THETA); % Create a polar line originated at p and with angle THETA in radians. % % L = createLine(RHO, THETA); % Create a polar line with normal theta, and with min distance to origin % equal to rho. rho can be negative, in this case, the line is the same % as with CREATELINE(-rho, theta+pi), but the orientation is different. % % % Note: in all cases, parameters can be vertical arrays of the same % dimension. The result is then an array of lines, of dimensions [N*4]. % % % See also % lines2d, createEdge, createRay % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % NOTE : A line can also be represented with a 1*5 array : % [x0 y0 dx dy t]. % whith 't' being one of the following : % - t=0 : line is a singleton (x0,y0) % - t=1 : line is an edge segment, between points (x0,y0) and (x0+dx, % y0+dy). % - t=Inf : line is a Ray, originated from (x0,y0) and going to infinity % in the direction(dx,dy). % - t=-Inf : line is a Ray, originated from (x0,y0) and going to infinity % in the direction(-dx,-dy). % - t=NaN : line is a real straight line, and contains all points % verifying the above equation. % This seems us a convenient way to represent uniformly all kind of lines % (including edges, rays, and even point). % % NOTE2 : Any line object can be represented using a 1x6 array : % [x0 y0 dx dy t0 t1] % the first 4 parameters define the supporting line, % t0 represent the position of the first point on the line, % and t1 the position of the last point. % * for edges : t0 = 0, and t1=1 % * for straight lines : t0 = -inf, t1=inf % * for rays : t0=0, t1=inf (or t0=-inf,t1=0 for inverted ray). % I propose to call these objects 'lineArc' if length(varargin)==1 % Only one input parameter. It can be : % - line angle % - array of four parameters % TODO : add control for arrays of lines. var = varargin{1}; if size(var, 2)==4 % 4 parameters of the line in a single array. line = var; elseif size(var, 2)==1 % 1 parameter : angle of the line, going through origin. line = [zeros(size(var)) zeros(size(var)) cos(var) sin(var)]; else error('wrong number of dimension for arg1 : can be 1 or 4'); end elseif length(varargin)==2 % 2 input parameters. They can be : % - line angle and signed distance to origin. % - 2 points, then 2 arrays of 1*2 double. v1 = varargin{1}; v2 = varargin{2}; if size(v1, 2)==2 && size(v2, 2)==1 % first param is point, and second param is angle of line line = [v1(:,1), v1(:,2) cos(v2) sin(v2)]; elseif size(v1, 2)==1 % first param is angle of line, and second param is signed distance % to origin. line = [v1.*cos(v2) v1.*sin(v2) -sin(v2) cos(v2)]; elseif size(v1, 2)==3 || size(v2, 2)==3 error('The 1st or 2nd input argument has 3 columns. You may want to try createLine3d.'); else % first input parameter is first point, and second input is the % second point. line = [v1(:,1), v1(:,2), v2(:,1)-v1(:,1), v2(:,2)-v1(:,2)]; end elseif length(varargin)==3 % 3 input parameters : % first one is a point belonging to the line, % second and third ones are direction vector of the line (dx and dy). p = varargin{1}; line = [p(:,1) p(:,2) varargin{2} varargin{3}]; elseif length(varargin)==4 % 4 input parameters : % they are x0, y0 (point belongng to line) and dx, dy (direction vector % of the line). % All parameters should have the same size. line = [varargin{1} varargin{2} varargin{3} varargin{4}]; else error('Wrong number of arguments in ''createLine'' '); end matgeom-1.2.4/inst/geom2d/PaxHeaders/isPointInEllipse.m0000644000000000000000000000013214576357161020006 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPointInEllipse.m0000644000175000017500000000550214576357161021570 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointInEllipse(point, ellipse, varargin) %ISPOINTINELLIPSE Check if a point is located inside a given ellipse. % % B = isPointInEllipse(POINT, ELLIPSE) % Returns true if point is located inside the given ellipse. % % B = isPointInEllipse(POINT, ELLIPSE, TOL) % Specifies the tolerance value % % Example: % isPointInEllipse([1 0], [0 0 2 1 0]) % ans = % 1 % isPointInEllipse([0 0], [0 0 2 1 0]) % ans = % 1 % isPointInEllipse([1 1], [0 0 2 1 0]) % ans = % 0 % isPointInEllipse([1 1], [0 0 2 1 30]) % ans = % 1 % % See also % ellipses2d, isPointInCircle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-03-11 % Copyright 2011-2023 INRA - TPV URPOI - BIA IMASTE % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % compute ellipse to unit circle transform rot = createRotation(-deg2rad(ellipse(5))); sca = createScaling(1./ellipse(3:4)); trans = sca * rot; % transform points to unit circle basis pTrans = bsxfun(@minus, point, ellipse(:,1:2)); pTrans = transformPoint(pTrans, trans); % test if distance to origin smaller than 1 b = sqrt(sum(power(pTrans, 2), 2)) - 1 <= tol; matgeom-1.2.4/inst/geom2d/PaxHeaders/ellipses2d.m0000644000000000000000000000013214576357161016622 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/ellipses2d.m0000644000175000017500000000445114576357161020406 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ellipses2d(varargin) %ELLIPSES2D Description of functions operating on ellipses. % % Ellipses are represented by their center, the length of their 2 % semi-axes length, and their angle from the Ox direction (in degrees). % E = [XC YC A B THETA]; % % See also % circles2d, equivalentEllipse, createEllipse, fitEllipse % isPointInEllipse, ellipsePerimeter, ellipseCartesianCoefficients % ellipseToPolygon, projPointOnEllipse, distancePointEllipse, % transformEllipse, drawEllipse, drawEllipseArc % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - Cepia Software Platform help('ellipses2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/drawCenteredEdge.m0000644000000000000000000000013214576357161017750 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawCenteredEdge.m0000644000175000017500000001214214576357161021530 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCenteredEdge(varargin) %DRAWCENTEREDEDGE Draw an edge centered on a point. % % Draws a centered edge, defined by a center, a length and an orientation % (in degrees). This function can be used to draw principal axes of an % ellipse or of an oriented box. % % % drawCenteredEdge(EDGE) % Draws an edge centered on a point. EDGE has format [XC YC L THETA], % with (Xc, YC) being edge center, L being the edge length, and THETA % beigng the edge orientation, in degrees (counted Counter-clockwise from % horizontal). % Input argument can also be a N-by-4 array, in that can several edges % are drawn. % % drawCenteredEdge(CENTER, L, THETA) % Specifies argument in seperate inputs. % % drawCenteredEdge(..., NAME, VALUE) % Also specifies drawing options by using one or several parameter name - % value pairs (see doc of plot function for details). % % drawCenteredEdge(AX, ...) % Specifies the axis to draw the edge on. % % H = drawCenteredEdge(...) % Returns handle(s) to the created edges(s). % % Example % % Draw an ellipse with its two axes % figure(1); clf; % center = [50 40]; % r1 = 30; r2 = 10; % theta = 20; % elli = [center r1 r2 theta]; % drawEllipse(elli, 'linewidth', 2); % axis([0 100 0 100]); axis equal; % hold on; % edges = [center 2*r1 theta ; center 2*r2 theta+90]; % drawCenteredEdge(edges, 'linewidth', 2, 'color', 'g'); % % See also % edges2d, drawOrientedBox, drawEllipse, centeredEdgeToEdge, drawEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-08-05 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% process input variables if nargin < 1 error('Function requires an input argument'); end % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end var = varargin{1}; if size(var, 2) == 4 % manage edge in single parameter len = var(:, 3); theta = var(:, 4); center = var(:, 1:2); N = size(center, 1); varargin(1) = []; elseif length(varargin) >= 3 % parameters given in different arguments % size of data center = varargin{1}; len = varargin{2}; theta = varargin{3}; varargin(1:3) = []; % ensure all data have same size NP = size(center, 1); NL = size(len, 1); ND = size(theta, 1); N = max([NP NL ND]); if N > 1 if NP == 1, center = repmat(center, [N 1]); end if NL == 1, len = repmat(len, [N 1]); end if ND == 1, theta = repmat(theta, [N 1]); end end end % extract drawing options options = varargin(:); %% Draw edges % coordinates of center point xc = center(:, 1); yc = center(:, 2); % convert angle to radians theta = theta * pi / 180; % computation shortcuts cot = cos(theta); sit = sin(theta); % compute starting and ending points x1 = xc - len .* cot / 2; x2 = xc + len .* cot / 2; y1 = yc - len .* sit / 2; y2 = yc + len .* sit / 2; % save hold state holdState = ishold(ax); hold(ax, 'on'); % draw the edges h = zeros(N, 1); for i = 1:N h(i) = plot(ax, [x1(i) x2(i)], [y1(i) y2(i)]); end % apply style to edges if ~isempty(options) > 0 for i = 1:N set(h(i), options{:}); end end %% Format output % restore hold state if ~holdState hold(ax, 'off'); end % process output arguments if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/drawLine.m0000644000000000000000000000013214576357161016321 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawLine.m0000644000175000017500000000612114576357161020101 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawLine(lin, varargin) %DRAWLINE Draw a straight line clipped by the current axis. % % drawLine(LINE); % Draws the line LINE on the current axis, by using current axis to clip % the line. % % drawLine(LINE, PARAM, VALUE); % Specifies drawing options. % % H = drawLine(...) % Returns a handle to the created line object. If clipped line is not % contained in the axis, the function returns -1. % % Example % figure; hold on; axis equal; % axis([0 100 0 100]); % drawLine([30 40 10 20]); % drawLine([30 40 20 -10], 'Color', 'm', 'LineWidth', 2); % drawLine([-30 140 10 20]); % % See also % lines2d, createLine, drawEdge, clipLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE isLine3d = @(x) validateattributes(x,{'numeric'},... {'nonempty','nonnan','real','finite','size',[nan,4]}); defOpts.Color = 'b'; [ax, lin, varargin] = ... parseDrawInput(lin, isLine3d, 'line', defOpts, varargin{:}); % extract bounding box of the current axis xlim = get(ax, 'xlim'); ylim = get(ax, 'ylim'); % clip lines with current axis box clip = clipLine(lin, [xlim ylim]); ok = isfinite(clip(:,1)); % initialize result array to invalide handles h = -1 * ones(size(lin, 1), 1); % draw valid lines h(ok) = plot(ax, clip(ok, [1 3])', clip(ok, [2 4])', varargin{:}); % return line handle if needed if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/edgeLength.m0000644000000000000000000000013214576357161016622 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/edgeLength.m0000644000175000017500000000473214576357161020410 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function len = edgeLength(varargin) %EDGELENGTH Return length of an edge. % % L = edgeLength(EDGE); % Returns the length of an edge, with parametric representation: % [x1 y1 x2 y2]. % % The function also works for several edges, in this case input is a % N-by-4 array, containing parametric representation of each edge, and % output is a N-by-1 array containing length of each edge. % % See also % edges2d, edgeAngle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-02-19 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if nargin == 1 % input is an edge [X1 Y1 X2 Y2] edge = varargin{1}; len = hypot(edge(:,3)-edge(:,1), edge(:,4)-edge(:,2)); elseif nargin == 2 % input are two points [X1 Y1] and [X2 Y2] p1 = varargin{1}; p2 = varargin{2}; len = hypot(p2(:,1)-p1(:,1), p2(:,2)-p1(:,2)); end matgeom-1.2.4/inst/geom2d/PaxHeaders/clipLine.m0000644000000000000000000000013214576357161016313 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/clipLine.m0000644000175000017500000001112214576357161020070 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = clipLine(line, box, varargin) %CLIPLINE Clip a line with a box. % % EDGE = clipLine(LINE, BOX); % LINE is a straight line given as a 4 element row vector: [x0 y0 dx dy], % with (x0 y0) being a point of the line and (dx dy) a direction vector, % BOX is the clipping box, given by its extreme coordinates: % [xmin xmax ymin ymax]. % The result is given as an edge, defined by the coordinates of its 2 % extreme points: [x1 y1 x2 y2]. % If line does not intersect the box, [NaN NaN NaN NaN] is returned. % % Function works also if LINE is a N-by-4 array, if BOX is a Nx4 array, % or if both LINE and BOX are N-by-4 arrays. In these cases, EDGE is a % N-by-4 array. % % % Example % line = [30 40 10 0]; % box = [0 100 0 100]; % res = clipLine(line, box) % res = % 0 40 100 40 % % See also % lines2d, boxes2d, edges2d % clipEdge, clipRay, clipLine3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-08-27, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - Cepia Software Platform % adjust size of two input arguments nLines = size(line, 1); nBoxes = size(box, 1); if nLines == 1 && nBoxes > 1 line = repmat(line, nBoxes, 1); elseif nBoxes == 1 && nLines > 1 box = repmat(box, nLines, 1); elseif nLines ~= nBoxes error('bad sizes for input'); end % allocate memory nLines = size(line, 1); edge = zeros(nLines, 4); % main loop on lines for i = 1:nLines % extract limits of the box xmin = box(i, 1); xmax = box(i, 2); ymin = box(i, 3); ymax = box(i, 4); % use direction vector for box edges similar to direction vector of the % line in order to reduce computation errors delta = hypot(line(i,3), line(i,4)); % compute intersection with each edge of the box px1 = intersectLines(line(i,:), [xmin ymin delta 0]); % lower edge px2 = intersectLines(line(i,:), [xmax ymin 0 delta]); % right edge py1 = intersectLines(line(i,:), [xmax ymax -delta 0]); % upper edge py2 = intersectLines(line(i,:), [xmin ymax 0 -delta]); % left edge % remove undefined intersections (case of lines parallel to box edges) points = [px1 ; px2 ; py1 ; py2]; points = points(isfinite(points(:,1)), :); % sort points according to their position on the line pos = linePosition(points, line(i,:)); [pos, inds] = sort(pos); %#ok points = points(inds, :); % create clipped edge by using the two points in the middle ind = size(points, 1)/2; inter1 = points(ind,:); inter2 = points(ind+1,:); edge(i, 1:4) = [inter1 inter2]; % check that middle point of the edge is contained in the box midX = mean(edge(i, [1 3])); xOk = xmin <= midX && midX <= xmax; midY = mean(edge(i, [2 4])); yOk = ymin <= midY && midY <= ymax; % if one of the bounding condition is not met, set edge to NaN if ~(xOk && yOk) edge (i,:) = NaN; end end matgeom-1.2.4/inst/geom2d/PaxHeaders/transformLine.m0000644000000000000000000000013214576357161017377 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/transformLine.m0000644000175000017500000000513214576357161021160 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dest = transformLine(line, trans) %TRANSFORMLINE Transform a line with an affine transform. % % LINE2 = transformLine(LINE1, TRANS); % returns the line LINE1 transformed with affine transform TRANS. % LINE1 has the form [x0 y0 dx dy], and TRANS is a transformation % matrix. % % Format of TRANS can be one of : % [a b] , [a b c] , or [a b c] % [d e] [d e f] [d e f] % [0 0 1] % % LINE2 = transformLine(LINES, TRANS); % Also work when LINES is a [N*4] array of double. In this case, LINE2 % has the same size as LINE. % % See also % lines2d, transforms2d, transformPoint % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % isolate points points1 = line(:, 1:2); points2 = line(:, 1:2) + line(:, 3:4); % transform points points1 = transformPoint(points1, trans); points2 = transformPoint(points2, trans); dest = createLine(points1, points2); matgeom-1.2.4/inst/geom2d/PaxHeaders/hausdorffDistance.m0000644000000000000000000000013214576357161020210 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/hausdorffDistance.m0000644000175000017500000000703114576357161021771 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [hd, ind1, ind2] = hausdorffDistance(pts1, pts2) %HAUSDORFFDISTANCE Hausdorff distance between two point sets. % % HD = hausdorffDistance(PTS1, PTS2) % Computes the Hausdorff distance between the two point sets PTS1 and % PTS2. The Hausdorf distance can be used to compare two shapes. % % The distance between a point x and a set Y is given by: % d(x, Y) = inf { d(x,y) | y in Y } % The distance between two non empty sets X and Y is given by: % d(X, Y) = sup { d(x,Y) | x in X } % The Hausdorff distance between sets X and Y distance is defined as the % maximum of d(X,Y) and d(Y,X): % HD(X,Y) = max { d(X,Y), d(Y,X) } % % % Example % % Compute Hausdorff distance between an ellipse and a rectangle % % first define two shapes % rect = resamplePolygon(orientedBoxToPolygon([20 30 80 40 30]), 60); % poly = ellipseToPolygon([20 30 40 20 30], 500); % % display the shapes % figure; hold on % drawPolygon(poly, 'b'); % drawPolygon(rect, 'g'); % axis equal; % % compute hausdorff distance % [hd ind1 ind2] = hausdorffDistance(poly, rect); % p1h = poly(ind1, :); % p2h = rect(ind2, :); % drawPoint([p1h;p2h], 'mo'); % drawEdge([p1h p2h], 'm') % % See also % points2d, minDistancePoints % % References % http://en.wikipedia.org/wiki/Hausdorff_distance % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-05-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRAE - Cepia Software Platform % distance from pts1 to pts2 [dists1, ind12] = minDistancePoints(pts1, pts2); [max1, ind11] = max(dists1); % distance from pts2 to pts1 [dists2, ind22] = minDistancePoints(pts2, pts1); [max2, ind21] = max(dists2); % keep the max of the two distances hd = max(max1, max2); % keep the rigt indices if max1 > max2 ind1 = ind11; ind2 = ind12(ind11); else ind1 = ind22(ind21); ind2 = ind21; end matgeom-1.2.4/inst/geom2d/PaxHeaders/createDirectedCircle.m0000644000000000000000000000013214576357161020605 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createDirectedCircle.m0000644000175000017500000000630114576357161022365 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function circle = createDirectedCircle(varargin) %CREATEDIRECTEDCIRCLE Create a directed circle. % % C = createDirectedCircle(P1, P2, P3); % Creates a circle going through the given points. % C is a 1*4 array of the form: [XC YC R INV]. % The last parameter is set to 1 if the points are located in clockwise % order on the circle. % % C = createDirectedCircle(P1, P2); % Creates the circle whith center P1 and passing throuh the point P2. % % Works also when input are point arrays the same size, in this case the % result has as many lines as the point arrays. % % See also % circles2d, createCircle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-01-12 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE if nargin == 2 % inputs are the center and a point on the circle p1 = varargin{1}; p2 = varargin{2}; x0 = (p1(:,1) + p2(:,1))/2; y0 = (p1(:,2) + p2(:,2))/2; r = hypot((p2(:,1)-p1(:,1)), (p2(:,2)-p1(:,2)))/2; % circle is direct by default d = 0; elseif nargin == 3 % inputs are three points on the circle p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; % compute circle center line1 = medianLine(p1, p2); line2 = medianLine(p1, p3); center = intersectLines(line1, line2); x0 = center(:, 1); y0 = center(:, 2); % circle radius r = hypot((p1(:,1)-x0), (p1(:,2)-y0)); % compute circle orientation angle = angle3Points(p1, center, p2) + angle3Points(p2, center, p3); d = angle>2*pi; end circle = [x0 y0 r d]; matgeom-1.2.4/inst/geom2d/PaxHeaders/edgeToPolyline.m0000644000000000000000000000013214576357161017477 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/edgeToPolyline.m0000644000175000017500000000513614576357161021264 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly = edgeToPolyline(edge, N) %EDGETOPOLYLINE Convert an edge to a polyline with a given number of segments. % % POLY = edgeToPolyline(EDGE, N) % % Example % edge = [10 20 60 40]; % poly = edgeToPolyline(edge, 10); % drawEdge(edge, 'lineWidth', 2); % hold on % drawPoint(poly); % axis equal; % % See also % edges2d, drawEdge, drawPolyline % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-11-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform if N < 1 error('number of segments must be greater than 1'); end if length(edge) == 4 % case of planar edges p1 = edge(1:2); p2 = edge(3:4); poly = [linspace(p1(1), p2(1), N+1)' linspace(p1(2), p2(2), N+1)']; else % case of 3D edges p1 = edge(1:3); p2 = edge(4:6); poly = [... linspace(p1(1), p2(1), N+1)' ... linspace(p1(2), p2(2), N+1)' ... linspace(p1(3), p2(3), N+1)']; end matgeom-1.2.4/inst/geom2d/PaxHeaders/edgeAngle.m0000644000000000000000000000013214576357161016427 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/edgeAngle.m0000644000175000017500000000446614576357161020221 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = edgeAngle(edge) %EDGEANGLE Return angle of edge. % % A = edgeAngle(EDGE) % Returns the angle between horizontal, right-axis and the edge EDGE. % Angle is given in radians, between 0 and 2*pi, in counter-clockwise % direction. % Notation for edge is [x1 y1 x2 y2] (coordinates of starting and ending % points). % % Example % p1 = [10 20]; % p2 = [30 40]; % rad2deg(edgeAngle([p1 p2])) % ans = % 45 % % See also % edges2d, angles2d, edgeAngle, lineAngle, edgeLength % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-04-06 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE line = createLine(edge(:,1:2), edge(:,3:4)); theta = lineAngle(line); matgeom-1.2.4/inst/geom2d/PaxHeaders/intersectLineCircle.m0000644000000000000000000000013214576357161020506 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/intersectLineCircle.m0000644000175000017500000001004414576357161022265 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = intersectLineCircle(line, circle) %INTERSECTLINECIRCLE Intersection point(s) of a line and a circle. % % INTERS = intersectLineCircle(LINE, CIRCLE); % Returns a 2-by-2-by-N array, containing on each row the coordinates of % an intersection point for each line-circle pair, i.e. INTERS(:,:,k) % contains the intersections between LINE(k,:) and CIRCLE(k,:). % % If a line-circle pair does not intersect, the corresponding results are % set to NaN. % % Example % % base point % center = [10 0]; % % create vertical line % l1 = [center 0 1]; % % circle % c1 = [center 5]; % pts = intersectLineCircle(l1, c1) % pts = % 10 -5 % 10 5 % % draw the result % figure; clf; hold on; % axis([0 20 -10 10]); % drawLine(l1); % drawCircle(c1); % drawPoint(pts, 'rx'); % axis equal; % % See also % lines2d, circles2d, intersectLines, intersectCircles % % References % http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/ % http://mathworld.wolfram.com/Circle-LineIntersection.html % % ------ % Authors: David Legland, JuanPi Carbajal % E-mail: david.legland@inrae.fr, ajuanpi+dev@gmail.com % Created: 2011-01-14, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % check size of inputs nLines = size(line, 1); nCircles = size(circle, 1); if nLines ~= nCircles error ('matGeom:geom3d:invalidArguments', ... 'Requires same number of lines and circles'); end % center parameters center = circle(:, 1:2); radius = circle(:, 3); % line parameters dp = line(:, 1:2) - center; vl = line(:, 3:4); % coefficients of second order equation a = sum(line(:, 3:4).^2, 2); b = 2 * sum(dp .* vl, 2); c = sum(dp.^2, 2) - radius.^2; % discriminant delta = b .^ 2 - 4 * a .* c; points = nan(2, 2, nCircles); valid = delta >= 0; if any(valid) % compute roots (as a N-by-N-by-2 array) u = bsxfun(@plus, -b(valid), bsxfun(@times, [-1 1], sqrt(delta(valid)))); u = bsxfun(@rdivide, u, a(valid)) / 2; if sum(valid) == 1 points = [... line(1:2) + u(:,1) .* line(3:4); ... line(1:2) + u(:,2) .* line(3:4)]; else tmp = [... line(valid, 1:2) + u(:,1) .* line(valid, 3:4) ... line(valid, 1:2) + u(:,2) .* line(valid, 3:4)].'; points(:, :, valid) = permute(reshape(tmp, [2, 2, nCircles]), [2 1 3]); end end matgeom-1.2.4/inst/geom2d/PaxHeaders/ellipseCartesianCoefficients.m0000644000000000000000000000013214576357161022365 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/ellipseCartesianCoefficients.m0000644000175000017500000000565214576357161024155 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function coeffs = ellipseCartesianCoefficients(elli) %ELLIPSECARTESIANCOEFFICIENTS Cartesian coefficients of an ellipse. % % COEFFS = ellipseCartesianCoefficients(ELLI) % Computes the cartesian coefficients of the ellipse ELLI, given by: % COEFFS = [A B C D E F] % such that the points on the ellipse follow: % A*X^2 + B*X*Y + C*Y^2 + D*X + E*Y + F = 0 % % Example % elli = [30 20 40 20 30]; % coeffs = ellipseCartesianCoefficients(elli) % elli2 = createEllipse(coeffs) % elli2 = % 30.0000 20.0000 40.0000 20.0000 30.0000 % % See also % ellipses2d, createEllipse, equivalentEllipse % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-09-05, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % retrieve ellipse center and squared radiusses xc = elli(1); yc = elli(2); a2 = elli(3)^2; b2 = elli(4)^2; % pre-compute trigonometric functions (angle is in degrees) cot = cos(elli(5) * pi / 180); sit = sin(elli(5) * pi / 180); % identification of each parameter A = a2 * sit * sit + b2 * cot * cot; B = 2 * (b2 - a2) * sit * cot; C = a2 * cot * cot + b2 * sit * sit; D = - 2 * A * xc - B * yc; E = - B * xc - 2 * C * yc; F = A * xc * xc + B * xc * yc + C * yc * yc - a2 * b2; % concatenate into a single row vector coeffs = [A B C D E F]; matgeom-1.2.4/inst/geom2d/PaxHeaders/reverseLine.m0000644000000000000000000000013214576357161017037 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/reverseLine.m0000644000175000017500000000410214576357161020614 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = reverseLine(line) %REVERSELINE Return same line but with opposite orientation. % % INVLINE = reverseLine(LINE); % Returns the opposite line of LINE. % LINE has the format [x0 y0 dx dy], then INVLINE will have following % parameters: [x0 y0 -dx -dy]. % % See also % lines2d, createLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-01-20 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE line(:, 3:4) = -line(:, 3:4); matgeom-1.2.4/inst/geom2d/PaxHeaders/angle3Points.m0000644000000000000000000000013214576357161017122 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/angle3Points.m0000644000175000017500000000476014576357161020711 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = angle3Points(varargin) %ANGLE3POINTS Compute oriented angle made by 3 points. % % ALPHA = angle3Points(P1, P2, P3); % Computes the angle between the points P1, P2 and P3. % Pi are either [1*2] arrays, or [N*2] arrays, in this case ALPHA is a % [N*1] array. The angle computed is the directed angle between line % (P2P1) and line (P2P3). % Result is always given in radians, between 0 and 2*pi. % % See also % points2d, angles2d, angle2points % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-02-23 % Copyright 2004-2023 INRA - Cepia Software Platform if length(varargin)==3 p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; elseif length(varargin)==1 var = varargin{1}; p1 = var(1,:); p2 = var(2,:); p3 = var(3,:); end % angle line (P2 P1) theta = lineAngle(createLine(p2, p1), createLine(p2, p3)); matgeom-1.2.4/inst/geom2d/PaxHeaders/bisector.m0000644000000000000000000000013214576357161016366 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/bisector.m0000644000175000017500000000605614576357161020155 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function ray = bisector(varargin) %BISECTOR Return the bisector of two lines, or 3 points. % % RAY = bisector(LINE1, LINE2); % create the bisector of the two lines, given as [x0 y0 dx dy]. % % RAY = bisector(P1, P2, P3); % create the bisector of lines (P2 P1) and (P2 P3). % % The result has the form [x0 y0 dx dy], with [x0 y0] being the origin % point ans [dx dy] being the direction vector, normalized to have unit % norm. % % See also % lines2d, rays2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - Cepia Software Platform if length(varargin)==2 % two lines line1 = varargin{1}; line2 = varargin{2}; point = intersectLines(line1, line2); elseif length(varargin)==3 % three points p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; line1 = createLine(p2, p1); line2 = createLine(p2, p3); point = p2; elseif length(varargin)==1 % three points, given in one array var = varargin{1}; p1 = var(1, :); p2 = var(2, :); p3 = var(3, :); line1 = createLine(p2, p1); line2 = createLine(p2, p3); point = p2; end % compute line angles a1 = lineAngle(line1); a2 = lineAngle(line2); % compute bisector angle (angle of first line + half angle between lines) angle = mod(a1 + mod(a2-a1+2*pi, 2*pi)/2, pi*2); % create the resulting ray ray = [point cos(angle) sin(angle)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/clipPoints.m0000644000000000000000000000013214576357161016700 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/clipPoints.m0000644000175000017500000000445614576357161020471 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = clipPoints(points, box) %CLIPPOINTS Clip a set of points by a box. % % CLIP = clipPoints(POINTS, BOX); % Returns the set of points which are located inside of the box BOX. % % % See also % points2d, boxes2d, clipLine, drawPoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - Cepia Software Platform % get bounding box limits xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % compute indices of points inside visible area xOk = points(:,1)>=xmin & points(:,1)<=xmax; yOk = points(:,2)>=ymin & points(:,2)<=ymax; % keep only points inside box points = points(xOk & yOk, :); matgeom-1.2.4/inst/geom2d/PaxHeaders/projPointOnLine.m0000644000000000000000000000013214576357161017645 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/projPointOnLine.m0000644000175000017500000000617514576357161021436 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = projPointOnLine(point, line) %PROJPOINTONLINE Project a point orthogonally onto a line. % % PT2 = projPointOnLine(PT, LINE). % Computes the (orthogonal) projection of point PT onto the line LINE. % % Function works also for multiple points and lines. In this case, it % returns multiple points. % Point PT1 is a [N*2] array, and LINE is a [N*4] array (see createLine % for details). Result PT2 is a [N*2] array, containing coordinates of % orthogonal projections of PT1 onto lines LINE. % % Example % line = [0 2 2 1]; % projPointOnLine([3 1], line) % ans = % 2 3 % % See also % lines2d, points2d, isPointOnLine, linePosition, projPointOnEllipse % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-07-04 % Copyright 2005-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % parse input arguments p = inputParser; addRequired(p, 'point', @(x)validateattributes(x,{'numeric'},... {'size',[nan, 2],'nonnan','real','finite'})) addRequired(p, 'line', @(x)validateattributes(x,{'numeric'},... {'size',[nan, 4],'nonnan','real','finite'})) parse(p, point, line) % direction vector of the line vx = line(:, 3); vy = line(:, 4); % difference of point with line origin dx = point(:,1) - line(:,1); dy = point(:,2) - line(:,2); % Position of projection on line, using dot product tp = (dx .* vx + dy .* vy ) ./ (vx .* vx + vy .* vy); % convert position on line to cartesian coordinates point = [line(:,1) + tp .* vx, line(:,2) + tp .* vy]; matgeom-1.2.4/inst/geom2d/PaxHeaders/randomPointInBox.m0000644000000000000000000000013214576357161020006 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/randomPointInBox.m0000644000175000017500000000537614576357161021601 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = randomPointInBox(box, N, varargin) %RANDOMPOINTINBOX Generate random point within a box. % % PTS = randomPointInBox(BOX) % Generate a random point within the box BOX. The result is a 1-by-2 row % vector. % % PTS = randomPointInBox(BOX, N) % Generates N points within the box. The result is a N-by-2 array. % % BOX has the format: % BOX = [xmin xmax ymin ymax]. % % Example % % draw points within a box % box = [10 80 20 60]; % pts = randomPointInBox(box, 500); % figure(1); clf; hold on; % drawBox(box); % drawPoint(pts, '.'); % axis('equal'); % axis([0 100 0 100]); % % See also % geom2d, points2d, boxes2d, randomPointInBox3d, randomPointInPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-10, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas if nargin < 2 N = 1; end % extract box bounds xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % compute size of box dx = xmax - xmin; dy = ymax - ymin; % compute point coordinates points = [rand(N, 1)*dx+xmin , rand(N, 1)*dy+ymin]; matgeom-1.2.4/inst/geom2d/PaxHeaders/angleSort.m0000644000000000000000000000013214576357161016512 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/angleSort.m0000644000175000017500000000630714576357161020300 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = angleSort(pts, varargin) %ANGLESORT Sort points in the plane according to their angle to origin. % % % PTS2 = angleSort(PTS); % Computes angle of points with origin, and sort points with increasing % angles in Counter-Clockwise direction. % % PTS2 = angleSort(PTS, PTS0); % Computes angles between each point of PTS and PT0, which can be % different from origin. % % PTS2 = angleSort(..., THETA0); % Specifies the starting angle for sorting. % % [PTS2, I] = angleSort(...); % Also returns in I the indices of PTS, such that PTS2 = PTS(I, :); % % [PTS2, I, ANGLES] = angleSort(...); % Also returns the ANGLES in corresponding order to PTS2. % % See also % points2d, angles2d, angle2points, normalizeAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-24 % Copyright 2005-2023 INRA - Cepia Software Platform % default values pt0 = [0 0]; theta0 = 0; if length(varargin)==1 var = varargin{1}; if size(var, 2)==1 % specify angle theta0 = var; else pt0 = var; end elseif length(varargin)==2 pt0 = varargin{1}; theta0 = varargin{2}; end n = size(pts, 1); pts2 = pts - repmat(pt0, [n 1]); angle = lineAngle([zeros(n, 2) pts2]); angle = mod(angle - theta0 + 2*pi, 2*pi); [angles, I] = sort(angle); % format output switch nargout case 1 varargout{1} = pts(I, :); case 2 varargout{1} = pts(I, :); varargout{2} = I; case 3 varargout{1} = pts(I, :); varargout{2} = I; varargout{3} = angles; end matgeom-1.2.4/inst/geom2d/PaxHeaders/edges2d.m0000644000000000000000000000013214576357161016071 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/edges2d.m0000644000175000017500000000521614576357161017655 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges2d(varargin) %EDGES2D Description of functions operating on planar edges. % % An edge is represented by the coordinate of its extremities: % EDGE = [X1 Y1 X2 Y2]; % % Centered edges are sometimes used (for example for representing main % axes of an ellipse or an oriented box). Centered edges are represented % by their center, their length, and their orientation (counted in % degrees and counter-clockwise). % CEDGE = [XC YC LEN THETA]; % % A set of edges is represented by a N-by-4 array, each row representing % an edge. % % % See also % lines2d, rays2d, points2d, createEdge, parallelEdge, % edgeAngle, edgeLength, midPoint, edgeToLine, lineToEdge % intersectEdges, intersectLineEdge, isPointOnEdge, edgeToPolyline % clipEdge, transformEdge, intersectEdgePolygon, centeredEdgeToEdge % drawEdge, drawCenteredEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('edges2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/createScaling.m0000644000000000000000000000013214576357161017320 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createScaling.m0000644000175000017500000000621014576357161021077 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createScaling(varargin) %CREATESCALING Create the 3*3 matrix of a scaling in 2 dimensions. % % TRANS = createScaling(SX, SY); % return the matrix corresponding to scaling by SX and SY in the 2 % main directions. % The returned matrix has the form: % [SX 0 0] % [0 SY 0] % [0 0 1] % % TRANS = createScaling(SX); % Assume SX and SY are equals. % % TRANS = createScaling(CENTER, ...); % Specifies the center of the scaling transform. The argument CENTER % should be a 1-by-2 array representing coordinates of center. % % See also % transforms2d, transformPoint, createTranslation, createRotation % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-07 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % defined default arguments sx = 1; sy = 1; cx = 0; cy = 0; % process input arguments if nargin == 1 % the argument is either the scaling factor in both direction, % or a 1x2 array containing scaling factor in each direction var = varargin{1}; sx = var(1); sy = var(1); if length(var)>1 sy = var(2); end elseif nargin == 2 % the 2 arguments are the scaling factors in each dimension sx = varargin{1}; sy = varargin{2}; elseif nargin == 3 % first argument is center, 2nd and 3d are scaling factors center = varargin{1}; cx = center(1); cy = center(2); sx = varargin{2}; sy = varargin{3}; end % concatenate results in a 3-by-3 matrix trans = [sx 0 cx*(1-sx); 0 sy cy*(1-sy); 0 0 1]; matgeom-1.2.4/inst/geom2d/PaxHeaders/intersectEdges.m0000644000000000000000000000013214576357161017524 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/intersectEdges.m0000644000175000017500000001445714576357161021317 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = intersectEdges(edge1, edge2, varargin) %INTERSECTEDGES Return all intersections between two set of edges. % % P = intersectEdges(E1, E2); % returns the intersection point of edges E1 and E2. % E1 and E2 are 1-by-4 arrays, containing parametric representation of % each edge (in the form [x1 y1 x2 y2], see 'createEdge' for details). % % In case of colinear edges, the result P contains [Inf Inf]. % In case of parallel but not colinear edges, the result P contains % [NaN NaN]. % % If each input is N-by-4 array, the result is a N-by-2 array containing % the intersection of each couple of edges. % If one of the input has N rows and the other 1 row, the result is a % N-by-2 array. % % P = intersectEdges(E1, E2, TOL); % Specifies a tolerance parameter to determine parallel and colinear % edges, and if a point belongs to an edge or not. The latter test is % performed on the relative position of the intersection point over the % edge, that should lie within [-TOL; 1+TOL]. % % See also % edges2d, intersectLines % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - Cepia Software Platform % tolerance for precision tol = 1e-14; if nargin > 2 tol = varargin{1}; end %% Initialisations % ensure input arrays are same size N1 = size(edge1, 1); N2 = size(edge2, 1); % ensure input have same size if N1 ~= N2 if N1 == 1 edge1 = repmat(edge1, [N2 1]); N1 = N2; elseif N2 == 1 edge2 = repmat(edge2, [N1 1]); end end % initialize result array x0 = zeros(N1, 1); y0 = zeros(N1, 1); %% Detect parallel and colinear cases % indices of parallel edges %par = abs(dx1.*dy2 - dx1.*dy2) return [NaN NaN] x0(par & ~col) = NaN; y0(par & ~col) = NaN; %% Process colinear edges % colinear edges may have 0, 1 or infinite intersection % Setup result intersection point as follow: % * no intersection -> [NaN NaN] % * partial overlap -> [Inf Inf] % * touches at extremity -> extremity coordinates % Discrimnation based on position of edge2 vertices on edge1 if sum(col) > 0 % array for storing results of colinear edges resCol = Inf * ones(size(col)); colInds = find(col); % compute position of edge2 vertices wrt edge1 t1 = edgePosition(edge2(col, 1:2), edge1(col, :), 'diag'); t2 = edgePosition(edge2(col, 3:4), edge1(col, :), 'diag'); % control location of vertices: we want t1 t2; tmp = t1(swap); t1(swap) = t2(swap); t2(swap) = tmp; % edge totally before first vertex or totally after last vertex resCol(colInds(t2 < -tol)) = NaN; resCol(colInds(t1 > 1+tol)) = NaN; % set up result into point coordinate x0(col) = resCol(col); y0(col) = resCol(col); % touches on first point of first edge touch = colInds(abs(t2) < tol); x0(touch) = edge1(touch, 1); y0(touch) = edge1(touch, 2); % touches on second point of first edge touch = colInds(abs(t1-1) < tol); x0(touch) = edge1(touch, 3); y0(touch) = edge1(touch, 4); end %% Process non parallel cases % process edges whose supporting lines intersect i = find(~par); % use a test to avoid process empty arrays if sum(i) > 0 % extract base parameters of supporting lines for non-parallel edges x1 = edge1(i,1); y1 = edge1(i,2); dx1 = edge1(i,3) - x1; dy1 = edge1(i,4) - y1; x2 = edge2(i,1); y2 = edge2(i,2); dx2 = edge2(i,3) - x2; dy2 = edge2(i,4) - y2; % compute intersection points of supporting lines delta = (dx2.*dy1 - dx1.*dy2); x0(i) = ((y2-y1).*dx1.*dx2 + x1.*dy1.*dx2 - x2.*dy2.*dx1) ./ delta; y0(i) = ((x2-x1).*dy1.*dy2 + y1.*dx1.*dy2 - y2.*dx2.*dy1) ./ -delta; % compute position of intersection points on each edge % t1 is position on edge1, t2 is position on edge2 t1 = ((y0(i)-y1).*dy1 + (x0(i)-x1).*dx1) ./ (dx1.*dx1+dy1.*dy1); t2 = ((y0(i)-y2).*dy2 + (x0(i)-x2).*dx2) ./ (dx2.*dx2+dy2.*dy2); % check position of points on edges. % it should be comprised between 0 and 1 for both t1 and t2. % if not, the edges do not intersect out = t1<-tol | t1>1+tol | t2<-tol | t2>1+tol; x0(i(out)) = NaN; y0(i(out)) = NaN; end %% format output arguments point = [x0 y0]; matgeom-1.2.4/inst/geom2d/PaxHeaders/drawCircleArc.m0000644000000000000000000000013214576357161017261 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawCircleArc.m0000644000175000017500000001007314576357161021042 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawCircleArc(varargin) %DRAWCIRCLEARC Draw a circle arc on the current axis. % % drawCircleArc(ARC); % Draws circle arc defined by ARC = [XC YC R START EXTENT], with (XC, YC) % being the circle center, R being the circle radius, starting from angle % START, and with angular extent given by EXTENT. START and EXTENT angles % are given in degrees. % % drawCircleArc(XC, YC, R, START, EXTENT); % Alternative syntax that seperates inputs. % % drawCircleArc(..., PARAM, VALUE); % specifies plot properties by using one or several parameter name-value % pairs. % % drawCircleArc(AX, ...); % Specifies handle of the axis to draw on. % % H = drawCircleArc(...); % Returns a handle to the created line object. % % Example % % Draw a red thick circle arc % arc = [10 20 30 -120 240]; % figure; % axis([-50 100 -50 100]); % hold on % drawCircleArc(arc, 'LineWidth', 3, 'Color', 'r') % % See also % circles2d, drawCircle, drawEllipse, circleArcToPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-12-12 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% Parse input arguments % extract handle of axis to draw on [ax, varargin] = parseAxisHandle(varargin{:}); circle = varargin{1}; if size(circle, 2) == 5 x0 = circle(:,1); y0 = circle(:,2); r = circle(:,3); start = circle(:,4); extent = circle(:,5); varargin(1) = []; elseif length(varargin) >= 5 x0 = varargin{1}; y0 = varargin{2}; r = varargin{3}; start = varargin{4}; extent = varargin{5}; varargin(1:5) = []; else error('drawCircleArc: please specify center, radius and angles of circle arc'); end %% Pre-processing % convert angles in radians t0 = deg2rad(start); t1 = t0 + deg2rad(extent); % number of line segments N = 60; % initialize handles vector h = zeros(length(x0), 1); % save hold state holdState = ishold(ax); hold(ax, 'on'); %% Display each circle arc % draw each circle arc individually for i = 1:length(x0) % compute basis t = linspace(t0(i), t1(i), N+1)'; % compute vertices coordinates xt = x0(i) + r(i)*cos(t); yt = y0(i) + r(i)*sin(t); % draw the circle arc h(i) = plot(ax, xt, yt, varargin{:}); end %% post-processing % restore hold state if ~holdState hold(ax, 'off'); end if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/ellipsePerimeter.m0000644000000000000000000000013214576357161020066 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/ellipsePerimeter.m0000644000175000017500000000656214576357161021657 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function perim = ellipsePerimeter(ellipse, varargin) %ELLIPSEPERIMETER Perimeter of an ellipse. % % P = ellipsePerimeter(ELLI) % Computes the perimeter of an ellipse, using numerical integration. % ELLI is an ellipse, given using one of the following formats: % * a 1-by-5 row vector containing coordinates of center, length of % semi-axes, and orientation in degrees % * a 1-by-2 row vector containing only the lengths of the semi-axes. % The result % % P = ellipsePerimeter(ELLI, TOL) % Specify the relative tolerance for numerical integration. % % % Example % P = ellipsePerimeter([30 40 30 10 15]) % P = % 133.6489 % % See also % ellipses2d, ellipseArea, ellipseToPolygon, drawEllipse % % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform %% Parse input argument if size(ellipse, 2) == 5 ra = ellipse(:, 3); rb = ellipse(:, 4); elseif size(ellipse, 2) == 2 ra = ellipse(:, 1); rb = ellipse(:, 2); elseif size(ellipse, 2) == 1 ra = ellipse; rb = varargin{1}; varargin(1) = []; end % relative tolerance tol = 1e-10; if ~isempty(varargin) tol = varargin{1}; end %% Numerical integration n = length(ra); perim = zeros(n, 1); for i = 1:n % function to integrate f = @(t) sqrt(ra(i) .^ 2 .* cos(t) .^ 2 + rb(i) .^ 2 .* sin(t) .^ 2) ; % absolute tolerance from relative tolerance eps = tol * max(ra(i), rb(i)); % integrate on first quadrant if verLessThan('matlab', '7.14') perim(i) = 4 * quad(f, 0, pi/2, eps); %#ok else perim(i) = 4 * integral(f, 0, pi/2, 'AbsTol', eps); end end matgeom-1.2.4/inst/geom2d/PaxHeaders/projPointOnEllipse.m0000644000000000000000000000013214576357161020353 xustar0030 mtime=1710874225.126193356 30 atime=1710874225.126193356 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/projPointOnEllipse.m0000644000175000017500000000712314576357161022136 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function proj = projPointOnEllipse(point, elli) %PROJPOINTONELLIPSE Project a point orthogonally onto an ellipse. % % PROJ = projPointOnEllipse(PT, ELLI) % Computes the (orthogonal) projection of point PT onto the ellipse given % by ELLI. % % % Example % % create an ellipse and a point % elli = [50 50 40 20 30]; % pt = [60 10]; % % display reference figures % figure; hold on; drawEllipse(elli, 'b'); % axis equal; axis([0 100 0 100]); % drawPoint(pt, 'bo'); % % compute projected point % proj = projPointOnEllipse(pt, elli); % drawEdge([pt proj], 'b'); % drawPoint(proj, 'k*'); % % See also % ellipses2d, distancePointEllipse, projPointOnLine, ellipsePoint % drawEllipse % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-07-17, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % defaults nMaxIters = 4; % compute transform to centered axis-aligned ellipse center = elli(1:2); theta = deg2rad(elli(5)); transfo = createRotation(-theta) * createTranslation(-center); pointT = transformPoint(point, transfo); % retrieve ellipse semi axis lengths a = elli(3); b = elli(4); % keep absolute values px = abs(pointT(:,1)); py = abs(pointT(:,2)); % initial guess of solution tx = 0.707; ty = 0.707; % iterate for i = 1:nMaxIters x = a * tx; y = b * ty; ex = (a*a - b*b) * power(tx, 3) / a; ey = (b*b - a*a) * power(ty, 3) / b; rx = x - ex; ry = y - ey; qx = px - ex; qy = py - ey; r = hypot(ry, rx); q = hypot(qy, qx); tx = min(1, max(0, (qx .* r ./ q + ex) / a)); ty = min(1, max(0, (qy .* r ./ q + ey) / b)); t = hypot(ty, tx); tx = tx ./ t; ty = ty ./ t; end % computes coordinates of projection projX = a * tx; projY = b * ty; % fix sign projX(pointT(:,1) < 0) = -projX(pointT(:,1) < 0); projY(pointT(:,2) < 0) = -projY(pointT(:,2) < 0); % project pack to basis of original ellipse proj = transformPoint([projX projY], inv(transfo)); matgeom-1.2.4/inst/geom2d/PaxHeaders/Contents.m0000644000000000000000000000013214576357161016351 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/Contents.m0000644000175000017500000003320314576357161020132 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. %CONTENTS GEOM2D Geometry 2D Toolbox. % Version 1.24 07-Jun-2018. % % Library to handle and visualize geometric primitives such as points, % lines, circles and ellipses, polygons... % % The goal is to provide a low-level library for manipulating geometrical % primitives, making easier the development of more complex geometric % algorithms. % % Most functions works for planar shapes, but some ones have been % extended to 3D or to any dimension. % % Points % points2d - Description of functions operating on points. % midPoint - Middle point of two points or of an edge. % circumCenter - Circumcenter of three points. % isCounterClockwise - Compute the relative orientation of 3 points. % polarPoint - Create a point from polar coordinates (rho + theta). % angle2Points - Compute horizontal angle between 2 points. % angle3Points - Compute oriented angle made by 3 points. % distancePoints - Compute distance between two points. % transformPoint - Apply an affine transform to a point or a point set. % drawPoint - Draw the point on the axis. % % Point Sets % clipPoints - Clip a set of points by a box. % centroid - Compute centroid (center of mass) of a set of points. % boundingBox - Bounding box of a set of points. % principalAxes - Principal axes of a set of ND points. % angleSort - Sort points in the plane according to their angle to origin. % findClosestPoint - Find index of closest point in an array. % minDistancePoints - Minimal distance between several points. % mergeClosePoints - Merge points that are closer than a given distance. % hausdorffDistance - Hausdorff distance between two point sets. % nndist - Nearest-neighbor distances of each point in a set. % % Vectors % vectors2d - Description of functions operating on plane vectors. % createVector - Create a vector from two points. % vectorNorm - Compute norm of a vector, or of a set of vectors. % vectorAngle - Horizontal angle of a vector, or angle between 2 vectors. % normalizeVector - Normalize a vector to have norm equal to 1. % isPerpendicular - Check orthogonality of two vectors. % isParallel - Check parallelism of two vectors. % transformVector - Transform a vector with an affine transform. % rotateVector - Rotate a vector by a given angle. % % Straight lines % lines2d - Description of functions operating on planar lines. % createLine - Create a straight line from 2 points, or from other inputs. % fitLine - Fit a straight line to a set of points. % medianLine - Create a median line between two points. % cartesianLine - Create a straight line from cartesian equation coefficients. % orthogonalLine - Create a line orthogonal to another one through a point. % parallelLine - Create a line parallel to another one. % intersectLines - Return all intersection points of N lines in 2D. % lineAngle - Computes angle between two straight lines. % linePosition - Position of a point on a line. % clipLine - Clip a line with a box. % reverseLine - Return same line but with opposite orientation. % transformLine - Transform a line with an affine transform. % lineToEdge - Convert a straight line to a finite edge. % drawLine - Draw a straight line clipped by the current axis. % % Edges (line segments between 2 points) % edges2d - Description of functions operating on planar edges. % createEdge - Create an edge between two points, or from a line. % edgeAngle - Return angle of edge. % edgeLength - Return length of an edge. % parallelEdge - Edge parallel to another edge. % centeredEdgeToEdge - Convert a centered edge to a two-points edge. % midPoint - Middle point of two points or of an edge. % edgePosition - Return position of a point on an edge. % clipEdge - Clip an edge with a rectangular box. % reverseEdge - Intervert the source and target vertices of edge. % intersectEdges - Return all intersections between two set of edges. % intersectLineEdge - Return intersection between a line and an edge. % transformEdge - Transform an edge with an affine transform. % edgeToLine - Convert an edge to a straight line. % edgeToPolyline - Convert an edge to a polyline with a given number of segments. % drawEdge - Draw an edge given by 2 points. % drawCenteredEdge - Draw an edge centered on a point. % % Rays % rays2d - Description of functions operating on planar rays. % createRay - Create a ray (half-line), from various inputs. % bisector - Return the bisector of two lines, or 3 points. % clipRay - Clip a ray with a box. % drawRay - Draw a ray on the current axis. % % Relations between points and lines % distancePointEdge - Minimum distance between a point and an edge. % distancePointLine - Minimum distance between a point and a line. % projPointOnLine - Project a point orthogonally onto a line. % pointOnLine - Create a point on a line at a given position on the line. % isPointOnLine - Test if a point belongs to a line. % isPointOnEdge - Test if a point belongs to an edge. % isPointOnRay - Test if a point belongs to a ray. % isLeftOriented - Test if a point is on the left side of a line. % % Circles % circles2d - Description of functions operating on circles. % createCircle - Create a circle from 2 or 3 points. % createDirectedCircle - Create a directed circle. % intersectCircles - Intersection points of two circles. % intersectLineCircle - Intersection point(s) of a line and a circle. % circleToPolygon - Convert a circle into a series of points. % circleArcToPolyline - Convert a circle arc into a series of points. % isPointInCircle - Test if a point is located inside a given circle. % isPointOnCircle - Test if a point is located on a given circle. % enclosingCircle - Find the minimum circle enclosing a set of points. % circumCircle - Circumscribed circle of three points. % radicalAxis - Compute the radical axis (or radical line) of 2 circles. % drawCircle - Draw a circle on the current axis. % drawCircleArc - Draw a circle arc on the current axis. % % Ellipses and Parabola % ellipses2d - Description of functions operating on ellipses. % equivalentEllipse - Equivalent ellipse of a set of points. % fitEllipse - Fit an ellipse to a set of 2D points. % transformEllipse - Apply an affine transformation to an ellipse. % createEllipse - Create an ellipse, from various input types. % distancePointEllipse - Distance from a point to an ellipse. % projPointOnEllipse - Project a point orthogonally onto an ellipse. % isPointInEllipse - Check if a point is located inside a given ellipse. % ellipseArea - Area of an ellipse. % ellipsePerimeter - Perimeter of an ellipse. % ellipseToPolygon - Convert an ellipse into a series of points. % ellipsePoint - Coordinates of a point on an ellipse from parametric equation. % ellipseCartesianCoefficients - Cartesian coefficients of an ellipse. % drawEllipse - Draw an ellipse on the current axis. % drawEllipseAxes - Draw the main axes of an ellipse as line segments. % drawEllipseArc - Draw an ellipse arc on the current axis. % drawParabola - Draw a parabola on the current axis. % % Geometric transforms % transforms2d - Description of functions operating on transforms. % createTranslation - Create the 3*3 matrix of a translation. % createRotation - Create the 3*3 matrix of a rotation. % createRotation90 - Matrix of a rotation for 90 degrees multiples. % createScaling - Create the 3*3 matrix of a scaling in 2 dimensions. % createHomothecy - Create the the 3x3 matrix of an homothetic transform. % createBasisTransform - Compute matrix for transforming a basis into another basis. % createLineReflection - Create the the 3x3 matrix of a line reflection. % principalAxesTransform - Align a set of points along its principal axes. % fitAffineTransform2d - Compute the affine transform that best register two point sets. % registerICP - Fit affine transform by Iterative Closest Point algorithm. % polynomialTransform2d - Apply a polynomial transform to a set of points. % fitPolynomialTransform2d - Coefficients of polynomial transform between two point sets. % % Angles % angles2d - Description of functions for manipulating angles. % normalizeAngle - Normalize an angle value within a 2*PI interval. % angleAbsDiff - Absolute difference between two angles. % angleDiff - Difference between two angles. % % Boxes % boxes2d - Description of functions operating on bounding boxes. % intersectBoxes - Intersection of two bounding boxes. % mergeBoxes - Merge two boxes, by computing their greatest extent. % randomPointInBox - Generate random point within a box. % boxToRect - Convert box data to rectangle data. % boxToPolygon - Convert a bounding box to a square polygon. % drawBox - Draw a box defined by coordinate extents. % % Triangles % isPointInTriangle - Test if a point is located inside a triangle. % triangleArea - Signed area of a triangle. % % Rectangles % rectToPolygon - Convert a rectangle into a polygon (set of vertices). % rectToBox - Convert rectangle data to box data. % drawRect - Draw rectangle on the current axis. % orientedBox - Minimum-width oriented bounding box of a set of points. % orientedBoxToPolygon - Convert an oriented box to a polygon (set of vertices). % drawOrientedBox - Draw centered oriented rectangle. % % Splines % cubicBezierToPolyline - Compute equivalent polyline from bezier curve control. % drawBezierCurve - Draw a cubic bezier curve defined by 4 control points. % % Various drawing functions % drawVector - Draw vector at a given position. % drawArrow - Draw an arrow on the current axis. % drawLabels - Draw labels at specified positions. % drawShape - Draw various types of shapes (circles, polygons...). % % Other shapes % squareGrid - Generate equally spaces points in plane. % hexagonalGrid - Generate hexagonal grid of points in the plane. % triangleGrid - Generate triangular grid of points in the plane. % crackPattern - Create a (bounded) crack pattern tessellation. % crackPattern2 - Create a (bounded) crack pattern tessellation. % % % Credits: % * function 'enclosingCircle' rewritten from a file from Yazan Ahed % (yash78@gmail.com), available on Matlab File Exchange % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-07 % Copyright 2005-2023 INRA - Cepia Software Platform help(mfilename); matgeom-1.2.4/inst/geom2d/PaxHeaders/normalizeAngle.m0000644000000000000000000000013214576357161017523 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/normalizeAngle.m0000644000175000017500000000506014576357161021304 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function alpha = normalizeAngle(alpha, varargin) %NORMALIZEANGLE Normalize an angle value within a 2*PI interval. % % ALPHA2 = normalizeAngle(ALPHA); % ALPHA2 is the same as ALPHA modulo 2*PI and is positive. % % ALPHA2 = normalizeAngle(ALPHA, CENTER); % Specifies the center of the angle interval. % If CENTER==0, the interval is [-pi ; +pi] % If CENTER==PI, the interval is [0 ; 2*pi] (default). % % Example: % % normalization between 0 and 2*pi (default) % normalizeAngle(5*pi) % ans = % 3.1416 % % % normalization between -pi and +pi % normalizeAngle(7*pi/2, 0) % ans = % -1.5708 % % See also % vectorAngle, lineAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-03-10, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas center = pi; if ~isempty(varargin) center = varargin{1}; end alpha = mod(alpha-center+pi, 2*pi) + center-pi; matgeom-1.2.4/inst/geom2d/PaxHeaders/orthogonalLine.m0000644000000000000000000000013214576357161017540 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/orthogonalLine.m0000644000175000017500000000546214576357161021327 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = orthogonalLine(line, point) %ORTHOGONALLINE Create a line orthogonal to another one through a point. % % PERP = orthogonalLine(LINE, POINT); % Returns the line orthogonal to the line LINE and going through the % point given by POINT. Directed angle from LINE to PERP is pi/2. % LINE is given as [x0 y0 dx dy] and POINT is [xp yp]. % % Works also when LINE is a N-by-4 array, or POINT is a N-by-2 array. In % this case, the result is a N-by-4 array. % % % Example % refLine = createLine([10 10], [30 20]); % pt = [20 40]; % figure; hold on; axis equal; axis([0 50 0 50]); % drawLine(refLine, 'lineWidth', 2); % drawPoint(pt); % perp = orthogonalLine(refLine, pt); % drawLine(perp, 'color', 'r'); % % See also % lines2d, parallelLine, intersectLines % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE N = max(size(point, 1), size(line, 1)); if size(point, 1)>1 res = point; else res = ones(N, 1)*point; end if size(line, 1)>1 res(:,3) = -line(:,4); res(:,4) = line(:,3); else res(:,3) = -ones(N,1)*line(4); res(:,4) = ones(N,1)*line(3); end matgeom-1.2.4/inst/geom2d/PaxHeaders/clipEdge.m0000644000000000000000000000013214576357161016270 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/clipEdge.m0000644000175000017500000001167314576357161020060 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge2 = clipEdge(edge, box) %CLIPEDGE Clip an edge with a rectangular box. % % EDGE2 = clipEdge(EDGE, BOX); % EDGE: [x1 y1 x2 y2], % BOX : [xmin xmax ymin ymax], or [xmin xmax ; ymin ymax]. % return : % EDGE2 = [xc1 yc1 xc2 yc2]; % % If clipping is null, return [0 0 0 0]; % % if EDGE is a N-by-4 array, return an N-by-4 array, corresponding to % each clipped edge. % % See also % edges2d, boxes2d, clipLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-14 % Copyright 2005-2023 INRA - Cepia Software Platform % process data input if size(box, 1) == 2 box = box'; end % get limits of window xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % convert window limits into lines lineX0 = [xmin ymin xmax-xmin 0]; lineX1 = [xmin ymax xmax-xmin 0]; lineY0 = [xmin ymin 0 ymax-ymin]; lineY1 = [xmax ymin 0 ymax-ymin]; % compute outcodes of each vertex p11 = edge(:,1) < xmin; p21 = edge(:,3) < xmin; p12 = edge(:,1) > xmax; p22 = edge(:,3) > xmax; p13 = edge(:,2) < ymin; p23 = edge(:,4) < ymin; p14 = edge(:,2) > ymax; p24 = edge(:,4) > ymax; out1 = [p11 p12 p13 p14]; out2 = [p21 p22 p23 p24]; % detect edges totally inside window -> no clip. inside = sum(out1 | out2, 2) == 0; % detect edges totally outside window outside = sum(out1 & out2, 2) > 0; % select edges not totally outside, and process separately edges totally % inside window ind = find(~(inside | outside)); % allocate memroty for all clipped edges edge2 = zeros(size(edge)); % copy result of edges totally inside clipping box edge2(inside, :) = edge(inside, :); % iterate over edges for i = 1:length(ind) % current edge iedge = edge(ind(i), :); % compute intersection points with each line of bounding window px0 = intersectLineEdge(lineX0, iedge); px1 = intersectLineEdge(lineX1, iedge); py0 = intersectLineEdge(lineY0, iedge); py1 = intersectLineEdge(lineY1, iedge); % create array of points points = [px0; px1; py0; py1; iedge(1:2); iedge(3:4)]; % remove infinite points (edges parallel to box edges) points = points(all(isfinite(points), 2), :); % sort points by x then y points = sortrows(points); % get center positions between consecutive points centers = (points(2:end,:) + points(1:end-1,:))/2; % find the centers (if any) inside window inside = find( centers(:,1) >= xmin & centers(:,2) >= ymin & ... centers(:,1) <= xmax & centers(:,2) <= ymax); % if multiple segments are inside box, which can happen due to finite % resolution, only take the longest segment if length(inside) > 1 % compute delta vectors of the segments dv = points(inside+1,:) - points(inside,:); % compute lengths of segments len = hypot(dv(:,1), dv(:,2)); % find index of longest segment [a, I] = max(len); %#ok inside = inside(I); end % if one of the center points is inside box, then the according edge % segment is indide box if length(inside) == 1 % restore same direction of edge if iedge(1) > iedge(3) || (iedge(1) == iedge(3) && iedge(2) > iedge(4)) edge2(ind(i), :) = [points(inside+1,:) points(inside,:)]; else edge2(ind(i), :) = [points(inside,:) points(inside+1,:)]; end end end % end of loop over edges matgeom-1.2.4/inst/geom2d/PaxHeaders/distancePointLine.m0000644000000000000000000000013214576357161020170 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/distancePointLine.m0000644000175000017500000000753114576357161021756 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [dist, pos] = distancePointLine(point, line) %DISTANCEPOINTLINE Minimum distance between a point and a line. % % D = distancePointLine(POINT, LINE) % Return the euclidean distance between line LINE and point POINT. % % LINE has the form: [x0 y0 dx dy], and POINT is [x y]. % % If LINE is N-by-4 array, result is N-by-1 array computes for each line. % % If POINT is N-by-2, then result is computed for each point. % % If both POINT and LINE are array, result is computed for each couple of % point and line, and is returned in a NP-by-NL array, where NP is the % number of points, and NL is the number of lines. % % % See also % lines2d, points2d, distancePoints, distancePointEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-06-24 % Copyright 2005-2023 INRA - BIA-BIBS % direction vector of each line (row vectors) vx = line(:, 3)'; vy = line(:, 4)'; % squared norm of direction vectors, with a check of validity delta = (vx .* vx + vy .* vy); invalidEdges = delta < eps; delta(invalidEdges) = 1; % difference of coordinates between point and line origins % (NP-by-NE arrays) dx = bsxfun(@minus, point(:, 1), line(:, 1)'); dy = bsxfun(@minus, point(:, 2), line(:, 2)'); % compute position of points projected on the line, by using normalised dot % product % (result is a NP-by-NL array) pos = bsxfun(@rdivide, bsxfun(@times, dx, vx) + bsxfun(@times, dy, vy), delta); % ensure degenerated lines are correclty processed (consider the line % origin as closest point) pos(:, invalidEdges) = 0; % compute distance between point and its projection on the line dist = hypot(bsxfun(@times, pos, vx) - dx, bsxfun(@times, pos, vy) - dy); % if size(line, 1)==1 && size(point, 1)>1 % line = repmat(line, [size(point, 1) 1]); % end % % if size(point, 1)==1 && size(line, 1)>1 % point = repmat(point, [size(line, 1) 1]); % end % % dx = line(:, 3); % dy = line(:, 4); % % % compute position of points projected on line % tp = ((point(:, 2) - line(:, 2)).*dy + (point(:, 1) - line(:, 1)).*dx) ./ (dx.*dx+dy.*dy); % p0 = line(:, 1:2) + [tp tp].*[dx dy]; % % % % compute distances between points and their projections % dx = point - p0; % dist = sqrt(sum(dx.*dx, 2)); matgeom-1.2.4/inst/geom2d/PaxHeaders/drawEllipseAxes.m0000644000000000000000000000013214576357161017650 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawEllipseAxes.m0000644000175000017500000000754214576357161021440 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipseAxes(varargin) %DRAWELLIPSEAXES Draw the main axes of an ellipse as line segments. % % drawEllipseAxes(ELLI) % drawEllipseAxes(..., STYLE) % drawEllipseAxes(..., NAME, VALUE) % Draw the axes of the ellipse given by ELLI onto the currrent axis. % STYLE specifies the drawing style using a short character array like % 'b', 'k:', 'm-'... % More complex drawing style can be specified using plot-like parameter % name-value pairs. % % drawEllipseAxes(AX, ELLI) % Specifies the axes to draw the ellipse on. % % Example % elli = [50 50 40 20 30]; % figure; hold on; axis equal; axis([0 100 0 100]); % drawEllipse(elli, 'LineWidth', 2, 'Color', 'b') % drawEllipseAxes(elli, 'k') % % See also % ellipses2d, drawEllipse, drawEllipseArc % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-09-11, using Matlab 9.9.0.1570001 (R2020b) Update 4 % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Extract input arguments % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % extract dawing style strings styles = {}; for iElli = 1:length(varargin) if ischar(varargin{iElli}) styles = varargin(iElli:end); varargin(iElli:end) = []; break; end end % retrieve ellipse parameters ellipse = varargin{1}; x0 = ellipse(:, 1); y0 = ellipse(:, 2); a = ellipse(:, 3); b = ellipse(:, 4); theta = ellipse(:, 5); nElli = length(x0); %% Process drawing of a set of ellipses % angular positions of edge extremities ti = [0 pi pi/2 3*pi/2]; % compute position of points to draw each ellipse h = zeros(2 * nElli , 1); for iElli = 1:nElli % pre-compute rotation angles (given in degrees) cot = cosd(theta(iElli)); sit = sind(theta(iElli)); % compute position of points used to draw current ellipse xt = x0(iElli) + a(iElli) * cos(ti) * cot - b(iElli) * sin(ti) * sit; yt = y0(iElli) + a(iElli) * cos(ti) * sit + b(iElli) * sin(ti) * cot; % stores handle to graphic object h(2 * iElli - 1) = plot(ax, xt(1:2), yt(1:2), styles{:}); h(2 * iElli) = plot(ax, xt(3:4), yt(3:4), styles{:}); end % return handles if required if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/cartesianLine.m0000644000000000000000000000013214576357161017335 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/cartesianLine.m0000644000175000017500000000452714576357161021125 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = cartesianLine(varargin) %CARTESIANLINE Create a straight line from cartesian equation coefficients. % % L = cartesianLine(A, B, C); % Create a line verifying the Cartesian equation: % A*x + B*x + C = 0; % % See also % lines2d, createLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-25 % Copyright 2004-2023 INRA - Cepia Software Platform if length(varargin)==1 var = varargin{1}; a = var(:,1); b = var(:,2); c = var(:,3); elseif length(varargin)==3 a = varargin{1}; b = varargin{2}; c = varargin{3}; end % normalisation factor d = a.*a + b.*b; x0 = -a.*c./d; y0 = -b.*c./d; theta = atan2(-a, b); dx = cos(theta); dy = sin(theta); line = [x0 y0 dx dy]; matgeom-1.2.4/inst/geom2d/PaxHeaders/pointOnLine.m0000644000000000000000000000013214576357161017012 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/pointOnLine.m0000644000175000017500000000445014576357161020575 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = pointOnLine(line, pos) %POINTONLINE Create a point on a line at a given position on the line. % % P = pointOnLine(LINE, POS); % Creates the point belonging to the line LINE, and located at the % distance D from the line origin. % LINE has the form [x0 y0 dx dy]. % LINE and D should have the same number N of rows. The result will have % N rows ans 2 column (x and y positions). % % See also % lines2d, points2d, onLine, onLine, linePosition % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-07 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE angle = lineAngle(line); point = [line(:,1) + pos .* cos(angle), line(:,2) + pos .* sin(angle)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/clipRay.m0000644000000000000000000000013214576357161016157 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/clipRay.m0000644000175000017500000000664314576357161017750 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [edge, isInside] = clipRay(ray, bb) %CLIPRAY Clip a ray with a box. % % EDGE = clipRay(RAY, BOX); % RAY is a straight ray given as a 4 element row vector: [x0 y0 dx dy], % with (x0 y0) being the origin of the ray and (dx dy) its direction % vector, BOX is the clipping box, given by its extreme coordinates: % [xmin xmax ymin ymax]. % The result is given as an edge, defined by the coordinates of its 2 % extreme points: [x1 y1 x2 y2]. % If the ray does not intersect the box, [NaN NaN NaN NaN] is returned. % % Function works also if RAY is a N-by-4 array, if BOX is a Nx4 array, or % if both RAY and BOX are N-by-4 arrays. In these cases, EDGE is a N-by-4 % array. % % See also % rays2d, boxes2d, edges2d, clipLine, drawRay % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-05-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2010-2023 INRA - Cepia Software Platform % adjust size of two input arguments if size(ray, 1) == 1 ray = repmat(ray, size(bb, 1), 1); elseif size(bb, 1) == 1 bb = repmat(bb, size(ray, 1), 1); elseif size(ray, 1) ~= size(bb, 1) error('bad sizes for input'); end % first compute clipping of supporting line edge = clipLine(ray, bb); % detects valid edges (edges outside box are all NaN) inds = find(isfinite(edge(:, 1))); % compute position of edge extremities relative to the ray pos1 = linePosition(edge(inds,1:2), ray(inds,:), 'diag'); pos2 = linePosition(edge(inds,3:4), ray(inds,:), 'diag'); % if first point is before ray origin, replace by origin edge(inds(pos1 < 0), 1:2) = ray(inds(pos1 < 0), 1:2); % if last point of edge is before origin, set all edge to NaN edge(inds(pos2 < 0), :) = NaN; % eventually returns result about inside or outside if nargout > 1 isInside = isfinite(edge(:,1)); end matgeom-1.2.4/inst/geom2d/PaxHeaders/edgePosition.m0000644000000000000000000000013214576357161017205 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/edgePosition.m0000644000175000017500000000757614576357161021004 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function pos = edgePosition(point, edge, varargin) %EDGEPOSITION Return position of a point on an edge. % % POS = edgePosition(POINT, EDGE); % Computes position of point POINT on the edge EDGE, relative to the % position of edge vertices. % EDGE has the form [x1 y1 x2 y2], % POINT has the form [x y], and is assumed to belong to edge supporting % line. The result POS has the following meaning: % POS < 0: POINT is located before the first vertex % POS = 0: POINT is located on the first vertex % 0 < POS < 1: POINT is located between the 2 vertices (on the edge) % POS = 1: POINT is located on the second vertex % POS > 1: POINT is located after the second vertex % % POS = edgePosition(POINT, EDGES); % If EDGES is an array of NL edges, return NE positions, corresponding to % each edge. % % POS = edgePosition(POINTS, EDGE); % If POINTS is an array of NP points, return NP positions, corresponding % to each point. % % POS = edgePosition(POINTS, EDGES); % If POINTS is an array of NP points and EDGES is an array of NE edges, % return an array of [NP NE] position, corresponding to each couple % point-edge. % % POS = edgePosition(POINTS, EDGES, 'diag'); % When POINTS and EDGES are two arrays with same number of rows, returns % single column vector corresponding to each pair of point-edge. % % See also % edges2d, createEdge, isPointOnEdge, edgeToLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-25 % Copyright 2004-2023 INRA - Cepia Software Platform % parse input options diag = false; if ~isempty(varargin) && strcmp(varargin{1}, 'diag') diag = true; end % number of points and of edges nEdges = size(edge, 1); nPoints = size(point, 1); if nPoints == nEdges && diag % reshape into N-by-1 arrays dxe = (edge(:,3) - edge(:,1)); dye = (edge(:,4) - edge(:,2)); dxp = point(:,1) - edge(:,1); dyp = point(:,2) - edge(:,2); else % reshape arrays to result in NP-by-NE arrays dxe = (edge(:,3) - edge(:,1))'; dye = (edge(:,4) - edge(:,2))'; dxp = bsxfun(@minus, point(:,1), edge(:,1)'); dyp = bsxfun(@minus, point(:,2), edge(:,2)'); end % compute position pos = (dxp .* dxe + dyp .* dye) ./ (dxe .* dxe + dye .* dye); matgeom-1.2.4/inst/geom2d/PaxHeaders/intersectBoxes.m0000644000000000000000000000013214576357161017555 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/intersectBoxes.m0000644000175000017500000000477114576357161021346 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = intersectBoxes(box1, box2) %INTERSECTBOXES Intersection of two bounding boxes. % % RES = intersectBoxes(BOX1, BOX2) % % Example % box1 = [5 20 5 30]; % box2 = [0 15 0 15]; % intersectBoxes(box1, box2) % ans = % 5 15 5 15 % % See also % boxes2d, drawBox, mergeBoxes % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % unify sizes of data if size(box1,1) == 1 box1 = repmat(box1, size(box2,1), 1); elseif size(box2, 1) == 1 box2 = repmat(box2, size(box1,1), 1); elseif size(box1,1) ~= size(box2,1) error('Bad size for inputs'); end % compute extreme coords mini = min(box1(:,[2 4]), box2(:,[2 4])); maxi = max(box1(:,[1 3]), box2(:,[1 3])); % concatenate result into a new box structure box = [maxi(:,1) mini(:,1) maxi(:,2) mini(:,2)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/createLineReflection.m0000644000000000000000000000013214576357161020642 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createLineReflection.m0000644000175000017500000000507114576357161022425 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createLineReflection(line) %CREATELINEREFLECTION Create the the 3x3 matrix of a line reflection. % % TRANS = createLineReflection(LINE); % where line is given as [x0 y0 dx dy], return the affine tansform % corresponding to the desired line reflection % % % See also % lines2d, transforms2d, transformPoint, % createTranslation, createHomothecy, createScaling % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-01-19 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract line parameters x0 = line(:,1); y0 = line(:,2); dx = line(:,3); dy = line(:,4); % normalisation coefficient of line direction vector delta = dx*dx + dy*dy; % compute coefficients of transform m00 = (dx*dx - dy*dy)/delta; m01 = 2*dx*dy/delta; m02 = 2*dy*(dy*x0 - dx*y0)/delta; m10 = 2*dx*dy/delta; m11 = (dy*dy - dx*dx)/delta; m12 = 2*dx*(dx*y0 - dy*x0)/delta; % create transformation trans = [m00 m01 m02; m10 m11 m12; 0 0 1]; matgeom-1.2.4/inst/geom2d/PaxHeaders/mergeClosePoints.m0000644000000000000000000000013214576357161020036 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/mergeClosePoints.m0000644000175000017500000000522114576357161021616 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = mergeClosePoints(points, varargin) %MERGECLOSEPOINTS Merge points that are closer than a given distance. % % PTS2 = mergeClosePoints(PTS, DIST) % Remove points in the array PTS such that no points closer than the % distance DIST remain in the array. % % PTS2 = mergeClosePoints(PTS) % If the distance is not specified, the default value 1e-14 is used. % % % Example % pts = rand(200, 2); % pts2 = mergeClosePoints(pts, .1); % figure; drawPoint(pts, '.'); % hold on; drawPoint(pts2, 'mo'); % % See also % points2d, removeMultipleVertices % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % default values minDist = 1e-14; if ~isempty(varargin) minDist = varargin{1}; end i = 1; while i < size(points, 1) dist = distancePoints(points(i,:), points); inds = dist < minDist; inds(i) = 0; points(inds, :) = []; % switch to next point i = i + 1; end matgeom-1.2.4/inst/geom2d/PaxHeaders/createRotation.m0000644000000000000000000000013214576357161017537 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createRotation.m0000644000175000017500000000653214576357161021325 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = createRotation(varargin) %CREATEROTATION Create the 3*3 matrix of a rotation. % % TRANS = createRotation(THETA); % Returns the rotation corresponding to angle THETA (in radians) % The returned matrix has the form : % [cos(theta) -sin(theta) 0] % [sin(theta) cos(theta) 0] % [0 0 1] % % TRANS = createRotation(POINT, THETA); % TRANS = createRotation(X0, Y0, THETA); % Also specifies origin of rotation. The result is similar as performing % translation(-X0, -Y0), rotation(THETA), and translation(X0, Y0). % % Example % % apply a rotation on a polygon % poly = [0 0; 30 0;30 10;10 10;10 20;0 20]; % trans = createRotation([10 20], pi/6); % polyT = transformPoint(poly, trans); % % display the original and the rotated polygons % figure; hold on; axis equal; axis([-10 40 -10 40]); % drawPolygon(poly, 'k'); % drawPolygon(polyT, 'b'); % % See also % transforms2d, transformPoint, createRotation90, createTranslation % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % default values cx = 0; cy = 0; theta = 0; % get input values if length(varargin)==1 % only angle theta = varargin{1}; elseif length(varargin)==2 % origin point (as array) and angle var = varargin{1}; cx = var(1); cy = var(2); theta = varargin{2}; elseif length(varargin)==3 % origin (x and y) and angle cx = varargin{1}; cy = varargin{2}; theta = varargin{3}; end % compute coefs cot = cos(theta); sit = sin(theta); tx = cy*sit - cx*cot + cx; ty = -cy*cot - cx*sit + cy; % create transformation matrix trans = [cot -sit tx; sit cot ty; 0 0 1]; matgeom-1.2.4/inst/geom2d/PaxHeaders/createCircle.m0000644000000000000000000000013214576357161017141 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createCircle.m0000644000175000017500000000624614576357161020731 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function circle = createCircle(varargin) %CREATECIRCLE Create a circle from 2 or 3 points. % % C = createCircle(P1, P2, P3); % Creates the circle passing through the 3 given points. % C is a 1*3 array of the form: [XC YX R]. % % C = createCircle(P1, P2); % Creates the circle whith center P1 and passing throuh the point P2. % % Works also when input are point arrays the same size, in this case the % result has as many lines as the point arrays. % % Example % % Draw a circle passing through 3 points. % p1 = [10 15]; % p2 = [15 20]; % p3 = [10 25]; % circle = createCircle(p1, p2, p3); % figure; hold on; axis equal; axis([0 50 0 50]); % drawPoint([p1 ; p2; p3]); % drawCircle(circle); % % See also % circles2d, createDirectedCircle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE if nargin == 2 % inputs are the center and a point on the circle p1 = varargin{1}; p2 = varargin{2}; x0 = p1(:,1); y0 = p1(:,2); r = hypot((p2(:,1)-x0), (p2(:,2)-y0)); elseif nargin == 3 % inputs are three points on the circle p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; % compute circle center line1 = medianLine(p1, p2); line2 = medianLine(p1, p3); point = intersectLines(line1, line2); x0 = point(:, 1); y0 = point(:, 2); % circle radius r = hypot((p1(:,1)-x0), (p1(:,2)-y0)); end % create array for returning result circle = [x0 y0 r]; matgeom-1.2.4/inst/geom2d/PaxHeaders/isPerpendicular.m0000644000000000000000000000013214576357161017705 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isPerpendicular.m0000644000175000017500000000600514576357161021466 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPerpendicular(v1, v2, varargin) %ISPERPENDICULAR Check orthogonality of two vectors. % % B = isPerpendicular(V1, V2) % where V1 and V2 are two 1-by-2 row arrays, returns 1 if the vectors are % perpendicular, and 0 otherwise. % % Also works when V1 and V2 are two N-by-2 arrays with same number of % rows. In this case, return a N-by-1 array containing 1 at the positions % of perpendicular vectors. % % Also works when one of V1 or V2 is 1-by-2 and the other one is a N-by-2 % array. In this case the result has size N-by-1. % % B = isPerpendicular(V1, V2, ACCURACY) % specifies accuracy of numerical tests, default is 1e-14. % % % Example % isPerpendicular([1 2 1], [2 4 2]) % ans = % 1 % % isPerpendicular([1 2 1], [1 3 2]) % ans = % 0 % % See also % vectors2d, isParallel, lines2d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-04-25 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % default accuracy acc = 1e-14; if ~isempty(varargin) acc = abs(varargin{1}); end % normalize vectors v1 = normalizeVector(v1); v2 = normalizeVector(v2); % adapt size of inputs n1 = size(v1, 1); n2 = size(v2, 1); if n1 ~= n2 if n1 == 1 v1 = v1(ones(n2, 1), :); elseif n2==1 v2 = v2(ones(n1, 1), :); else error('Inputs must either have same size, or one must be scalar'); end end % performs test b = abs(dot(v1, v2, 2)) < acc; matgeom-1.2.4/inst/geom2d/PaxHeaders/radicalAxis.m0000644000000000000000000000013214576357161017000 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/radicalAxis.m0000644000175000017500000000566414576357161020573 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function line = radicalAxis(circle1, circle2) %RADICALAXIS Compute the radical axis (or radical line) of 2 circles. % % L = radicalAxis(C1, C2) % Computes the radical axis of 2 circles. % % Example % C1 = [10 10 5]; % C2 = [60 50 30]; % L = radicalAxis(C1, C2); % hold on; axis equal;axis([0 100 0 100]); % drawCircle(C1);drawCircle(C2);drawLine(L); % % See also % lines2d, circles2d, createCircle % % Ref: % http://mathworld.wolfram.com/RadicalLine.html % http://en.wikipedia.org/wiki/Radical_axis % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-05-15, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % extract circles parameters x1 = circle1(:,1); x2 = circle2(:,1); y1 = circle1(:,2); y2 = circle2(:,2); r1 = circle1(:,3); r2 = circle2(:,3); % distance between each couple of centers dist = sqrt((x2-x1).^2 + (y2-y1).^2); % relative position of intersection point of % the radical line with the line joining circle centers d = (dist.^2 + r1.^2 - r2.^2) * .5 ./ dist; % compute angle of radical axis angle = lineAngle(createLine([x1 y1], [x2 y2])); cot = cos(angle); sit = sin(angle); % parameters of the line x0 = x1 + d*cot; y0 = y1 + d*sit; dx = -sit; dy = cot; % concatenate into one structure line = [x0 y0 dx dy]; matgeom-1.2.4/inst/geom2d/PaxHeaders/ellipsePoint.m0000644000000000000000000000013214576357161017223 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/ellipsePoint.m0000644000175000017500000000532314576357161021006 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = ellipsePoint(elli, pos) %ELLIPSEPOINT Coordinates of a point on an ellipse from parametric equation. % % POINT = ellipsePoint(ELLI, POS) % Computes the coordinates of the point with parameter value POS on the % ellipse. POS is contained within [0, 2*PI]. % % Example % elli = [50 50 40 20 30]; % pts = ellipsePoint(elli, linspace(0, pi, 12)); % figure; drawEllipse(elli, 'b'); hold on; % axis equal; axis([0 100 0 100]); % drawPoint(pts, 'bo'); % % See also % ellipses2d, drawEllipse, projPointOnEllipse, ellipseToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-09-09, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % make sure pos is column vector pos = pos(:); % pre-compute rotation angles (given in degrees) theta = elli(:,5); cot = cosd(theta); sit = sind(theta); % compute position of points used to draw current ellipse a = elli(:,3); b = elli(:,4); xt = elli(:,1) + a * cos(pos) * cot - b * sin(pos) * sit; yt = elli(:,2) + a * cos(pos) * sit + b * sin(pos) * cot; % concatenate point = [xt yt]; matgeom-1.2.4/inst/geom2d/PaxHeaders/intersectLines.m0000644000000000000000000000013214576357161017547 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/intersectLines.m0000644000175000017500000001117314576357161021332 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = intersectLines(line1, line2, varargin) %INTERSECTLINES Return all intersection points of N lines in 2D. % % PT = intersectLines(L1, L2); % returns the intersection point of lines L1 and L2. L1 and L2 are 1-by-4 % row arrays, containing parametric representation of each line (in the % form [x0 y0 dx dy], see 'createLine' for details). % % In case of colinear lines, returns [Inf Inf]. % In case of parallel but not colinear lines, returns [NaN NaN]. % % If each input is [N*4] array, the result is a [N*2] array containing % intersections of each couple of lines. % If one of the input has N rows and the other 1 row, the result is a % [N*2] array. % % PT = intersectLines(L1, L2, EPS); % Specifies the tolerance for detecting parallel lines. Default is 1e-14. % % Example % line1 = createLine([0 0], [10 10]); % line2 = createLine([0 10], [10 0]); % point = intersectLines(line1, line2) % point = % 5 5 % % See also % lines2d, edges2d, intersectEdges, intersectLineEdge % intersectLineCircle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% Process input arguments % extract tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % check size of each input N1 = size(line1, 1); N2 = size(line2, 1); N = max(N1, N2); if N1 ~= N2 && N1*N2 ~= N error('matGeom:IntersectLines:IllegalArgument', ... 'The two input arguments must have same number of lines'); end %% Check parallel and colinear lines % coordinate differences of origin points dx = bsxfun(@minus, line2(:,1), line1(:,1)); dy = bsxfun(@minus, line2(:,2), line1(:,2)); % indices of parallel lines denom = line1(:,3) .* line2(:,4) - line2(:,3) .* line1(:,4); par = abs(denom) < tol; % indices of colinear lines col = abs(dx .* line1(:,4) - dy .* line1(:,3)) < tol & par ; % initialize result array x0 = zeros(N, 1); y0 = zeros(N, 1); % initialize result for parallel lines x0(col) = Inf; y0(col) = Inf; x0(par & ~col) = NaN; y0(par & ~col) = NaN; % in case all line couples are parallel, return if all(par) point = [x0 y0]; return; end %% Extract coordinates of itnersecting lines % indices of intersecting lines inds = ~par; % extract base coordinates of first lines if N1 > 1 line1 = line1(inds,:); end x1 = line1(:,1); y1 = line1(:,2); dx1 = line1(:,3); dy1 = line1(:,4); % extract base coordinates of second lines if N2 > 1 line2 = line2(inds,:); end x2 = line2(:,1); y2 = line2(:,2); dx2 = line2(:,3); dy2 = line2(:,4); % re-compute coordinate differences of origin points dx = bsxfun(@minus, line2(:,1), line1(:,1)); dy = bsxfun(@minus, line2(:,2), line1(:,2)); %% Compute intersection points denom = denom(inds); x0(inds) = (x2 .* dy2 .* dx1 - dy .* dx1 .* dx2 - x1 .* dy1 .* dx2) ./ denom ; y0(inds) = (dx .* dy1 .* dy2 + y1 .* dx1 .* dy2 - y2 .* dx2 .* dy1) ./ denom ; % concatenate result point = [x0 y0]; matgeom-1.2.4/inst/geom2d/PaxHeaders/vectors2d.m0000644000000000000000000000013214576357161016467 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/vectors2d.m0000644000175000017500000000441414576357161020252 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vectors2d %VECTORS2D Description of functions operating on plane vectors. % % A vector is defined by its two cartesian coordinates, put into a row % vector of 2 elements: % V = [vx vy]; % % Several vectors are stored in a matrix with two columns, one for the % x-coordinate, one for the y-coordinate. % VS = [vx1 vy1 ; vx2 vy2 ; vx3 vy3]; % % See also % vectorNorm, vectorAngle, isPerpendicular, isParallel % normalizeVector, transformVector, rotateVector % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas help('vectors2d'); matgeom-1.2.4/inst/geom2d/PaxHeaders/drawRect.m0000644000000000000000000000013214576357161016327 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawRect.m0000644000175000017500000000613714576357161020116 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawRect(varargin) %DRAWRECT Draw rectangle on the current axis. % % drawRect(RECT) % draws the rectangles defined by RECT = [X0 Y0 W H]. % the four corners of rectangle are then : % (X0, Y0), (X0+W, Y0), (X0, Y0+H), (X0+W, Y0+H). % % RECT = [X0 Y0 W H THETA] also specifies orientation for the rectangle. % Theta is given in degrees. % % If RECT is a N-by-4 or N-by-5 array, several rectangles are drawn. % % drawRect(..., PARAM, VALUE) % Specifies one or several parameters name-value pairs, see plot function % for details. % % drawRect(AX, ...) % Specifies the handle of the axis to draw the rectangle on. % % H = drawRect(...) % Returns handle of the created graphic objects. % % See also % drawOrientedBox, drawBox, rectToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-12-10 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on [ax, varargin] = parseAxisHandle(varargin{:}); rect = varargin{1}; varargin(1) = []; % number of rectangles to draw n = size(rect, 1); % save hold state holdState = ishold(ax); hold(ax, 'on'); % display each rectangle h = zeros(n, 1); for i = 1:n % compute vertex corodinates poly = rectToPolygon(rect(i, :)); % display resulting polygon h(i) = drawPolygon(ax, poly, varargin{:}); end % restore hold state if ~holdState hold(ax, 'off'); end % process output if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/ellipseToPolygon.m0000644000000000000000000000013214576357161020064 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/ellipseToPolygon.m0000644000175000017500000000635214576357161021652 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = ellipseToPolygon(ellipse, N) %ELLIPSETOPOLYGON Convert an ellipse into a series of points. % % P = ellipseToPolygon(ELL, N); % converts ELL given as [x0 y0 a b] or [x0 y0 a b theta] into a polygon % with N edges. The result P is a N-by-2 array containing the coordinates % of the N vertices of the polygon. % % P = ellipseToPolygon(ELL); % Use a default number of edges equal to 72. This results in one point % for each 5 degrees. % % [X, Y] = ellipseToPolygon(...); % Return the coordinates of vertices in two separate arrays. % % Example % poly = ellipseToPolygon([50 50 40 30 20], 60); % figure; hold on; % axis equal; axis([0 100 10 90]); % drawPolygon(poly, 'b'); % drawPoint(poly, 'bo'); % % See also % ellipses2d, drawEllipse, circleToPolygon, rectToPolygon, ellipsePoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-04-06 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % default value for N if nargin < 2 N = 72; end % angle of ellipse theta = 0; if size(ellipse, 2) > 4 theta = ellipse(:,5); end % get ellipse parameters xc = ellipse(:,1); yc = ellipse(:,2); a = ellipse(:,3); b = ellipse(:,4); % create time basis t = linspace(0, 2*pi, N+1)'; t(end) = []; % pre-compute trig functions (angles is in degrees) cot = cosd(theta); sit = sind(theta); % position of points x = xc + a * cos(t) * cot - b * sin(t) * sit; y = yc + a * cos(t) * sit + b * sin(t) * cot; % format output depending on number of a param. if nargout == 1 varargout = {[x y]}; elseif nargout == 2 varargout = {x, y}; end matgeom-1.2.4/inst/geom2d/PaxHeaders/angleDiff.m0000644000000000000000000000013214576357161016433 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/angleDiff.m0000644000175000017500000000455314576357161020222 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dif = angleDiff(angle1, angle2) %ANGLEDIFF Difference between two angles. % % Computes the signed angular difference between two angles in radians. % The result is comprised between -PI and +PI. % % Example % A = angleDiff(-pi/4, pi/4) % A = % 1.5708 % equal to pi/2 % A = angleDiff(pi/4, -pi/4) % A = % -1.5708 % equal to -pi/2 % % See also % angles2d, angleAbsDiff % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-07-27, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % first, normalization angle1 = normalizeAngle(angle1); angle2 = normalizeAngle(angle2); % compute difference and normalize in [-pi pi] dif = normalizeAngle(angle2 - angle1, 0); matgeom-1.2.4/inst/geom2d/PaxHeaders/drawPoint.m0000644000000000000000000000013214576357161016523 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawPoint.m0000644000175000017500000001016714576357161020310 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function h = drawPoint(varargin) %DRAWPOINT Draw the point on the axis. % % drawPoint(X, Y); % Draws points defined by coordinates X and Y. % X and Y should be array the same size. % % drawPoint(COORD); % Packs coordinates in a single N-by-2 array. % % drawPoint(..., OPT); % Draws each point with given option. OPT is a series of arguments pairs % compatible with 'plot' model. Default drawing option is 'bo', % corresponding to blue circles. % If a format string is used then only the color is effective. % Markers can be set using the 'marker' property. % The property 'linestyle' cannot be set. % % drawPoint(AX, ...); % Specifies the axis to draw the points in. AX should be a handle to a axis % object. By default, display on current axis. % % H = drawPoint(...) also return a handle to each of the drawn points. % % Example % % display a single point % figure; % drawPoint([10 10]); % % % display several points forming a circle % t = linspace(0, 2*pi, 20)'; % drawPoint([5*cos(t)+10 3*sin(t)+10], 'r+'); % axis equal; % % See also % points2d, clipPoints % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw in [ax, varargin] = parseAxisHandle(varargin{:}); % extract point(s) coordinates if size(varargin{1}, 2) == 2 % points packed in one array var = varargin{1}; px = var(:, 1); py = var(:, 2); varargin(1) = []; elseif isvector(varargin{1}) % points stored in separate arrays if nargin == 1 || ~isnumeric(varargin{2}) error('Missing array of y-coordinates'); end px = varargin{1}; py = varargin{2}; varargin(1:2) = []; px = px(:); py = py(:); else error('Points should be two 1D arrays or one N-by-2 array'); end if length(varargin) > 1 % Check if linestyle is given char_opt = cellfun(@lower, varargin(cellfun(@ischar, varargin)), ... 'UniformOutput', false); tf = ismember('linestyle', char_opt); if tf error('Points cannot be draw with lines, use plot or drawPolygon instead'); end hh = plot(ax, px, py, 'marker', 'o', 'linestyle', 'none', varargin{:}); elseif length(varargin) == 1 % use the specified single option (for example: 'b.', or 'k+') hh = plot(ax, px, py, varargin{1}); else % use a default marker hh = plot(ax, px, py, 'o'); end if nargout == 1 h = hh; end end matgeom-1.2.4/inst/geom2d/PaxHeaders/private0000644000000000000000000000013214576357160015772 xustar0030 mtime=1710874224.578193881 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/private/0000755000175000017500000000000014576357160017627 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/geom2d/private/PaxHeaders/parseThreePoints.m0000644000000000000000000000013214576357161021525 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/private/parseThreePoints.m0000644000175000017500000000500614576357161023306 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [a b c] = parseThreePoints(varargin) %PARSETHREEPOINTS Parse three points from variable length input array. % % [A B C] = parseThreePoints(PTS); % [A B C] = parseThreePoints(P1, P2, P3); % [A B C] = parseThreePoints(VERTICES, INDS); % % Example % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % extract input args if nargin == 1 % inputs are 3 points packed into a 3-by-2 array var = varargin{1}; a = var(1,:); b = var(2,:); c = var(3,:); elseif nargin == 3 % inputs are 3 separate points a = varargin{1}; b = varargin{2}; c = varargin{3}; elseif nargin == 2 % inputs are a vertex array, and index array pts = varargin{1}; inds = varargin{2}; a = pts(inds(1), :); b = pts(inds(2), :); c = pts(inds(3), :); end matgeom-1.2.4/inst/geom2d/PaxHeaders/isLeftOriented.m0000644000000000000000000000013214576357161017474 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isLeftOriented.m0000644000175000017500000000466214576357161021264 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isLeftOriented(point, line) %ISLEFTORIENTED Test if a point is on the left side of a line. % % B = isLeftOriented(POINT, LINE); % Returns TRUE if the point lies on the left side of the line with % respect to the line direction. % % If POINT is a NP-by-2 array, and/or LINE is a NL-by-4 array, the result % is a NP-by-NL array containing the result for each point-line % combination. % % See also % lines2d, points2d, isCounterClockwise, isPointOnLine, distancePointLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-07-31 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % equivalent to: % b = (xp-x0).*dy-(yp-y0).*dx < 0; b = bsxfun(@minus, ... bsxfun(@times, bsxfun(@minus, point(:,1), line(:,1)'), line(:,4)'), ... bsxfun(@times, bsxfun(@minus, point(:,2), line(:,2)'), line(:,3)')) < 0; matgeom-1.2.4/inst/geom2d/PaxHeaders/nndist.m0000644000000000000000000000013214576357161016053 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/nndist.m0000644000175000017500000000740014576357161017634 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [dists, neighInds] = nndist(points) %NNDIST Nearest-neighbor distances of each point in a set. % % DISTS = nndist(POINTS) % Returns the distance to the nearest neighbor of each point in an array % of points. % POINTS is an array of points, NP-by-ND. % DISTS is a NP-by-1 array containing the distances to the nearest % neighbor. % % This functions first computes the Delaunay triangulation of the set of % points, then search for nearest distance in the set of each vertex % neighbors. This reduces the overall complexity, but difference was % noticed only for large sets (>10000 points) % % Example % % Display Stienen diagram of a set of random points in unit square % pts = rand(100, 2); % [dists, inds] = nndist(pts); % figure; drawPoint(pts, 'k.'); % hold on; drawCircle([pts dists/2], 'b'); % axis equal; axis([-.1 1.1 -.1 1.1]); % % also display edges % drawEdge([pts pts(inds, :)], 'b'); % % See also % points2d, distancePoints, minDistancePoints, findPoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-01, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % number of points n = size(points, 1); % allocate memory dists = zeros(n, 1); neighInds = zeros(n, 1); % in case of few points, use direct computation if n < 3 inds = 1:n; for i = 1:n % compute minimal distance [dists(i), indN] = minDistancePoints(points(i,:), points(inds~=i, :)); if indN >= i neighInds(i) = inds(indN) + 1; else neighInds(i) = inds(indN); end end return; end % use Delaunay Triangulation to facilitate computations DT = delaunay (points); % compute distance to nearest neighbor of each point in the pattern for i = 1:n % find indices of neighbor vertices in Delaunay Triangulation. % this set contains the nearest neighbor inds = unique(DT(sum(DT == i, 2) > 0, :)); inds = inds(inds~=i); % compute minimal distance [dists(i), indN] = min(distancePoints(points(i,:), points(inds, :))); neighInds(i) = inds(indN); end matgeom-1.2.4/inst/geom2d/PaxHeaders/transformPoint.m0000644000000000000000000000013214576357161017601 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/transformPoint.m0000644000175000017500000000660314576357161021366 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = transformPoint(varargin) %TRANSFORMPOINT Apply an affine transform to a point or a point set. % % PT2 = transformPoint(PT1, TRANSFO); % Returns the result of the transformation TRANSFO applied to the point % PT1. PT1 has the form [xp yp], and TRANSFO is either a 2-by-2, a % 2-by-3, or a 3-by-3 matrix, % % Format of TRANSFO can be one of : % [a b] , [a b c] , or [a b c] % [d e] [d e f] [d e f] % [0 0 1] % % PT2 = transformPoint(PT1, TRANSFO); % Also works when PTA is a N-by-2 array representing point coordinates. % In this case, the result PT2 has the same size as PT1. % % [X2, Y2] = transformPoint(X1, Y1, TRANS); % Also works when PX1 and PY1 are two arrays the same size. The function % transforms each pair (PX1, PY1), and returns the result in (X2, Y2), % which has the same size as (PX1 PY1). % % % See also % points2d, transforms2d, translation, rotation % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % parse input arguments if length(varargin) == 2 var = varargin{1}; px = var(:,1); py = var(:,2); trans = varargin{2}; elseif length(varargin) == 3 px = varargin{1}; py = varargin{2}; trans = varargin{3}; else error('wrong number of arguments in "transformPoint"'); end % apply linear part of the transform px2 = px * trans(1,1) + py * trans(1,2); py2 = px * trans(2,1) + py * trans(2,2); % add translation vector, if exist if size(trans, 2) > 2 px2 = px2 + trans(1,3); py2 = py2 + trans(2,3); end % format output arguments if nargout < 2 varargout{1} = [px2 py2]; elseif nargout varargout{1} = px2; varargout{2} = py2; end matgeom-1.2.4/inst/geom2d/PaxHeaders/lineToEdge.m0000644000000000000000000000013214576357161016573 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/lineToEdge.m0000644000175000017500000000443514576357161020361 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = lineToEdge(line) %LINETOEDGE Convert a straight line to a finite edge. % % EDGE = lineToEdge(LINE) % Returns the edge with same origin as the line LINE, and with second % extremity corresponding to the addition of line origin and direction. % LINE is represented as [X0 Y0 DX DY] % EDGE is represented as [X1 Y1 X2 Y2] % % Example % line = [3 4 1 2]; % edge = lineToEdge(line) % edge = % 3 4 4 6 % % See also % lines2d, edges2d, edgeToLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-05-07, using Matlab 9.6.0.1072779 (R2019a) % Copyright 2019-2023 INRA - Cepia Software Platform edge = [line(:, 1:2) line(:,1:2)+line(:,3:4)]; matgeom-1.2.4/inst/geom2d/PaxHeaders/intersectLineEdge.m0000644000000000000000000000013214576357161020151 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/intersectLineEdge.m0000644000175000017500000001173314576357161021736 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = intersectLineEdge(line, edge, varargin) %INTERSECTLINEEDGE Return intersection between a line and an edge. % % P = intersectLineEdge(LINE, EDGE); % returns the intersection point of lines LINE and edge EDGE. % LINE is a 1-by-4 array containing parametric representation of the line % (in the form [x0 y0 dx dy], see 'createLine' for details). % EDGE is a 1-by-4 array containing the coordinates of first and second % points (in the form [x1 y1 x2 y2], see 'createEdge' for details). % % In case of colinear line and edge, returns [Inf Inf]. % If line does not intersect edge, returns [NaN NaN]. % % If each input is N-by-4 array, the result is a N-by-2 array containing % intersections for each couple of edge and line. % If one of the input has N rows and the other 1 row, the result is a % N-by-2 array. % % P = intersectLineEdge(LINE, EDGE, TOL); % Specifies the tolerance option for determining if a point belongs to an % edge and if lines are parallel. % % See also % lines2d, edges2d, intersectEdges, intersectLines % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract tolerance option tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % number of lines and edges nLines = size(line, 1); nEdges = size(edge, 1); % origin and direction vector of lines lx0 = line(:,1); ly0 = line(:,2); ldx = line(:,3); ldy = line(:,4); % origin and direction vector of edges ex1 = edge(:,1); ey1 = edge(:,2); ex2 = edge(:,3); ey2 = edge(:,4); edx = ex2 - ex1; edy = ey2 - ey1; % normalizes direction vectors ldn = hypot(ldx, ldy); ldx = ldx ./ ldn; ldy = ldy ./ ldn; % normalizes direction vectors edgeLength = hypot(edx, edy); edx = edx ./ edgeLength; edy = edy ./ edgeLength; % indices of parallel lines par = abs(ldx .* edy - edx .* ldy) < tol; % indices of colinear lines col = abs((ex1-lx0) .* ldy - (ey1-ly0) .* ldx) < tol & par ; xi(col) = Inf; yi(col) = Inf; xi(par & ~col) = NaN; yi(par & ~col) = NaN; i = ~par; % compute intersection points if nLines == nEdges xi(i) = ((ey1(i)-ly0(i)).*ldx(i).*edx(i) + lx0(i).*ldy(i).*edx(i) - ex1(i).*edy(i).*ldx(i)) ./ ... (edx(i).*ldy(i)-ldx(i).*edy(i)) ; yi(i) = ((ex1(i)-lx0(i)).*ldy(i).*edy(i) + ly0(i).*ldx(i).*edy(i) - ey1(i).*edx(i).*ldy(i)) ./ ... (ldx(i).*edy(i)-edx(i).*ldy(i)) ; elseif nLines == 1 xi(i) = ((ey1(i)-ly0).*ldx.*edx(i) + lx0.*ldy.*edx(i) - ex1(i).*edy(i).*ldx) ./ ... (edx(i).*ldy-ldx.*edy(i)) ; yi(i) = ((ex1(i)-lx0).*ldy.*edy(i) + ly0.*ldx.*edy(i) - ey1(i).*edx(i).*ldy) ./ ... (ldx.*edy(i)-edx(i).*ldy) ; elseif nEdges == 1 xi(i) = ((ey1-ly0(i)).*ldx(i).*edx + lx0(i).*ldy(i).*edx - ex1(i).*edy.*ldx(i)) ./ ... (edx.*ldy(i)-ldx(i).*edy) ; yi(i) = ((ex1-lx0(i)).*ldy(i).*edy + ly0(i).*ldx(i).*edy - ey1(i).*edx.*ldy(i)) ./ ... (ldx(i).*edy-edx.*ldy(i)) ; end % format output arguments point = [xi' yi']; % compute position of points projected on the supporting line, by using % dot product and normalising by edge length pos = bsxfun(@rdivide, ... bsxfun(@times, bsxfun(@minus, xi, ex1), edx) + ... bsxfun(@times, bsxfun(@minus, yi, ey1), edy), edgeLength); % set coordinates of points outside edge to NaN out = pos < -tol | pos > (1+tol); point(out, :) = NaN; matgeom-1.2.4/inst/geom2d/PaxHeaders/rectToPolygon.m0000644000000000000000000000013214576357161017364 xustar0030 mtime=1710874225.130193352 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/rectToPolygon.m0000644000175000017500000000553214576357161021151 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [tx, ty] = rectToPolygon(rect) %RECTTOPOLYGON Convert a rectangle into a polygon (set of vertices). % % POLY = rectToPolygon(RECT); % Converts rectangle given as [X0 Y0 W H] or [X0 Y0 W H THETA] into a % 4-by-2 array double, containing coordinate of rectangle vertices. % X0 and Y0 are the coordinates of the "lower left" vertex (before % applying rotation), W and H are the width and the height of the % rectangle, and THETA is the rotation angle around the first vertex, in % degrees. % % See also % orientedBoxToPolygon, ellipseToPolygon, drawRect, drawPolygon % % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-04-06 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract rectangle parameters theta = 0; x0 = rect(1); y0 = rect(2); w = rect(3); h = rect(4); if length(rect) > 4 theta = rect(5); end % precompute angular quantities cot = cosd(theta); sit = sind(theta); % compute vertex coordinates tx = zeros(4, 1); ty = zeros(4, 1); tx(1) = x0; ty(1) = y0; tx(2) = x0 + w * cot; ty(2) = y0 + w * sit; tx(3) = x0 + w * cot - h * sit; ty(3) = y0 + w * sit + h * cot; tx(4) = x0 - h * sit; ty(4) = y0 + h * cot; % format output if nargout <= 1 tx = [tx ty]; end matgeom-1.2.4/inst/geom2d/PaxHeaders/isParallel.m0000644000000000000000000000013214576357161016644 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.130193352 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isParallel.m0000644000175000017500000000617614576357161020436 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isParallel(v1, v2, varargin) %ISPARALLEL Check parallelism of two vectors. % % B = isParallel(V1, V2) % where V1 and V2 are two row vectors of length ND, ND being the % dimension, returns 1 if the vectors are parallel, and 0 otherwise. % % Also works when V1 and V2 are two N-by-ND arrays with same number of % rows. In this case, return a N-by-1 array containing 1 at the positions % of parallel vectors. % % Also works when one of V1 or V2 is N-by-1 and the other one is N-by-ND % array, in this case return N-by-1 results. % % B = isParallel(V1, V2, ACCURACY) % specifies the accuracy for numerical computation. Default value is % 1e-14. % % % Example % isParallel([1 2], [2 4]) % ans = % 1 % isParallel([1 2], [1 3]) % ans = % 0 % % See also % vectors2d, isPerpendicular, lines2d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-04-25 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % default accuracy acc = 1e-14; if ~isempty(varargin) acc = abs(varargin{1}); end % normalize vectors v1 = normalizeVector(v1); v2 = normalizeVector(v2); % adapt size of inputs if needed n1 = size(v1, 1); n2 = size(v2, 1); if n1 ~= n2 if n1 == 1 v1 = v1(ones(n2,1), :); elseif n2 == 1 v2 = v2(ones(n1,1), :); end end % performs computation if size(v1, 2) == 2 % computation for plane vectors b = abs(v1(:, 1) .* v2(:, 2) - v1(:, 2) .* v2(:, 1)) < acc; else % computation in greater dimensions b = vectorNorm(cross(v1, v2, 2)) < acc; end matgeom-1.2.4/inst/geom2d/PaxHeaders/vectorNorm.m0000644000000000000000000000013214576357161016712 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/vectorNorm.m0000644000175000017500000000562114576357161020476 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function n = vectorNorm(v, varargin) %VECTORNORM Compute norm of a vector, or of a set of vectors. % % N = vectorNorm(V); % Returns the euclidean norm of vector V. % % N = vectorNorm(V, N); % Specifies the norm to use. N can be any value greater than 0. % N=1 -> city lock norm % N=2 -> euclidean norm % N=inf -> compute max coord. % % When V is a MxN array, compute norm for each vector of the array. % Vector are given as rows. Result is then a [M*1] array. % % Example % n1 = vectorNorm([3 4]) % n1 = % 5 % % n2 = vectorNorm([1, 10], inf) % n2 = % 10 % % See also % vectors2d, vectorAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract the type of norm to compute d = 2; if ~isempty(varargin) d = varargin{1}; end if d==2 % euclidean norm: sum of squared coordinates, and take square root n = sqrt(sum(v.*v, ndims(v))); elseif d==1 % absolute norm: sum of absolute coordinates n = sum(abs(v), ndims(v)); elseif d==inf % infinite norm: uses the maximal corodinate n = max(v, [], ndims(v)); else % Other norms, use explicit but slower expression n = power(sum(power(v, d), ndims(v)), 1/d); end matgeom-1.2.4/inst/geom2d/PaxHeaders/isCounterClockwise.m0000644000000000000000000000013214576357161020373 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/isCounterClockwise.m0000644000175000017500000000745314576357161022164 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = isCounterClockwise(p1, p2, p3, varargin) %ISCOUNTERCLOCKWISE Compute the relative orientation of 3 points. % % CCW = isCounterClockwise(P1, P2, P3); % Computes the orientation of the 3 points. The returns is: % +1 if the path P1->P2->P3 turns Counter-Clockwise (i.e., the point P3 % is located "on the left" of the line P1-P2) % -1 if the path turns Clockwise (i.e., the point P3 lies "on the right" % of the line P1-P2) % 0 if the point P3 is located on the line segment [P1 P2]. % % This function can be used in more complicated algorithms: detection of % line segment intersections, convex hulls, point in triangle... % % CCW = isCounterClockwise(P1, P2, P3, EPS); % Specifies the threshold used for detecting colinearity of the 3 points. % Default value is 1e-12 (absolute). % % Example % isCounterClockwise([0 0], [10 0], [10 10]) % ans = % 1 % isCounterClockwise([0 0], [0 10], [10 10]) % ans = % -1 % isCounterClockwise([0 0], [10 0], [5 0]) % ans = % 0 % % See also % points2d, isPointOnLine, isPointInTriangle, polygonArea % % References % Algorithm adapated from Sedgewick's book. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-04-09 % Copyright 2010-2023 INRAE - Cepia Software Platform % get threshold value eps = 1e-12; if ~isempty(varargin) eps = varargin{1}; end % ensure all data have same size np = max([size(p1, 1) size(p2, 1) size(p3,1)]); if np > 1 if size(p1,1) == 1 p1 = repmat(p1, np, 1); end if size(p2,1) == 1 p2 = repmat(p2, np, 1); end if size(p3,1) == 1 p3 = repmat(p3, np, 1); end end % init with 0 res = zeros(np, 1); % extract vector coordinates x0 = p1(:, 1); y0 = p1(:, 2); dx1 = p2(:, 1) - x0; dy1 = p2(:, 2) - y0; dx2 = p3(:, 1) - x0; dy2 = p3(:, 2) - y0; % check non colinear cases res(dx1 .* dy2 > dy1 .* dx2) = 1; res(dx1 .* dy2 < dy1 .* dx2) = -1; % case of colinear points ind = abs(dx1 .* dy2 - dy1 .* dx2) < eps; res(ind( (dx1(ind) .* dx2(ind) < 0) | (dy1(ind) .* dy2(ind) < 0) )) = -1; res(ind( hypot(dx1(ind), dy1(ind)) < hypot(dx2(ind), dy2(ind)) )) = 1; matgeom-1.2.4/inst/geom2d/PaxHeaders/normalizeVector.m0000644000000000000000000000013214576357161017737 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/normalizeVector.m0000644000175000017500000000471414576357161021525 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vn = normalizeVector(v) %NORMALIZEVECTOR Normalize a vector to have norm equal to 1. % % V2 = normalizeVector(V); % Returns the normalization of vector V, such that ||V|| = 1. V can be % either a row or a column vector. % % When V is a M-by-N array, normalization is performed for each row of % the array. % % When V is a M-by-N-by-2 array, normalization is performed along the % last dimension of the array. % % Example: % vn = normalizeVector([3 4]) % vn = % 0.6000 0.8000 % vectorNorm(vn) % ans = % 1 % % See also % vectors2d, vectorNorm % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-11-29 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if ismatrix(v) vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); else vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, ndims(v)))); end matgeom-1.2.4/inst/geom2d/PaxHeaders/createEdge.m0000644000000000000000000000013214576357161016604 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/createEdge.m0000644000175000017500000001127014576357161020365 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edge = createEdge(varargin) %CREATEEDGE Create an edge between two points, or from a line. % % The internal format for edge representation is given by coordinates of % two points : [x1 y1 x2 y2]. % This function can serve as a line to edge converter. % % % E = createEdge(P1, P2); % Returns the edge between the two given points P1 and P2. % % E = createEdge(x0, y0, dx, dy); % Returns the edge going through point (x0, y0) and with direction % vector (dx,dy). % % E = createEdge(param); % where param is an array of 4 values, creates the edge going through the % point (param(1) param(2)), and with direction vector given by % (param(3) param(4)). % % E = createEdge(LINE, D); % create the edge contained in LINE, with same direction and start point, % but with length given by D. % % % Note: in all cases, parameters can be vertical arrays of the same % dimension. The result is then an array of edges, of dimensions N-by-4. % % % See also % edges2d, lines2d, drawEdge, clipEdge, createLine % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE if nargin == 1 % Only one input parameter. It can be : % - line angle % - array of four parameters % TODO : add control for arrays of lines. var = varargin{1}; if size(var, 2)==4 % 4 parameters of the line in a single array. %edge = var; edge = zeros(size(var)); edge(:, 1:2) = var(:,1:2); edge(:, 3:4) = edge(:, 1:2)+var(:,3:4); elseif size(var, 2)==1 % 1 parameter : angle of the line, going through origin. edge = [zeros(size(var,1)) zeros(size(var,1)) cos(var) sin(var)]; else error('wrong number of dimension for arg1 : can be 1 or 4'); end elseif nargin == 2 % 2 input parameters. They can be : % - 2 points, then 2 arrays of 1*2 double, % - a line, and a distance. % extract the two arguments v1 = varargin{1}; v2 = varargin{2}; if size(v1, 2) == 2 % first input parameter is first point, and second input is the % second point. %edge = [v1(:,1), v1(:,2), v2(:,1), v2(:,2)]; edge = [v1 v2]; else % first input parameter is a line, and second one a distance. angle = atan2(v1(:,4), v1(:,3)); edge = [v1(:,1), v1(:,2), v1(:,1)+v2.*cos(angle), v1(:,2)+v2.*sin(angle)]; end elseif nargin == 3 % 3 input parameters : % first one is a point belonging to the line, % second and third ones are direction vector of the line (dx and dy). p = varargin{1}; edge = [p(:,1) p(:,2) p(:,1)+varargin{2} p(:,2)+varargin{3}]; elseif nargin == 4 % 4 input parameters : % they are x0, y0 (point belonging to line) and dx, dy (direction % vector of the line). % All parameters should have the same size. edge = [varargin{1} varargin{2} varargin{1}+varargin{3} varargin{2}+varargin{4}]; else error('Wrong number of arguments in ''createEdge'' '); end matgeom-1.2.4/inst/geom2d/PaxHeaders/linePosition.m0000644000000000000000000000013214576357161017230 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/linePosition.m0000644000175000017500000001104114576357161021005 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function pos = linePosition(point, line, varargin) %LINEPOSITION Position of a point on a line. % % POS = linePosition(POINT, LINE); % Computes position of point POINT on the line LINE, relative to origin % point and direction vector of the line. % LINE has the form [x0 y0 dx dy], % POINT has the form [x y], and is assumed to belong to line. % % POS = linePosition(POINT, LINES); % If LINES is an array of NL lines, return NL positions, corresponding to % each line. % % POS = linePosition(POINTS, LINE); % If POINTS is an array of NP points, return NP positions, corresponding % to each point. % % POS = linePosition(POINTS, LINES); % If POINTS is an array of NP points and LINES is an array of NL lines, % return an array of [NP NL] position, corresponding to each couple % point-line. % % POS = linePosition(POINTS, LINES, 'diag'); % When POINTS and LINES have the same number of rows, computes positions % only for couples POINTS(i,:) and LINES(i,:). The result POS is a column % vector with as many rows as the number of points/lines. % % % Example % line = createLine([10 30], [30 90]); % linePosition([20 60], line) % ans = % .5 % % See also % lines2d, createLine, projPointOnLine, isPointOnLine % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-25 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % if diag is true, we need only to compute position of i-th point with i-th % line. diag = ~isempty(varargin) && ischar(varargin{1}) && strcmpi(varargin{1}, 'diag'); if diag % In the case of 'diag' option, use direct correspondence between % points and lines % check input have same size np = size(point, 1); nl = size(line, 1); if np ~= nl error('matGeom:linePosition', ... 'Using diag option, number of points and lines should be the same'); end % direction vector of the lines vx = line(:, 3); vy = line(:, 4); % difference of coordinates between point and line origins dx = point(:, 1) - line(:, 1); dy = point(:, 2) - line(:, 2); else % General case -> return NP-by-NL array % direction vector of the lines vx = line(:, 3)'; vy = line(:, 4)'; % difference of coordinates between point and line origins dx = bsxfun(@minus, point(:, 1), line(:, 1)'); dy = bsxfun(@minus, point(:, 2), line(:, 2)'); end % squared norm of direction vector, with a check of validity delta = vx .* vx + vy .* vy; invalidLine = delta < eps; delta(invalidLine) = 1; % compute position of points projected on the line, by using normalised dot % product (NP-by-NL array) pos = bsxfun(@rdivide, bsxfun(@times, dx, vx) + bsxfun(@times, dy, vy), delta); % ensure degenerated edges are correclty processed (consider the first % vertex is the closest one) if diag pos(invalidLine) = 0; else pos(:, invalidLine) = 0; end matgeom-1.2.4/inst/geom2d/PaxHeaders/drawShape.m0000644000000000000000000000013214576357161016472 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/geom2d/drawShape.m0000644000175000017500000000760114576357161020256 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawShape(varargin) %DRAWSHAPE Draw various types of shapes (circles, polygons...). % % drawShape(TYPE, PARAM) % Draw the shape of type TYPE, specified by given parameter PARAM. TYPE % can be one of {'circle', 'ellipse', 'rect', 'polygon', 'curve'} % PARAM depend on the type. For example, if TYPE is 'circle', PARAM will % contain [x0 y0 R]. % % Examples: % drawShape('circle', [20 10 30]); % Draw circle centered on [20 10] with radius 10. % drawShape('rect', [20 20 40 10 pi/3]); % Draw rectangle centered on [20 20] with length 40 and width 10, and % oriented pi/3 wrt axis Ox. % % % drawShape(..., OPTION) % also specifies drawing options. OPTION can be 'draw' (default) or % 'fill'. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-04-07 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % extract type and representation of shape type = varargin{1}; param = varargin{2}; varargin(1:2) = []; if ~iscell(type) type = {type}; end if ~iscell(param) tmp = cell(1, size(param, 1)); for i=1:size(param, 1) tmp{i} = param(i,:); end param = tmp; end % compute drawing options option = 'draw'; if ~isempty(varargin) var = varargin{1}; if strcmpi(var, 'fill') option = 'fill'; varargin(1) = []; elseif strcmpi(var, 'draw') option = 'draw'; varargin(1) = []; end end % transform each shape into a polygon shape = cell(1,length(type)); for i = 1:length(type) if strcmpi(type{i}, 'circle') shape{i} = circleToPolygon(param{i}, 128); elseif strcmpi(type{i}, 'rect') shape{i} = rectToPolygon(param{i}); elseif strcmpi(type{i}, 'polygon') shape{i} = param{i}; end end % draw or fill each shape as polygon hold on; h = zeros(length(shape), 1); if strcmp(option, 'draw') for i = 1:length(shape) h(i) = drawPolygon(ax, shape{i}, varargin{:}); end else for i = 1:length(shape) h(i) = fillPolygon(ax, shape{i}, varargin{:}); end end % format output if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/PaxHeaders/polygons2d0000644000000000000000000000013214576357160015243 xustar0030 mtime=1710874224.522193933 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/0000755000175000017500000000000014576357160017100 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonOuterNormal.m0000644000000000000000000000013214576357161021356 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonOuterNormal.m0000644000175000017500000000630214576357161023137 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vect = polygonOuterNormal(poly, iVertex) %POLYGONOUTERNORMAL Outer normal vector for a given vertex(ices). % % NV = polygonOuterNormal(POLY, VIND) % Where POLY is a polygon and VIND is the index of a vertex, returns the % outer normal vector of the specified vertex. % The normal is computed by averaging the tangent vectors of the two % neighbor edges, i.e. by computing a finite difference of the neighbor % vertices. % % NV = polygonOuterNormal(POLY) % Returns an array with as many vectors as the number of vertices of the % input polygon, containing the outer normal of each vertex. % % % Example % % compute outer normals to an ellipse % elli = [50 50 40 20 30]; % poly = ellipseToPolygon(elli, 200); % figure; hold on; % drawPolygon(poly, 'b'); axis equal; axis([0 100 10 90]); % inds = 1:10:200; pts = poly(inds, :); drawPoint(pts, 'bo') % vect = polygonOuterNormal(poly, inds); % drawVector(pts, vect*10, 'b'); % % See also % polygons2d, polygonPoint, polygonNormalAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-11-23, using Matlab 8.6.0.267246 (R2015b) % Copyright 2017-2023 INRA - Cepia Software Platform % number of vertices nv = size(poly, 1); % if indices not specified, compute for all vertices if nargin == 1 iVertex = 1:nv; end % allocate memory vect = zeros(length(iVertex), 2); % compute normal vector of each result vertex for i = 1:length(iVertex) iNext = mod(iVertex(i), nv) + 1; iPrev = mod(iVertex(i)-2, nv) + 1; tangent = (poly(iNext,:) - poly(iPrev,:)) / 2; vect(i,:) = [tangent(2) -tangent(1)]; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/intersectEdgePolygon.m0000644000000000000000000000013214576357161021634 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/intersectEdgePolygon.m0000644000175000017500000000617014576357161023420 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [intersects, inds] = intersectEdgePolygon(edge, poly, varargin) %INTERSECTEDGEPOLYGON Intersection point of an edge with a polygon. % % INTER = intersectEdgePolygon(EDGE, POLY) % Computes intersection(s) point(s) between the edge EDGE and the polygon % POLY. EDGE is given by [x1 y1 x2 y2]. POLY is a N-by-2 array of vertex % coordinates. % INTER is a M-by-2 array containing coordinates of intersection(s). It % can be empty if no intersection is found. % % [INTER, INDS] = intersectEdgePolygon(EDGE, POLY) % Also returns index/indices of edge(s) involved in intersections. % % Example % % Intersection of an edge with a square % poly = [0 0;10 0;10 10;0 10]; % edge = [9 2 9+3*1 2+3*2]; % exp = [10 4]; % inter = intersectEdgePolygon(edge, poly) % ans = % 10 4 % % See also % edges2d, polygons2d, intersectLinePolygon, intersectRayPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-24, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % get computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % get supporting line of edge line = edgeToLine(edge); % compute all intersections of supporting line with polygon [intersects, inds, pos] = intersectLinePolygon(line, poly, tol); % keep only intersection points located on the edge if ~isempty(intersects) keep = pos >= -tol & pos <= (1+tol); intersects = intersects(keep, :); inds = inds(keep); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/clipPolygon.m0000644000000000000000000000013214576357161017776 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/clipPolygon.m0000644000175000017500000000630314576357161021560 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = clipPolygon(polygon, w) %CLIPPOLYGON Clip a polygon with a rectangular box. % % POLY2 = clipPolygon(POLY, BOX); % POLY is N-by-2 array of points % BOX has the form: [XMIN XMAX YMIN YMAX]. % Returns the polygon created by the intersection of the polygon POLY and % the bounding box BOX. % % Note: Works only for convex polygons at the moment. % % See also % polygons2d, boxes2d, clipPolygonByLine, clipPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-14 % Copyright 2005-2023 INRA - Cepia Software Platform % check case of polygons stored in cell array if iscell(polygon) poly2 = cell(1, length(polygon)); for i = 1:length(polygon) poly2{i} = clipPolygon(polygon{i}, w); end return; end % check case of empty polygon N = size(polygon, 1); if N == 0 poly2 = zeros(0, 2); return end % create edges array of polygon edges = [polygon polygon([2:N 1], :)]; % clip edges edges = clipEdge(edges, w); % select non empty edges, and get their vertices ind = sum(abs(edges), 2) > 1e-14; pts = unique([edges(ind, 1:2); edges(ind, 3:4)], 'rows'); % add vertices of window corner corners = [w(1) w(3); w(1) w(4);w(2) w(3);w(2) w(4)]; ind = inpolygon(corners(:,1), corners(:,2), polygon(:,1), polygon(:,2)); pts = [pts; corners(ind, :)]; % polygon totally outside the window if size(pts, 1)==0 poly2 = pts; return; end % compute centroid of visible polygon pc = centroid(pts); % sort vertices around polygon angle = edgeAngle([repmat(pc, [size(pts, 1) 1]) pts]); [dummy, I] = sort(angle); %#ok % create resulting polygon poly2 = pts(I, :); matgeom-1.2.4/inst/polygons2d/PaxHeaders/clipPolygonByLine.m0000644000000000000000000000013214576357161021101 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/clipPolygonByLine.m0000644000175000017500000002110414576357161022657 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = clipPolygonByLine(poly, line, varargin) %CLIPPOLYGONBYLINE Clip a polygon by a directed line. % % POLY2 = clipPolygonByLine(POLY, LINE) % POLY is a [Nx2] array of points, and LINE is given as [x0 y0 dx dy]. % The result POLY2: % - Represents the part of the polygon on the left side of the directed % line, the left half-plane, if the line intersects the polygon. % - Is the same as POLY if the polygon is on the left side of the % directed line and the line does not intersect the polygon. % - Is an empty polygon [0x2] if the polygon on the right side of the % directed line and the line does not intersect the polygon. % % [POLY_L, POLY_R] = clipPolygonByLine(POLY, LINE, 'method', 'polyshape') % Uses MATLAB polyshape objects and functions to clip the polygon by the % line. Returns the right part POLY_R (right half-plane) in addition to % the left part POLY_L (left half-plane) in the polygon cell format. % % Example % line = [0.4 0 1 1]; % r = [2.5, 2, 1]; % poly = flipud(circleToPolygon([0 0 r(1)], round(2*pi*r(1)))); % poly2 = clipPolygonByLine(poly, line); % figure('color','w','numbertitle','off','name','Method: legland') % axis equal tight; hold on; xlabel('x'); ylabel('y') % fillPolygon(poly2) % poly2_centroid = polygonCentroid(poly2); % drawLabels(poly2_centroid,'L ','HorizontalAlignment','Right') % scatter(poly2_centroid(1), poly2_centroid(2),[],'k','filled') % midCircle = circleToPolygon([0 0 r(2)], round(2*pi*r(2))); % innerCircle = flipud(circleToPolygon([0 0 r(3)], round(2*pi*r(3)))); % poly = {poly, midCircle, innerCircle}; % clipPolygonByLine(poly, line, 'method','polyshape','debug',1); % % See also % clipPolygon % ------ % Author: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2005-07-31 % Copyright 2005-2023 INRA - Cepia Software Platform % Parsing p = inputParser; logParValidFunc=@(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addParameter(p,'method','legland',@(x) any(validatestring(x,{'legland','polyshape'}))); addParameter(p,'debugVisu',false,logParValidFunc); parse(p,varargin{:}); method = p.Results.method; debugVisu = p.Results.debugVisu; if iscell(poly) && numel(poly)==1 poly = poly{1}; elseif iscell(poly) && length(poly) > 1 method = 'polyshape'; end if ~iscell(poly) && any(isnan(poly(:))) poly = splitPolygons(poly); method = 'polyshape'; end switch method case 'legland' % avoid to process empty polygons if size(poly, 1)<3 varargout{1} = zeros([0 2]); return; end % ensure the last point is the same as the first one if sum(poly(end, :)==poly(1,:))~=2 poly = [poly; poly(1,:)]; end N = size(poly, 1); edges = [poly([N 1:N-1], :) poly]; b = isLeftOriented(poly, line); % case of totally clipped polygon if sum(b)==0 varargout{1} = zeros(0, 2); return; end poly2 = zeros(0, 2); i=1; while i<=N if isLeftOriented(poly(i,:), line) % keep all points located on the right side of line poly2 = [poly2; poly(i,:)]; %#ok else % compute of preceeding edge with line if i>1 poly2 = [poly2; intersectLineEdge(line, edges(i, :))]; %#ok end % go to the next point on the left side i=i+1; while i<=N % find the next point on the right side if isLeftOriented(poly(i,:), line) % add intersection of previous edge poly2 = [poly2; intersectLineEdge(line, edges(i, :))]; %#ok % add current point poly2 = [poly2; poly(i,:)]; %#ok % exit the second loop break; end i=i+1; end end i=i+1; end % remove last point if it is the same as the first one if sum(poly2(end, :)==poly(1,:))==2 poly2 = poly2(1:end-1, :); end if debugVisu figure('color','w','numbertitle','off', ... 'name', ['Debug Figure: ' mfilename ... '.m, Method: ' method]); axis equal tight; hold on; xlabel('x'); ylabel('y') fillPolygon(poly2,'g') poly2_centroid = polygonCentroid(poly2); drawLabels(poly2_centroid,'L ','HorizontalAlignment','Right') scatter(poly2_centroid(1), poly2_centroid(2),[],'k','filled') end varargout{1} = poly2; case 'polyshape' warning('off','MATLAB:polyshape:repairedBySimplify') polyShape = polygonToPolyshape(poly, 'debugVisu',0); warning('on','MATLAB:polyshape:repairedBySimplify') [bblim(1:2), bblim(3:4)] = boundingbox(polyShape); bbXdist = bblim(2)-bblim(1); bbYdist = bblim(4)-bblim(3); % Increase the bounding box a little bit bblim(1) = bblim(1)-0.01*bbXdist; bblim(2) = bblim(2)+0.01*bbXdist; bblim(3) = bblim(3)-0.01*bbYdist; bblim(4) = bblim(4)+0.01*bbYdist; % Bounding box BB = [bblim(1) bblim(3); bblim(2) bblim(3); ... bblim(2) bblim(4); bblim(1) bblim(4)]; % Clip the bounding box by the line BB_L = clipPolygonByLine(BB, line); PS_R = subtract(polyShape, polyshape(BB_L)); lineRev = [line(1:2) -line(3:4)]; BB_R = clipPolygonByLine(BB, lineRev); PS_L = subtract(polyShape, polyshape(BB_R)); lineSeg = clipLine(line, bblim); lineSeg = [lineSeg(1:2); lineSeg(3:4)]; % Intersection edges itsEdges = intersect(polyShape,lineSeg); itsEdges(2:end+1, 3:4) = itsEdges; itsEdges(1,3:4) = nan; itsEdges(end,1:2) = nan; itsEdges(any(isnan(itsEdges),2),:) = []; if debugVisu figure('color','w','numbertitle','off', ... 'name', ['Debug Figure: ' mfilename ... '.m, Method: ' method]); axis equal tight; hold on; xlabel('x'); ylabel('y') plot(PS_R,'FaceColor','g','EdgeColor','k') plot(PS_L,'FaceColor','b','EdgeColor','k') [PS_R_centroid(1), PS_R_centroid(2)] = centroid(PS_R); drawLabels(PS_R_centroid,' R','HorizontalAlignment','Left') scatter(PS_R_centroid(1), PS_R_centroid(2),[],'g','filled') [PS_L_centroid(1), PS_L_centroid(2)] = centroid(PS_L); drawLabels(PS_L_centroid,'L ','HorizontalAlignment','Right') scatter(PS_L_centroid(1), PS_L_centroid(2),[],'b','filled') drawEdge(itsEdges,'LineStyle','-','LineWidth',2,'Color','k') end varargout{1} = splitPolygons(PS_L.Vertices); varargout{2} = splitPolygons(PS_R.Vertices); varargout{3} = itsEdges; end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/pointSetsAverage.m0000644000000000000000000000013214576357161020762 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/pointSetsAverage.m0000644000175000017500000000551114576357161022544 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function average = pointSetsAverage(pointSets, varargin) %POINTSETSAVERAGE Compute the average of several point sets. % % AVERAGESET = pointSetsAverage(POINTSETS) % POINTSETS is a cell array containing several liste of points with the % same number of points. The function compute the average coordinate of % each vertex, and return the resulting average point set. % % Example % pointSetsAverage % % See also % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-04-01, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % check input if ~iscell(pointSets) error('First argument must be a cell array'); end % number of sets nSets = length(pointSets); % get reference size of coordinates array set1 = pointSets{1}; refSize = size(set1); % allocate memory for result average = zeros(refSize); % iterate on point sets for i = 1:nSets % get current point set, and check its size set = pointSets{i}; if sum(size(set) ~= refSize) > 0 error('All point sets must have the same size'); end % cumulative sum of coordinates average = average + set; end % normalize by the number of sets average = average / nSets; matgeom-1.2.4/inst/polygons2d/PaxHeaders/padPolyline.m0000644000000000000000000000013214576357161017757 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/padPolyline.m0000644000175000017500000000730714576357161021546 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = padPolyline(poly, M, varargin) %PADPOLYLINE Add vertices at each extremity of the polyline. % % POLY2 = padPolyline(POLY, M) % where M is a scalar, adds M vertices at the beginning and at the end of % the polyline. The number of vertices of the result polyline POLY2 is % equal to NV + 2*M. % % POLY2 = padPolyline(POLY, [M1 M2]) % Adds M1 vertices at the beginning of the polyline, and M2 at the end. % The number of vertices of the result polyline POLY2 is NV + M1 + M2. % % POLY2 = padPolyline(..., 'method', METHOD) % Specifies the padding method to use. METHOD can be one of {'symetric'} % (the default), or 'repeat'. % % Example % poly = circleArcToPolyline([50 50 30 30 80], 40); % poly2 = padPolyline(poly, 10, 'method', 'symetric'); % figure; hold on; axis equal; % drawPolyline(poly, 'color', 'b', 'linewidth', 2); % drawPolyline(poly2, 'color', 'm') % legend({'Initial', 'Padded'}, 'Location', 'SouthWest'); % % See also % polygons2d, smoothPolyline, polylineCurvature % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-03-31, using Matlab 9.12.0.1884302 (R2022a) % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Input argument management % default strategy method = 'symetric'; % padding before and after if isscalar(M) m1 = M; m2 = M; else m1 = M(1); m2 = M(2); end % other parameter name-value pairs while length(varargin) > 1 name = varargin{1}; if strcmpi(name, 'method') method = varargin{2}; else error('Unknown argument name: %s', name); end varargin(1:2) = []; end %% Main Processing % vertex number nv = size(poly,1); % switch processing depending on method if strcmp(method, 'repeat') poly2 = [... poly(ones(m1,1), :) ; ... poly ; poly(nv * ones(m2,1), :) ; ... ]; elseif strcmp(method, 'symetric') v1 = poly(1,:); vn = poly(end,:); poly2 = [... 2 * v1 - poly(m1+1:-1:2, :) ; ... poly ; 2 * vn - poly(nv-1:-1:nv-m2, :) ; ... ]; else error('Unknown method name: %s', method); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/findPoint.m0000644000000000000000000000013214576357161017431 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/findPoint.m0000644000175000017500000000636214576357161021220 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function index = findPoint(coord, points, varargin) %FINDPOINT Find index of a point in an set from its coordinates. % % IND = findPoint(POINT, ARRAY) % Returns the index of point whose coordinates match the 1-by-2 row array % POINT in the N-by-2 array ARRAY. If the point is not found, returns 0. % If several points are found, keep only the first one. % % If POINT is a M-by-2 array, the result is a M-by-1 array, containing % the index in the array of each point given by COORD, or 0 if the point % is not found. % % IND = findPoint(POINT, ARRAY, TOL) % use specified tolerance, to find point within a distance of TOL. % Default tolerance is zero. % % See also % points2d, minDistancePoints, distancePoints, findClosestPoint % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-07-17 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % number of points np = size(coord, 1); % allocate memory for result index = zeros(np, 1); % specify the tolerance tol = 0; if ~isempty(varargin) tol = varargin{1}; end if tol == 0 for i = 1:np % indices of matches ind = find(points(:,1) == coord(i,1) & points(:,2) == coord(i,2)); % format current result if isempty(ind) index(i) = 0; else index(i) = ind(1); end end else for i = 1:np % indices of matches ind = find(sqrt(sum(bsxfun(@minus, points, coord) .^ 2, 2)) <= tol); % format current result if isempty(ind) index(i) = 0; else index(i) = ind(1); end end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/resamplePolyline.m0000644000000000000000000000013214576357161021023 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/resamplePolyline.m0000644000175000017500000000646514576357161022616 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = resamplePolyline(poly, n) %RESAMPLEPOLYLINE Distribute N points equally spaced on a polyline. % % RES = resamplePolyline(POLY, N) % Resample the input polyline POLY such that the resulting polyline RES % has N points. All points of RES belong to the initial polyline, but are % not necessarily vertices. % % Example % poly = [0 10;0 0;20 0]; % figure; drawPolyline(poly, 'b'); % poly2 = resamplePolyline(poly, 10); % hold on; % drawPolyline(poly2, 'bo'); % axis equal; axis([-10 30 -10 20]); % % See also % polygons2d, drawPolyline, resamplePolygon, resamplePolylineByLength % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % parametrisation of the curve s = parametrize(poly); % distribute N points equally spaced Lmax = s(end); pos = linspace(0, Lmax, n); poly2 = zeros(n, size(poly, 2)); for i = 1:n % index of surrounding vertices before and after ind0 = find(s <= pos(i), 1, 'last'); ind1 = find(s >= pos(i), 1, 'first'); if ind0 == ind1 % get position of a vertex in input polyline poly2(i, :) = poly(ind0, :); continue; end % position of surrounding vertices pt0 = poly(ind0, :); pt1 = poly(ind1, :); % weights associated to each neighbor l0 = pos(i) - s(ind0); l1 = s(ind1) - pos(i); % linear interpolation of neighbor positions if (l0 + l1) > Lmax * 1e-12 poly2(i, :) = (pt0 * l1 + pt1 * l0) / (l0 + l1); else % if neighbors are too close, do not use interpolation poly2(i, :) = pt0; end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/reversePolygon.m0000644000000000000000000000013214576357161020522 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/reversePolygon.m0000644000175000017500000000416514576357161022310 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function rev = reversePolygon(poly) %REVERSEPOLYGON Reverse a polygon, by iterating vertices from the end. % % POLY2 = reversePolygon(POLY) % POLY2 has same vertices as POLY, but in different order. The first % vertex of the polygon is still the same. % % Example % reversePolygon % % See also % polygons2d, reversePolyline % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform rev = poly([1 end:-1:2], :); matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonSubcurve.m0000644000000000000000000000013214576357161020705 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonSubcurve.m0000644000175000017500000000701414576357161022467 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [res, inds] = polygonSubcurve(poly, t0, t1) %POLYGONSUBCURVE Extract a portion of a polygon. % % POLY2 = polygonSubcurve(POLYGON, POS0, POS1) % Create a new polyline, by keeping vertices located between positions % POS0 and POS1, and adding points corresponding to positions POS0 and % POS1 if they are not already vertices. % % [POLY2, INDS] = polygonSubcurve(POLYGON, POS0, POS1) % Also return indices of polygon vertices comprised between POS0 and % POS1. The array INDS may be smaller than the array POLY2. % % Example % Nv = 100; % poly = circleToPolygon([30 20 15], Nv); % arc1 = polygonSubcurve(poly, 15, 45); % arc2 = polygonSubcurve(poly, 90, 10); % contains polygon endpoints % figure; axis equal, hold on; axis([0 50 0 50]); % drawPolyline(arc1, 'linewidth', 4, 'color', 'g'); % drawPolyline(arc2, 'linewidth', 4, 'color', 'r'); % drawPolygon(poly, 'color', 'b'); % % See also % polygons2d, polylineSubcurve, projPointOnPolygon, polygonPoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRAE - Cepia Software Platform % number of vertices Nv = size(poly, 1); if t0 < t1 % format positions t0 = max(t0, 0); t1 = min(t1, Nv); end % indices of extreme vertices inside subcurve ind0 = ceil(t0)+1; ind1 = floor(t1)+1; % get the portion of polyline between 2 extremities if t0 < t1 % The result polyline does not contain the last vertex if ind1 <= Nv inds = ind0:ind1; else inds = 1; end else % polygon contains last vertex inds = [ind0:Nv 1:ind1]; end res = poly(inds, :); % add first point if it is not already a vertex if t0 ~= ind0-1 res = [polygonPoint(poly, t0); res]; end % add last point if it is not already a vertex if t1 ~= ind1-1 res = [res; polygonPoint(poly, t1)]; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polylineSubcurve.m0000644000000000000000000000013214576357161021051 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polylineSubcurve.m0000644000175000017500000000623514576357161022637 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [res, inds] = polylineSubcurve(poly, t0, t1) %POLYLINESUBCURVE Extract a portion of a polyline. % % POLY2 = polylineSubcurve(POLYLINE, POS0, POS1) % Create a new polyline, by keeping vertices located between positions % POS0 and POS1, and adding points corresponding to positions POS0 and % POS1 if they are not already vertices. % % [POLY2, INDS] = polylineSubcurve(POLYLINE, POS0, POS1) % Also returns the indices of the original polyline that were selected. % The size of the array INDS may be smaller than the array POLY, due to % the addition of new vertices at the extremities. % % Example % Nv = 100; % poly = circleAsPolygon([10 20 30], Nv); % poly2 = polylineSubcurve(poly, 15, 65); % drawCurve(poly2); % % See also % polygons2d, polygonSubCurve % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRAE - Cepia Software Platform % number of vertices Nv = size(poly, 1); if t0 < t1 % format positions t0 = max(t0, 0); t1 = min(t1, Nv-1); end % indices of extreme vertices inside subcurve ind0 = ceil(t0)+1; ind1 = floor(t1)+1; % get the portion of polyline between 2 extremities if t0 < t1 inds = ind0:ind1; else inds = [ind0:Nv 1:ind1]; end res = poly(inds, :); % add first point if it is not already a vertex if t0 ~= ind0-1 res = [polylinePoint(poly, t0); res]; end % add last point if it is not already a vertex if t1 ~= ind1-1 res = [res; polylinePoint(poly, t1)]; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/curveCMoment.m0000644000000000000000000000013214576357161020106 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/curveCMoment.m0000644000175000017500000000522214576357161021667 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function m = curveCMoment(curve, p, q) %CURVECMOMENT Compute centered inertia moment of a 2D curve. % M = curveCMoment(CURVE, P, Q) % % Example % curveCMoment % % See also % polygons2d, curveMoment, curveCSMoment % % Reference % Based on ideas and references in: % "Affine curve moment invariants for shape recognition" % Dongmin Zhao and Jie Chen % Pattern Recognition, 1997, vol. 30, pp. 865-901 % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-03-25, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % compute curve centroid centroid = polylineCentroid(curve); % coordinate of vertices px = curve(:,1)-centroid(1); py = curve(:,2)-centroid(2); % compute centroids of line segments cx = (px(1:end-1)+px(2:end))/2; cy = (py(1:end-1)+py(2:end))/2; % compute length of each line segment dl = hypot(px(2:end)-px(1:end-1), py(2:end)-py(1:end-1)); % compute moment m = zeros(size(p)); for i=1:length(p(:)) m(i) = sum(cx(:).^p(i) .* cy(:).^q(i) .* dl(:)); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/distancePointPolyline.m0000644000000000000000000000013214576357161022017 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/distancePointPolyline.m0000644000175000017500000001014614576357161023601 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [minDist, pos] = distancePointPolyline(point, poly, varargin) %DISTANCEPOINTPOLYLINE Compute shortest distance between a point and a polyline. % % DIST = distancePointPolyline(POINT, POLYLINE) % Returns the shortest distance between a point given as a 1-by-2 row % vector, and a polyline given as a NV-by-2 array of coordinates. % % If POINT is a NP-by-2 array, the result DIST is a NP-by-1 array, % containig the distance of each point to the polyline. % % [DIST, POS] = distancePointPolyline(POINT, POLYLINE) % Also returns the relative position of the point projected on the % polyline, between 0 and NV, the number of polyline vertices. % % ... = distancePointPolyline(POINT, POLYLINE, CLOSED) % Specifies if the polyline is closed or not. CLOSED can be one of: % * 'closed' -> the polyline is closed % * 'open' -> the polyline is open % a column vector of logical with the same number of elements as the % number of points -> specify individually if each polyline is % closed (true=closed). % % % Example: % pt1 = [30 20]; % pt2 = [30 5]; % poly = [10 10;50 10;50 50;10 50]; % distancePointPolyline([pt1;pt2], poly) % ans = % 10 % 5 % % See also % polygons2d, points2d % distancePointEdge, distancePointPolygon, projPointOnPolyline % % ------ % Author: David Legland, Juan Pablo Carbajal % E-mail: david.legland@inrae.fr, ajuanpi+dev@gmail.com % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % check if input polyline is closed or not closed = false; if ~isempty(varargin) c = varargin{1}; if strcmp('closed', c) closed = true; elseif strcmp('open', c) closed = false; elseif islogical(c) closed = c; end end % closes the polyline if necessary if closed poly = [poly; poly(1,:)]; end % number of points Np = size(point, 1); % construct the set of edges edges = [poly(1:end-1, :) poly(2:end, :)]; % compute distance between current each point and all edges, and also % returns the position of projection on corresponding edge, between 0 and 1 [dist, edgePos] = distancePointEdge(point, edges); % get the minimum distance, and index of edge providing minimum distance [minDist, edgeIndex] = min(dist, [], 2); % if required, compute projections pos = []; if nargout == 2 Ne = size(edgePos, 2); j = sub2ind([Np, Ne], (1:Np)', edgeIndex); pos = edgeIndex - 1 + edgePos(j); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonSymmetryAxis.m0000644000000000000000000000013214576357161021565 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonSymmetryAxis.m0000644000175000017500000000654714576357161023361 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function axis = polygonSymmetryAxis(poly) %POLYGONSYMMETRYAXIS Try to identify symmetry axis of polygon. % % LINE = polygonSymmetryAxis(POLY) % Returns a line that minimize difference between the polygon POLY and % its reflection with the line. % The difference metric between the two polygons is the sum of distances % between each vertex of original polygon to the reflected polygon. % % Example % % identify symmetry axis of an ellipse % elli = [50 50 40 20 30]; % poly = ellipseToPolygon(elli, 100); % line = polygonSymmetryAxis(poly); % figure; hold on; % drawEllipse(elli); % axis equal; axis ([0 100 0 100]); % drawLine(line); % % See also % transforms2d, transformPoint, distancePointPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-04-28, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform % start by centering the polygon center = polygonCentroid(poly); poly = bsxfun(@minus, poly, center); % first performs a rough search with 8 angles initAngles = linspace(0, pi, 9); initAngles(end) = []; initRes = zeros(8, 1); for i = 1:8 line = createLine([0 0 cos(initAngles(i)) sin(initAngles(i))]); rotMat = createLineReflection(line); polyRot = transformPoint(poly, rotMat); initRes(i) = sum(distancePointPolygon(poly, polyRot).^2); end % keep the angle that gives best result [dummy, indMin] = min(initRes); %#ok initAngle = initAngles(indMin); % Compute angle that best fit between polygon and its symmetric along line thetaMin = fminbnd(... @(theta) sum(distancePointPolygon(transformPoint(poly, createLineReflection([0 0 cos(theta) sin(theta)])), poly).^2), ... initAngle-pi/4, initAngle+pi/4); % format as a line axis = [center cos(thetaMin) sin(thetaMin)]; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polylineCurvature.m0000644000000000000000000000013214576357161021233 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polylineCurvature.m0000644000175000017500000000745614576357161023027 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function curv = polylineCurvature(poly, M) %POLYLINECURVATURE Estimate curvature on polyline vertices using polynomial fit. % % CURV = polygonCurvature(POLY, M) % Estimate the curvature for each vertex of a polygon, using polynomial % fit from the M vertices located around current vertex. M is usually an % odd value, resulting in a symmetric neighborhood. % % Polynomial fitting is of degree 2. % % % Example % % compute curvature on a curve obtained from skeleton image % img = imread('circles.png'); % img = imfill(img, 'holes'); % imgf = imfilter(double(img), fspecial('gaussian', 7, 2)); % figure(1), imshow(imgf); % % compute skeleton, and simplify to get a smooth polyline % skel = imSkeleton(imgf > 0.5); % path = imMaxGeodesicPath(skel); % poly = smoothPolyline(path, 15); % hold on; drawPolyline(poly, 'm'); % % compute curvature % curv = polylineCurvature(poly, 11); % figure; plot(curv); % minima = bwlabel(imextendedmin(curv, .05)); % centroids = imCentroid(minima); % inds = round(centroids(:,2)); % figure(1); hold on; drawPoint(poly2(inds, :), 'g*') % % See also % polygons2d, polygonCurvature, padPolyline % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-04-01, using Matlab 9.3.0.713579 (R2017b) % Copyright 2022-2023 INRA - Cepia Software Platform % number of vertices of polyline n = size(poly, 1); % allocate memory for result curv = zeros(n, 1); % number of vertices before and after current vertex m1 = floor((M - 1) / 2); m2 = ceil((M - 1) / 2); % parametrisation basis % As we recenter the points, the constant factor is omitted ti = (-m1:m2)'; X = [ti ti.^2]; % Iteration on vertex indices for i = m1+1:n-m2 % coordinate of current vertex, for recentring neighbor vertices x0 = poly(i,1); y0 = poly(i,2); % indices of neighbors inds = i-m1:i+m2; inds = mod(inds-1, n) + 1; % Least square estimation using mrdivide xc = X \ (poly(inds,1) - x0); yc = X \ (poly(inds,2) - y0); % compute curvature curv(i) = 2 * (xc(1)*yc(2) - xc(2)*yc(1) ) / power(xc(1)^2 + yc(1)^2, 3/2); end % duplicate curvature at extremities curv(1:m1) = curv(m1+1); curv(n-m2+1:n) = curv(n-m2); matgeom-1.2.4/inst/polygons2d/PaxHeaders/triangulatePolygon.m0000644000000000000000000000013214576357161021366 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/triangulatePolygon.m0000644000175000017500000000740114576357161023150 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function tri = triangulatePolygon(poly) %TRIANGULATEPOLYGON Computes a triangulation of the input polygon. % % TRI = triangulatePolygon(POLY) % Computes a triangulation TRI of the polygon defined by POLY % POLY contains the polygon vertices, as a Nv-by-2 array of double. % TRI is a Nt-by-3 array containing indices of vertices forming the % triangles. % % Example % % creates a simple polygon and computes its Delaunay triangulation % poly = [0 0 ; 10 0;5 10;15 15;5 20;-5 10]; % figure;drawPolygon(poly); axis equal % tri = triangulatePolygon(poly); % figure; % % patch('Faces', tri, 'Vertices', poly, 'facecolor', 'c'); % drawMesh(poly, tri, 'facecolor', 'c'); % axis equal % % % Another example for which constrains were necessary % poly2 = [10 10;80 10; 140 20;30 20; 80 30; 140 30; 120 40;10 40]; % tri2 = triangulatePolygon(poly2); % figure; drawMesh(poly2, tri2); % hold on, drawPolygon(poly2, 'linewidth', 2); % axis equal % axis([0 150 0 50]) % % See also % delaunayTriangulation, drawMesh, patch % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-11-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % compute constraints nv = size(poly, 1); cons = [(1:nv)' [2:nv 1]']; if verLessThan('matlab', '8.1') % Code for versions before R2013a % delaunay triangulation dt = DelaunayTri(poly(:,1), poly(:, 2), cons); %#ok % find which triangles are contained in polygon centers = incenters(dt); inds = isPointInPolygon(centers, poly); % keep selected triangles tri = dt.Triangulation(inds, :); else % Code for versions R2013a and later % delaunay triangulation % dt = DelaunayTri(poly(:,1), poly(:, 2), cons); dt = delaunayTriangulation(poly(:,1), poly(:, 2), cons); % find which triangles are contained in polygon % centers = incenters(dt); centers = incenter(dt); inds = isPointInPolygon(centers, poly); % keep selected triangles % tri = dt.Triangulation(inds, :); tri = dt.ConnectivityList(inds, :); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/drawVertices.m0000644000000000000000000000013214576357161020141 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/drawVertices.m0000644000175000017500000000760114576357161021725 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawVertices(varargin) %DRAWVERTICES Draw the vertices of a polygon or polyline. % % drawVertices(POLY) % Draws the vertices of the given polygon, using pre-defined style. % Default is to draw vertices as squares, with the first vertex filled. % % Example % poly = circleToPolygon([20 30 40], 16); % drawPolygon(poly); % hold on; axis equal; % drawVertices(poly); % % See also % drawPoint, drawPolygon, drawPolyline % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-11, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end var = varargin{1}; %% Manage cell arrays of polygons / polylines % case of a set of polygons stored in a cell array if iscell(var) N = length(var); h = zeros(N, 1); for i = 1:N state = ishold(gca); hold on; % check for empty polygons if ~isempty(var{i}) h(i) = drawVertices(ax, var{i}, varargin{2:end}); end if ~state hold off end end if nargout > 0 varargout = {h}; end return; end %% Parse coordinates and options % Extract coordinates of vertices if size(var, 2) > 1 % first argument is a vertex array px = var(:, 1); py = var(:, 2); varargin(1) = []; elseif length(varargin) >= 2 && isnumeric(varargin{1}) && isnumeric(varargin{2}) % arguments 1 and 2 correspond to x and y coordinate respectively px = varargin{1}; py = varargin{2}; varargin(1:2) = []; else % unknow input format error('Should specify either a N-by-2 array, or 2 N-by-1 vectors'); end % concatenate input argument(s) with default options defaults = {'MarkerSize', 6}; if length(varargin) == 1 varargin = [varargin defaults]; else varargin = [{'ks'} defaults varargin]; end %% Draw the vertices % draw the vertices h = plot(ax, px, py, varargin{:}); % draw the first vertex with a different style plot(ax, px(1), py(1), 'ks', 'MarkerFaceColor', 'k', 'MarkerSize', 8); % format output arg if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/intersectLinePolyline.m0000644000000000000000000000013214576357161022023 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/intersectLinePolyline.m0000644000175000017500000001126014576357161023603 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [intersects, edgeIndices] = intersectLinePolyline(line, poly, varargin) %INTERSECTLINEPOLYLINE Intersection points between a line and a polyline. % % P = intersectLinePolyline(LINE, POLY) % Returns the intersection points of the lines LINE with polyline POLY. % LINE is a 1-by-4 row vector containing parametric representation of the % line (in the format [x0 y0 dx dy], see the function 'createLine' for % details). % POLY is a NV-by-2 array containing coordinates of the polyline vertices % P is a K-by-2 array containing the coordinates of the K intersection % points. % % P = intersectLinePolyline(LINE, POLY, TOL) % Specifies the tolerance for geometric tests. Default is 1e-14. % % [P INDS] = intersectLinePolyline(...) % Also returns the indices of edges involved in intersections. INDS is a % K-by-1 column vector, such that P(i,:) corresponds to intersection of % the line with the i-th edge of the polyline. If the intersection occurs % at a polyline vertex, the index of only one of the two neighbor edges % is returned. % Note that due to numerical approximations, the use of function % 'isPointOnEdge' may give results not consistent with this function. % % % Examples % % compute intersections between a square and an horizontal line % poly = [0 0;10 0;10 10;0 10]; % line = [5 5 1 0]; % intersectLinePolyline(line, poly) % ans = % 10 5 % % also return indices of edges % [inters inds] = intersectLinePolyline(line, poly) % inters = % 10 5 % inds = % 2 % % % compute intersections between a square and a diagonal line % poly = [0 0;10 0;10 10;0 10]; % line = [5 5 1 1]; % intersectLinePolyline(line, poly) % ans = % 0 0 % 10 10 % % See also % lines2d, polylines2d, intersectLines, intersectLinePolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % get computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % create the array of edges N = size(poly, 1); edges = [poly(1:N-1, :) poly(2:N, :)]; % compute intersections with supporting lines of polyline edges supportLines = edgeToLine(edges); intersects = intersectLines(line, supportLines, tol); % find edges that are not parallel to the input line inds = find(isfinite(intersects(:, 1))); % compute position of intersection points on corresponding lines pos = linePosition(intersects(inds, :), supportLines(inds, :), 'diag'); % and keep only intersection points located on edges b = pos > -tol & pos < 1+tol; inds = inds(b); intersects = intersects(inds, :); % remove multiple vertices (can occur for intersections located at polyline % vertices) [intersects, I, J] = unique(intersects, 'rows'); %#ok if nargout > 1 % return indices of edges involved in intersection % (in case of intersection located at a vertex, only one of the % neighbor edges is returned) edgeIndices = inds(I); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/distancePolygonsNoCross.m0000644000000000000000000000013214576357161022333 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/distancePolygonsNoCross.m0000644000175000017500000000550614576357161024121 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dist = distancePolygonsNoCross(poly1, poly2) %DISTANCEPOLYGONSNOCROSS Compute the shortest distance between 2 polygons. % % DIST = distancePolygonsNoCross(POLY1, POLY2) % Computes the shortest distance between the boundaries of the two % polygons, assuming they do not cross. % Each polygon is given by a N-by-2 array containing the vertex % coordinates. % % If the polygons may cross, it is necessary to use the % 'distancePolygons' function, that adds a potentially costly test on the % intersection. % % Example % % Computes the distance between a square and a triangle % poly1 = [10 10;20 10;20 20;10 20]; % poly2 = [30 20;50 20;40 45]; % distancePolygons(poly1, poly2) % ans = % 10 % % See also % polygons2d, distancePolygons, distancePolylines, distancePointPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-17, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % compute distance of each vertex of a polygon to the other polygon dist1 = min(distancePointPolygon(poly1, poly2)); dist2 = min(distancePointPolygon(poly2, poly1)); % keep the minimum of the two distances dist = min(dist1, dist2); matgeom-1.2.4/inst/polygons2d/PaxHeaders/parsePolygon.m0000644000000000000000000000013214576357161020161 xustar0030 mtime=1710874225.134193349 30 atime=1710874225.134193349 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/parsePolygon.m0000644000175000017500000001165614576357161021752 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [polyOut, inputFormat] = parsePolygon(poly, format, varargin) %PARSEPOLYGON Conversion between different polygon formats. % % POLYOUT = parsePolygon(POLY, FORMAT) % Converts POLY to the specified format while FORMAT must be one of the % following options: 'cell','nan','repetition','polyshape'. Mainly used % in other polygon functions to bring the polygon into the required % format. % % Example % r = [2.5, 2, 1]; % poly = flipud(circleToPolygon([0 0 r(1)], round(2*pi*r(1)))); % midCircle = circleToPolygon([0 0 r(2)], round(2*pi*r(2))); % innerCircle = flipud(circleToPolygon([0 0 r(3)], round(2*pi*r(3)))); % poly = {poly, midCircle, innerCircle}; % polyOut = parsePolygon(poly, 'repetition'); % polyOut = parsePolygon(polyOut, 'nan'); % polyOut = parsePolygon(polyOut, 'polyshape'); % polyOut = parsePolygon(polyOut, 'cell'); % assert(isequal(poly, polyOut)) % % See also % polygonToPolyshape % % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-01-01, using MATLAB 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 % Parsing p = inputParser; addRequired(p,'format',... @(x) any(validatestring(x,{'cell','nan','repetition','polyshape'}))); parse(p,format,varargin{:}); format = p.Results.format; % If polygon is a polyshape object if isa(poly,'polyshape') polyOut = parsePolygon(poly.Vertices, format); inputFormat = 'polyshape'; return end % If polygon is a cell if iscell(poly) [r, c] = size(poly); if r > 1 && c > 1 error(['Non-supported polygon cell format with ' num2str(r) ' rows and ' num2str(c) 'columns!']) elseif r > 1 && c == 1 polyCell = poly'; elseif r == 1 && c > 1 polyCell = poly; elseif r == 1 && c == 1 polyCell = poly; end if any(cellfun(@(x) any(isnan(x(:))), poly)) error('Non-supported polygon cell format. Polygons in cell format should not contain NaN values!') end inputFormat = 'cell'; end if ~iscell(poly) && any(isnan(poly(:))) % If polygon contains nan polyCell = splitPolygons(poly)'; inputFormat = 'nan'; elseif ~iscell(poly) % If polygon contains vertex repetitions polyBackup = poly; polyCell = {}; count = 0; while ~isempty(poly) count = count+1; repLIdx = ismember(poly, poly(1,:), 'rows'); repIdx = find(repLIdx); if sum(repLIdx) == 1 polyCell = {poly}; if count == 1 break else warning('Contains vertex repetitions but the last vertex is not a repetiton!') polyCell = {polyBackup}; end elseif sum(repLIdx)>1 polyCell = [polyCell, {poly(1:repIdx(2)-1,:)}]; %#ok poly(1:repIdx(2),:) = []; end end inputFormat = 'repetition'; end % Convert to output format switch format case 'cell' polyOut = polyCell; case 'nan' polyOut = cell2mat((cellfun(@(x) [x; nan(1, size(x,2))], polyCell, 'UniformOutput',false))'); polyOut(end,:) = []; case 'repetition' polyOut = cell2mat((cellfun(@(x) [x; x(1,:)], polyCell, 'UniformOutput',false))'); case 'polyshape' polyOut = polyshape(polyCell{1}); NoP = length(polyCell); if NoP > 1 for p=2:NoP polyOut = addboundary(polyOut, polyCell{p}); end end end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/isPointOnPolyline.m0000644000000000000000000000013214576357161021135 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/isPointOnPolyline.m0000644000175000017500000000512214576357161022715 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = isPointOnPolyline(point, poly, varargin) %ISPOINTONPOLYLINE Test if a point belongs to a polyline. % % B = isPointOnPolyline(POINT, POLY) % Returns TRUE of the point POINT belong to the polyline defined by the % set of points in POLY. % % B = isPointOnPolyline(POINT, POLY, TOL) % Specify the absolute tolerance for testing the distance between the % point and the polyline. % % Example % pt1 = [30 20]; % pt2 = [30 10]; % poly = [10 10;50 10;50 50;10 50]; % isPointOnPolyline([pt1;pt2], poly) % ans = % 0 % 1 % % See also % points2d, polygons2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-19, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end % return true if distance is below a given threshold res = distancePointPolyline(point, poly) < tol; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonVertices.m0000644000000000000000000000013214576357161020673 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonVertices.m0000644000175000017500000000700314576357161022453 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vertices = polygonVertices(poly) %POLYGONVERTICES Extract all vertices of a (multi-)polygon. % % VERTS = polygonVertices(POLY) % Returns the set of verttices from the polygon POLY. POLY can be either: % * a N-by-2 array of vertices. In that case, POLY and VERTS are the % same. % * a N-by-2 array of vertices with pairs of NaN values separating two % rings of the polygon. In that case, the array VERTS corresponds to % the vertices of the polygon, without copying the NaN values. % * a cell array of loops. In that case, the functions recursively % process the polygons and populated the vertex array. % % % Example % % create a polygon with a hole, using NaN for separating rings % ring1 = [0 0 ; 50 0;50 50;0 50]; % ring2 = [20 20;20 30;30 30;30 20]; % poly = [ring1 ; NaN NaN ; ring2]; % figure; drawPolygon(poly, 'b'); % axis([-10 60 -10 60]); axis equal; hold on; % verts = polygonVertices(poly); % drawPoint(verts, 'bo'); % % % create a polygon with a hole, storing rings in cell array % ring1 = [0 0 ; 50 0;50 50;0 50]; % ring2 = [20 20;20 30;30 30;30 20]; % poly = {ring1, ring2}; % figure; drawPolygon(poly, 'b'); % axis([-10 60 -10 60]); axis equal; hold on; % verts = polygonVertices(poly); % drawPoint(verts, 'bo'); % % See also % polygons2d, polygonEdges % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-06-07, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018-2023 INRA - Cepia Software Platform if isnumeric(poly) % find NaN or infinite values inds = sum(isfinite(poly), 2) == 2; % filter non-finite vertices if necessary if any(~inds) vertices = poly(inds, :); else vertices = poly; end elseif iscell(poly) % process cell array vertices = zeros(0, 2); for i = 1:length(poly) vertices = [vertices ; polygonVertices(poly{i})]; %#ok end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonCentroid.m0000644000000000000000000000013214576357161020656 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonCentroid.m0000644000175000017500000000615414576357161022444 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [centroid, area, Sx, Sy] = polygonCentroid(varargin) %POLYGONCENTROID Computes the centroid (center of mass) of a polygon. % % CENTROID = polygonCentroid(POLY) % CENTROID = polygonCentroid(PTX, PTY) % Computes center of mass of a polygon defined by POLY. POLY is a N-by-2 % array of double containing coordinates of vertices. % % [CENTROID, AREA] = polygonCentroid(POLY) % Also returns the (signed) area of the polygon. % % Example % % Draws the centroid of a paper hen % x = [0 10 20 0 -10 -20 -10 -10 0]; % y = [0 0 10 10 20 10 10 0 -10]; % poly = [x' y']; % centro = polygonCentroid(poly); % drawPolygon(poly); % hold on; axis equal; % drawPoint(centro, 'bo'); % % References % Algorithm adapted from P. Bourke's web page. % % See also % polygons2d, polygonArea, polygonSecondAreaMoments, drawPolygon % polylineCentroid, centroid % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-05 % Copyright 2004-2023 % parse input arguments if nargin == 1 poly = varargin{1}; elseif nargin == 2 poly(:,1) = varargin{1}; poly(:,2) = varargin{2}; end poly = parsePolygon(poly, 'repetition'); px = poly(:,1); py = poly(:,2); % vertex indices N = length(px); iNext = [2:N 1]; % compute cross products common = px .* py(iNext) - px(iNext) .* py; Sx = 1/6*sum((py + py(iNext)) .* common); Sy = 1/6*sum((px + px(iNext)) .* common); % area and centroid area = sum(common) / 2; centroid = [Sy Sx] / area; matgeom-1.2.4/inst/polygons2d/PaxHeaders/parametrize.m0000644000000000000000000000013214576357161020022 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/parametrize.m0000644000175000017500000000734514576357161021613 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function par = parametrize(varargin) %PARAMETRIZE Parametrization of a polyline, based on edges lengths. % % PAR = parametrize(POLY); % Returns a parametrization of the curve defined by the serie of points, % based on euclidean distance between two consecutive points. % POLY is a N-by-2 array, representing coordinates of vertices. The % result PAR is N-by-1, and contains the cumulative length of edges until % corresponding vertex. % % PAR = parametrize(PX, PY); % is the same, but specify points coordinates in separate column vectors. % % PAR = parametrize(..., 'normalize', 1); % PAR = parametrize(..., 'normalize', true); % Rescales the result such that the last element of PAR is 1. % % Example % % Parametrize a circle approximation % poly = circleToPolygon([0 0 1], 200); % p = parametrize(poly); % p(end) % ans = % 6.2829 % % See also % polygons2d, polylineLength % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-04-06 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% Process inputs % extract vertex coordinates if size(varargin{1}, 2) > 1 % vertices in a single array pts = varargin{1}; varargin(1) = []; elseif length(varargin) == 2 % points as separate arrays pts = [varargin{1} varargin{2}]; varargin(1:2) = []; end % by default, do not normalize normalize = false; % extract options while length(varargin) > 1 param = varargin{1}; switch lower(param) case 'normalize' normalize = varargin{2}; otherwise error('Unknown parameter name: %s', param); end varargin(1:2) = []; end %% Parametrize polyline % compute cumulative sum of euclidean distances between consecutive % vertices, setting distance of first vertex to 0. if size(pts, 2) == 2 % process points in 2D par = [0 ; cumsum(hypot(diff(pts(:,1)), diff(pts(:,2))))]; else % process points in arbitrary dimension par = [0 ; cumsum(sqrt(sum(diff(pts).^2, 2)))]; end % eventually rescale between 0 and 1 if normalize par = par / par(end); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/distancePointPolygon.m0000644000000000000000000000013214576357161021653 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/distancePointPolygon.m0000644000175000017500000000533214576357161023436 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function minDist = distancePointPolygon(point, poly) %DISTANCEPOINTPOLYGON Shortest distance between a point and a polygon. % % DIST = distancePointPolygon(POINT, POLYGON) % Computes the shortest distance between the point POINT and the polygon % given by POLYGON. POINT is a 1-by-2 row vector, and POLYGON is a N-by-2 % array containing vertex coordinates. % The distance is computed as the minimal distance to the boundary edges. % % Example % % Computes the distance between a point and a square % square = [0 0; 10 0;10 10;0 10]; % p0 = [16 3]; % distancePointPolygon(p0, square) % ans = % 6 % % See also % polygons2d, points2d, distancePointPolyline, distancePointEdge, % projPointOnPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % eventually copy first point at the end to ensure closed polygon if sum(poly(end, :) == poly(1,:)) ~= 2 poly = [poly; poly(1,:)]; end % call to distancePointPolyline minDist = distancePointPolyline(point, poly); matgeom-1.2.4/inst/polygons2d/PaxHeaders/geod2cart.m0000644000000000000000000000013214576357161017351 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/geod2cart.m0000644000175000017500000000517314576357161021137 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = geod2cart(src, curve, normal) %GEOD2CART Convert geodesic coordinates to cartesian coord. % % PT2 = geod2cart(PT1, CURVE, NORMAL) % CURVE and NORMAL are both [N*2] array with the same length, and % represent positions of the curve, and normal to each point. % PT1 is the point to transform, in geodesic coordinate (first coord is % distance from the curve start, and second coord is distance between % point and curve). % % The function return the coordinate of PT1 in the same coordinate system % than for the curve. % % See also % polylines2d, cart2geod, curveLength % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-08 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE t = parametrize(curve); N = size(src, 1); ind = zeros(N, 1); for i = 1:N indices = find(t >= src(i,1)); if ~isempty(indices) ind(i) = indices(1); else ind(i) = 1; end end theta = lineAngle([zeros(N,2) normal(ind,:)]); d = src(:,2); point = [curve(ind,1)+d.*cos(theta), curve(ind,2)+d.*sin(theta)]; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonToPolyshape.m0000644000000000000000000000013214576357161021356 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonToPolyshape.m0000644000175000017500000000514314576357161023141 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polyShape = polygonToPolyshape(poly, varargin) %POLYGONTOPOLYSHAPE Convert a matGeom polygon to a MATLAB polyshape object. % % POLYSHAPE = polygonToPolyshape(POLY) % % Example % poly = [0 0; 1 0; 1 1; 0 1]; % polyShape = polygonToPolyshape(poly); % figure('color','w') % axis equal tight; hold on; xlabel('x'); ylabel('y') % plot(polyShape) % % See also % rowToPolygon % ------ % Author: oqilipo % E-mail: N/A % Created: 2022-12-31, using MATLAB 9.13.0.2080170 (R2022b) Update 1 % Copyright 2022-2023 parser = inputParser; logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addParameter(parser,'debugVisualization', false, logParValidFunc); parse(parser, varargin{:}); debugVisu = parser.Results.debugVisualization; polyShape = parsePolygon(poly, 'polyshape'); if debugVisu figure('color','w','numbertitle','off', ... 'name', ['Debug Figure: ' mfilename ... '.m: MATLAB polyshape object']); axis equal tight; hold on; xlabel('x'); ylabel('y') plot(polyShape) end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonNormalAngle.m0000644000000000000000000000013214576357161021306 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonNormalAngle.m0000644000175000017500000000663014576357161023073 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = polygonNormalAngle(poly, inds) %POLYGONNORMALANGLE Normal angle at each vertex of a polygon. % % THETA = polygonNormalAngle(POLY); % where POLY is a N-by-2 array representing vertex coordinates, computes % the normal angle at each vertex of the polygon. THETA is a N-by-1 array % containing numeric values between -PI and +PI. The result depends on % the orientation of the polygon (counter-clockwise or clockwise). % % THETA = polygonNormalAngle(POLY, IND); % Computes the normal angle for each vertex specified by IND. If IND is a % vector of vertex indices. % % % Example % % Normal angles at vertices of an isosceles right triangle are pi/2 at % % right angle-vertex and 3*pi/4 for the two remaining vertices. % poly = [0 0 ; 1 0 ; 0 1]; % polygonNormalAngle(poly) % ans = % 1.5708 % 2.3562 % 2.3562 % % % Compute normal angles for a slightly more complicated polygon % poly = [0 0;0 1;-1 1;0 -1;1 0]; % % compute normal angle at each vertex % theta = polygonNormalAngle(poly); % % sum of all normal angle of a non-intersecting polygon equals 2*pi % % (can be -2*pi if polygon is oriented clockwise) % sum(theta) % ans = % 6.2832 % % See also % polygons2d, polygonOuterNormal, normalizeAngle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-30 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % number of polygon vertices np = size(poly, 1); if nargin == 1 inds = 1:np; end % number of angles to compute nv = length(inds); theta = zeros(nv, 1); for i = 1:nv % current vertex curr = poly(inds(i), :); % previous and next vertices prev = poly(mod(inds(i)-2, np)+1, :); next = poly(mod(inds(i), np)+1, :); theta(i) = angle3Points(prev, curr, next) - pi; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonSelfIntersections.m0000644000000000000000000000013214576357161022552 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonSelfIntersections.m0000644000175000017500000000733414576357161024341 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = polygonSelfIntersections(poly, varargin) %POLYGONSELFINTERSECTIONS Find self-intersection points of a polygon. % % PTS = polygonSelfIntersections(POLY) % Return the position of self intersection points % % [PTS, POS1, POS2] = polygonSelfIntersections(POLY) % Also return the 2 positions of each intersection point (the position % when meeting point for first time, then position when meeting point % for the second time). % % [...] = polygonSelfIntersections(POLY, 'tolerance', TOL) % Specifies an additional parameter to decide whether two intersection % points should be considered the same, based on their euclidean % distance. % % % Example % % use a '8'-shaped polygon % poly = [10 0;0 0;0 10;20 10;20 20;10 20]; % polygonSelfIntersections(poly) % ans = % 10 10 % % See also % polygons2d, polylineSelfIntersections % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform tol = 1e-14; % parse optional arguments while length(varargin) > 1 pname = varargin{1}; if ~ischar(pname) error('Expect optional arguments as name-value pairs'); end if strcmpi(pname, 'tolerance') tol = varargin{2}; else error(['Unknown parameter name: ' pname]); end varargin(1:2) = []; end % ensure the last point equals the first one if sum(abs(poly(end, :)-poly(1,:)) < tol) ~= 2 poly = [poly; poly(1,:)]; end % compute intersections by calling algo for polylines [points, pos1, pos2] = polylineSelfIntersections(poly, 'closed', 'tolerance', tol); % It may append that first vertex of polygon is detected as intersection, % the following tries to detect this. % (pos1 < pos2 by construction) n = size(poly, 1) - 1; inds = abs(pos1) < tol & abs(pos2 - n) < tol; points(inds, :) = []; pos1(inds) = []; pos2(inds) = []; %% Post-processing % process output arguments if nargout <= 1 varargout = {points}; elseif nargout == 3 varargout = {points, pos1, pos2}; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonSignature.m0000644000000000000000000000013214576357161021050 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonSignature.m0000644000175000017500000000630314576357161022632 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [res, thetaList] = polygonSignature(poly, varargin) %POLYGONSIGNATURE Polar signature of a polygon (polar distance to origin). % % DISTS = polygonSignature(POLY, THETALIST) % Computes the polar signature of a polygon, for a set of angles in % degrees. If a ray at a given angle does not intersect the polygon, the % corresponding distance value is set to NaN. % % DISTS = polygonSignature(POLY, N) % When N is a scalar, uses N angles equally distributed between 0 and 360 % degrees. % % [DISTS, THETA] = polygonSignature(...) % Also returns the angle set for which the signature was computed. % % Example % polygonSignature % % See also % polygons2d, signatureToPolygon, intersectRayPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-03-14, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % default angle list thetaList = 0:359; % get user-defined angle list if ~isempty(varargin) var = varargin{1}; if isscalar(var) thetaList = linspace(0, 360, var+1); thetaList(end) = []; else thetaList = var; end end % also extract reference point if needed center = [0 0]; if nargin > 2 center = varargin{2}; end % allocate memory nTheta = length(thetaList); res = NaN * ones(nTheta, 1); % iterate on angles for i = 1:length(thetaList) theta = deg2rad(thetaList(i)); ray = [center cos(theta) sin(theta)]; ptInt = intersectRayPolygon(ray, poly); if ~isempty(ptInt) res(i) = distancePoints(center, ptInt(1,:)); end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/projPointOnPolyline.m0000644000000000000000000000013214576357161021474 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/projPointOnPolyline.m0000644000175000017500000001067614576357161023266 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = projPointOnPolyline(point, poly, varargin) %PROJPOINTONPOLYLINE Compute position of a point projected on a polyline. % % POS = projPointOnPolyline(POINT, POLYLINE) % Compute the position of the orthogonal projection of a point on a % polyline. % POINT is a 1-by-2 row vector containing point coordinates % POLYLINE is a N-by-2 array containing coordinates of polyline vertices % POS is the position of the point on the polyline, between 0 and the % number of vertices of the polyline. POS can be a non-integer value, in % this case, the integer part corresponds to the polyline edge index % (between 0 and Nv-1), and the floating-point part corresponds to the % relative position on i-th edge (between 0 and 1, 0: edge start, 1: edge % end). % % When POINT is an array of points, returns a column vector with as many % rows as the number of points. % % POS = projPointOnPolyline(POINT, POLYLINE, CLOSED) % Specifies if the polyline is closed or not. CLOSED can be one of: % 'closed' -> the polyline is closed % 'open' -> the polyline is open % a column vector of logical with the same number of elements as the % number of points -> specify individually if each polyline is % closed (true=closed). % % [POS, DIST] = projPointOnPolyline(...) % Also returns the distance between POINT and POLYLINE. % % Example % poly = [10 10; 20 10;20 20;10 20]; % projPointOnPolyline([15 0], poly) % ans = % 0.5000 % projPointOnPolyline([0 16], poly) % ans = % 3.0000 % % See also % points2d, polygons2d, polylinePoint, projPointOnPolygon % distancePointPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % check if input polyline is closed or not closed = false; if ~isempty(varargin) var = varargin{1}; if strcmp('closed', var) closed = true; elseif strcmp('open', var) closed = false; elseif islogical(var) closed = var; end end % closes the polyline if necessary if closed poly = [poly ; poly(1,:)]; end % number of points Np = size(point, 1); % allocate memory results pos = zeros(Np, 1); minDist = inf*ones(Np, 1); % iterate on points for p = 1:Np % build set of edges edges = [poly(1:end-1, :) poly(2:end, :)]; % compute distance between current point and all edges [dist, edgePos] = distancePointEdge(point(p, :), edges); % update distance and position if necessary [minDist(p), edgeIndex] = min(dist); pos(p) = edgeIndex - 1 + edgePos(edgeIndex); end % process output arguments if nargout <= 1 varargout{1} = pos; elseif nargout == 2 varargout{1} = pos; varargout{2} = minDist; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/convexHull.m0000644000000000000000000000013214576357161017626 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/convexHull.m0000644000175000017500000000655014576357161021414 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [hull, inds] = convexHull(points, varargin) %CONVEXHULL Convex hull of a set of points. % % POLY = convexHull(POINTS) % Computes the convex hull of the set of points POINTS. This function is % mainly a wrapper to the convhull function, that format the result to a % polygon. % % [POLY, INDS] = convexHull(POINTS) % Also returns the indices of convex hull vertices within the original % array of points. % % ... = convexHull(POINTS, 'simplify', BOOL) % specifies the 'simplify' option use dfor calling convhull. By default, % the convexHull functions uses simplify equals to TRUE (contrary to the % convhull function), resulting in a more simple convex polygon. % % % Example % % Draws the convex hull of a set of random points % pts = rand(30,2); % drawPoint(pts, '.'); % hull = convexHull(pts); % hold on; % drawPolygon(hull); % % % Draws the convex hull of a paper hen % x = [0 10 20 0 -10 -20 -10 -10 0]; % y = [0 0 10 10 20 10 10 0 -10]; % poly = [x' y']; % hull = convexHull(poly); % figure; drawPolygon(poly); % hold on; axis equal; % drawPolygon(hull, 'm'); % % See also % polygons2d, convhull % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-04-08, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % checkup on array size if size(points, 1) < 3 hull = points; inds = 1:size(points, 1); return; end % parse simplify option simplify = true; if nargin > 2 && strcmpi(varargin{1}, 'simplify') simplify = varargin{2}; end % compute convex hull by calling the 'convhull' function inds = convhull(points(:,1), points(:,2), 'simplify', simplify); hull = points(inds, :); matgeom-1.2.4/inst/polygons2d/PaxHeaders/curveCSMoment.m0000644000000000000000000000013214576357161020231 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/curveCSMoment.m0000644000175000017500000000534614576357161022021 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function m = curveCSMoment(curve, p, q) %CURVECSMOMENT Compute centered scaled moment of a 2D curve. % M = curveCSMoment(CURVE, P, Q) % % Example % curveCSMoment % % See also % polygons2d, curveMoment, curveCMoment % % Reference % Based on ideas and references in: % "Affine curve moment invariants for shape recognition" % Dongmin Zhao and Jie Chen % Pattern Recognition, 1997, vol. 30, pp. 865-901 % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-03-25, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % compute curve centroid centroid = polylineCentroid(curve); % compute perimeter L = polylineLength(curve); % coordinate of vertices px = curve(:,1)-centroid(1); py = curve(:,2)-centroid(2); % compute centroids of line segments cx = (px(1:end-1)+px(2:end))/2; cy = (py(1:end-1)+py(2:end))/2; % compute length of each line segment dl = hypot(px(2:end)-px(1:end-1), py(2:end)-py(1:end-1)); % compute moment m = zeros(size(p)); for i=1:length(p(:)) d = (p(i)+q(i))/2+1; m(i) = sum(cx(:).^p(i) .* cy(:).^q(i) .* dl(:)) / L^d; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/reversePolyline.m0000644000000000000000000000013214576357161020666 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/reversePolyline.m0000644000175000017500000000413114576357161022445 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function rev = reversePolyline(poly) %REVERSEPOLYLINE Reverse a polyline, by iterating vertices from the end. % % POLY2 = reversePolyline(POLY) % POLY2 has same vertices as POLY, but POLY2(i,:) is the same as % POLY(END-i+1,:). % % Example % reversePolyline % % See also % polygons2d, reversePolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform rev = poly(end:-1:1, :); matgeom-1.2.4/inst/polygons2d/PaxHeaders/simplifyPolygon.m0000644000000000000000000000013214576357161020703 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/simplifyPolygon.m0000644000175000017500000000515214576357161022466 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [poly, keepInds] = simplifyPolygon(poly, varargin) %SIMPLIFYPOLYGON Douglas-Peucker simplification of a polygon. % % POLY2 = simplifyPolygon(POLY, TOL) % Simplifies the input polygon using the Douglas-Peucker algorithm. % % Example % elli = [20 30 40 20 30]; % poly = ellipseToPolygon(elli, 500); % poly2 = simplifyPolygon(poly, 1); % use a tolerance equal to 1. % figure; hold on; % drawEllipse(elli); % drawPoint(poly2, 'mo'); % % See also % polygons2d, smoothPolygon, simplifyPolyline, resamplePolygon % % References % http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-03-14, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % call the simplifyPolyline function by ensuring the last vertex is present poly = poly([1:end 1], :); [poly, keepInds] = simplifyPolyline(poly, varargin{:}); % remove last vertex poly(end, :) = []; keepInds(end) = []; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonContains.m0000644000000000000000000000013214576357161020665 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonContains.m0000644000175000017500000000576014576357161022455 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = polygonContains(poly, point) %POLYGONCONTAINS Test if a point is contained in a multiply connected polygon. % % B = polygonContains(POLYGON, POINT); % Returns TRUE if the (possibly multi-connected) polygon POLYGON contains % the point(s) given by POINT. % This is an extension of the Matlab function inpolygon for the case of % polygons with holes. % % Example % POLY = [0 0; 10 0;10 10;0 10;NaN NaN;3 3;3 7;7 7;7 3]; % PT = [5 1;5 4]; % polygonContains(POLY, PT); % ans = % 1 % 0 % % See also % polygons2d, inpolygon, isPointInPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-11, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % transform as a cell array of simple polygons polygons = splitPolygons(poly); N = length(polygons); Np = size(point, 1); % compute orientation of polygon, and format to have Np*N matrix areas = zeros(N, 1); for i = 1:N areas(i) = polygonArea(polygons{i}); end ccw = areas > 0; ccw = repmat(ccw', Np, 1); % test if point inside each polygon in = false(size(point, 1), N); for i = 1:N poly = polygons{i}; in(:, i) = inpolygon(point(:,1), point(:,2), poly(:,1), poly(:,2)); end % count polygons containing point, weighted by polygon orientation res = sum(in.*(ccw==1) - in.*(ccw==0), 2); varargout{1} = res; matgeom-1.2.4/inst/polygons2d/PaxHeaders/expandPolygon.m0000644000000000000000000000013214576357161020326 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/expandPolygon.m0000644000175000017500000001053614576357161022113 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function loops = expandPolygon(poly, dist, varargin) %EXPANDPOLYGON Expand a polygon by a given (signed) distance. % % POLY2 = expandPolygon(POLY, DIST); % Associates to each edge of the polygon POLY the parallel line located % at distance DIST from the current edge, and compute intersections with % neighbor parallel lines. The input polygon POLY must be oriented % counter-clockwise. Otherwise, distance is computed inside the polygon. % The resulting polygon is simplified to remove inner "loops", and can % eventually be disconnected. % The result POLY2 is a cell array, each cell containing a simple linear % ring. % % This is a kind of dilation, but behaviour on corners is different. % This function keeps angles of polygons, but there is no direct relation % between the lengths of each polygon. % % It is also possible to specify negative distance, and get all points % inside the polygon. If the polygon is convex, the result equals % morphological erosion of polygon by a ball with radius equal to the % given distance. % % Example: % % Computes the negative offset of a non-convex polygon % poly = [10 10;30 10;30 30;20 20;10 30]; % poly2 = expandPolygon(poly, -3); % figure; % drawPolygon(poly, 'linewidth', 2); % hold on; drawPolygon(poly2, 'm') % axis equal; axis([0 40 0 40]); % % See also % polygons2d, polygonLoops, polygonSelfIntersections % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-14 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % default options cleanupLoops = false; % process input argument while length(varargin) > 1 paramName = varargin{1}; switch lower(paramName) case 'cleanuploops' cleanupLoops = varargin{2}; otherwise error(['Unknown parameter name: ' paramName]); end varargin(1:2) = []; end % eventually copy first point at the end to ensure closed polygon if sum(poly(end, :) == poly(1,:)) ~= 2 poly = [poly; poly(1,:)]; end % number of vertices of the polygon N = size(poly, 1)-1; % find lines parallel to polygon edges located at distance DIST lines = zeros(N, 4); for i = 1:N side = createLine(poly(i,:), poly(i+1,:)); lines(i, 1:4) = parallelLine(side, dist); end % compute intersection points of consecutive lines lines = [lines;lines(1,:)]; poly2 = zeros(N, 2); for i = 1:N poly2(i,1:2) = intersectLines(lines(i,:), lines(i+1,:)); end % split result polygon into set of loops (simple polygons) loops = polygonLoops(poly2); % keep only loops whose distance to original polygon is correct if cleanupLoops distLoop = zeros(length(loops), 1); for i = 1:length(loops) distLoop(i) = distancePolygons(loops{i}, poly); end loops = loops(abs(distLoop-abs(dist)) < abs(dist)/1000); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/smoothPolyline.m0000644000000000000000000000013214576357161020524 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/smoothPolyline.m0000644000175000017500000000620614576357161022310 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = smoothPolyline(poly, M) %SMOOTHPOLYLINE Smooth a polyline using local averaging. % % RES = smoothPolygon(POLY, M) % POLY contains the polyline vertices, and M is the size of smoothing % (given as the length of the convolution window). % Extremities of the polyline are smoothed with reduced window (last and % first vertices are kept identical, second and penultimate vertices are % smoothed with 3 values, etc.). % % Example % img = imread('circles.png'); % img = imfill(img, 'holes'); % contours = bwboundaries(img'); % poly = contours{1}(201:500,:); % figure; drawPolyline(poly, 'b'); hold on; % poly2 = smoothPolyline(poly, 21); % drawPolygon(poly2, 'm'); % % See also % polygons2d, smoothPolygon, simplifyPolyline, resamplePolyline % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-02-17, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform % compute the number of elements before and after M1 = floor((M - 1) / 2); M2 = ceil((M - 1) / 2); % create convolution vector v2 = ones(M, 1) / M; % apply filtering on central part of the polyline res(:,1) = conv(poly(:,1), v2, 'same'); res(:,2) = conv(poly(:,2), v2, 'same'); % need to recompute the extremities for i = 1:M1 i2 = 2 * i - 1; res(i, 1) = mean(poly(1:i2, 1)); res(i, 2) = mean(poly(1:i2, 2)); end for i = 1:M2 i2 = 2 * i - 1; res(end - i + 1, 1) = mean(poly(end-i2+1:end, 1)); res(end - i + 1, 2) = mean(poly(end-i2+1:end, 2)); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonLength.m0000644000000000000000000000013214576357161020330 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonLength.m0000644000175000017500000000562714576357161022122 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function len = polygonLength(poly, varargin) %POLYGONLENGTH Perimeter of a polygon. % % L = polygonLength(POLYGON); % Computes the boundary length of a polygon. POLYGON is given by a N-by-2 % array of vertices. % % Example % % Perimeter of a circle approximation % poly = circleToPolygon([0 0 1], 200); % polygonLength(poly) % ans = % 6.2829 % % See also % polygons2d, polygonCentroid, polygonArea, drawPolygon, polylineLength % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-11 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % If first argument is a cell array, this is a multi-polygon, and we simply % add the lengths of individual polygons if iscell(poly) len = 0; for i = 1:length(poly) len = len + polygonLength(poly{i}); end return; end % case of a polygon given as two coordinate arrays if nargin == 2 poly = [poly varargin{1}]; end % check there are enough points if size(poly, 1) < 2 len = 0; return; end % compute length if size(poly, 2) == 2 % polygon in dimension 2 (classical case) dp = diff(poly([1:end 1], :), 1, 1); len = sum(hypot(dp(:, 1), dp(:, 2))); else % polygon of larger dimension len = sum(sqrt(sum(diff(poly([2:end 1], :), 1, 1).^2, 2))); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/distancePolylines.m0000644000000000000000000000013214576357161021170 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/distancePolylines.m0000644000175000017500000000450014576357161022747 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dist = distancePolylines(poly1, poly2) %DISTANCEPOLYLINES Compute the shortest distance between 2 polylines. % % DIST = distancePolylines(POLY1, POLY2) % POLY1 and POLY2 should be two polylines represented by their list of % vertices. % % % See also % polygons2d, distancePolygons, distancePointPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-17, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % compute distance of each vertex of a polyline to the other polyline dist1 = min(distancePointPolyline(poly1, poly2)); dist2 = min(distancePointPolyline(poly2, poly1)); % keep the minimum of the two distances dist = min(dist1, dist2); matgeom-1.2.4/inst/polygons2d/PaxHeaders/drawPolyline.m0000644000000000000000000000013214576357161020150 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/drawPolyline.m0000644000175000017500000001034314576357161021731 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawPolyline(varargin) %DRAWPOLYLINE Draw a polyline specified by a list of points. % % drawPolyline(COORD); % packs coordinates in a single [N*2] array. % % drawPolyline(PX, PY); % specifies coordinates in separate arrays. PX and PY must be column % vectors with the same length. % % drawPolyline(..., TYPE); % where TYPE is either 'closed' or 'open', specifies if last point must % be connected to the first one ('closed') or not ('open'). % Default is 'open'. % % drawPolyline(..., PARAM, VALUE); % specify plot options as described for plot command. % % H = drawPolyline(...) also return a handle to the list of line objects. % % Example: % % Draw a curve representing an ellipse % t = linspace(0, 2*pi, 100)'; % px = 10*cos(t); py = 5*sin(t); % drawPolyline([px py], 'closed'); % axis equal; % % % The same, with different drawing options % drawPolyline([px py], 'closed', 'lineWidth', 2, 'lineStyle', '--'); % % See also % polygons2d, drawPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-06 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % If first argument is a cell array, draw each curve individually, % and eventually returns handle of each plot. var = varargin{1}; if iscell(var) h = []; for i = 1:length(var(:)) h = [h ; drawPolyline(ax, var{i}, varargin{2:end})]; %#ok end if nargout > 0 varargout = {h}; end return; end % extract curve coordinate if size(var, 2) == 1 % first argument contains x coord, second argument contains y coord px = var; if length(varargin) == 1 error('Wrong number of arguments in drawPolyline'); end py = varargin{2}; varargin = varargin(3:end); else % first argument contains both coordinate px = var(:, 1); py = var(:, 2); varargin = varargin(2:end); end % check if curve is closed or open closed = false; if ~isempty(varargin) var = varargin{1}; if strncmpi(var, 'close', 5) closed = true; varargin = varargin(2:end); elseif strncmpi(var, 'open', 4) closed = false; varargin = varargin(2:end); end end % if curve is closed, add first point at the end of the list if closed px = [px; px(1)]; py = [py; py(1)]; end % plot the curve, with eventually optional parameters h = plot(ax, px, py, varargin{:}); % format output arguments if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/steinerPoint.m0000644000000000000000000000013214576357161020162 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/steinerPoint.m0000644000175000017500000000530514576357161021745 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function pt = steinerPoint(varargin) %STEINERPOINT Compute steiner point (weighted centroid) of a polygon. % % PT = steinerPoint(POINTS); % PT = steinerPoint(PTX, PTY); % Computes steiner point of a polygon defined by POINTS. POINTS is a % [N*2] array of double. % % The steiner point is computed the same way as the polygon centroid, % except that a weight depending on the angle is given to each vertex. % % See also % polygons2d, polygonArea, polygonCentroid, drawPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-11-11 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if nargin==1 var = varargin{1}; px = var(:,1); py = var(:,2); elseif nargin==2 px = varargin{1}; py = varargin{2}; end % Algorithme P. Bourke sx = 0; sy = 0; N = length(px); for i=1:N-1 sx = sx + (px(i)+px(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); sy = sy + (py(i)+py(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); end sx = sx + (px(N)+px(1))*(px(N)*py(1) - px(1)*py(N)); sy = sy + (py(N)+py(1))*(px(N)*py(1) - px(1)*py(N)); pt = [sx sy]/6/polygonArea(px, py); matgeom-1.2.4/inst/polygons2d/PaxHeaders/clipPolyline.m0000644000000000000000000000013214576357161020142 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/clipPolyline.m0000644000175000017500000000663114576357161021730 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = clipPolyline(poly, box) %CLIPPOLYLINE Clip an open polyline with a rectangular box. % % POLY2 = clipPolyline(POLY, BOX); % POLY is N-by-2 array of vertex coordinates. % BOX has the form: [XMIN XMAX YMIN YMAX]. % Returns the set of polylines created by the intersection of the % polyline POLY and the bounding box BOX. The result is a cell array with % as many cells as the number of curve clips. % % % Example % circle = [5 5 6]; % poly = circleToPolygon(circle, 200); % box = [0 10 0 10]; % res = clipPolyline(poly, box); % figure; % hold on; axis equal; axis([-2 12 -2 12]); % drawCircle(circle, 'b:') % drawBox(box, 'k') % drawPolyline(res, 'linewidth', 2, 'color', 'b') % % See also % polygons2d, boxes2d, clipPolygon, clipEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-05-14 % Copyright 2005-2023 INRA - Cepia Software Platform % check case of polylines stored in cell array if iscell(poly) res = cell(1, length(poly)); for i = 1:length(poly) res{i} = clipPolyline(poly{i}, box); end return; end % check case of empty polylines N = size(poly, 1); if N == 0 res = cell(0, 0); return end % create edges array of polyline edges = [poly(1:N-1, :) poly(2:N, :)]; % clip edges edges = clipEdge(edges, box); % select non empty edges, and get their vertices % find clipped edges within box inds = sum(abs(edges), 2) > 1e-14; % find list of adjacent edges within box dinds = diff(inds); inds0 = find(dinds == 1) + 1; if inds(1) == 1 inds0 = [1 inds0]; end inds1 = find(dinds == -1); if inds(end) == 1 inds1 = [inds1 N-1]; end nClips = length(inds0); res = cell(1, nClips); for iClip = 1:nClips range = inds0(iClip):inds1(iClip); poly2 = [edges(range, 1:2) ; edges(range(end), 3:4)]; res{iClip} = poly2; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/readPolygonSet.m0000644000000000000000000000013214576357161020436 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/readPolygonSet.m0000644000175000017500000000574714576357161022233 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polys = readPolygonSet(filename) %READPOLYGONSET Read a set of simple polygons stored in a file. % % POLY = readPolygonSet(FILENAME); % Returns the polygon stored in the file FILENAME. % Polygons are assumed to be stored in text files, without headers, with % x and y coordinates packed in two separate lines: % X11 X12 X13 ... X1N % Y11 Y12 Y13 ... Y1N % X21 X22 X23 ... X2N % Y21 Y22 Y23 ... Y2N % % Each polygon may have a different number of vertices. The result is a % cell array of polygon, each cell containing a N-by-2 array representing % the vertex coordinates. % % See also % polygons2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-11 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % the set of polygons (no pre-allocation, as we do not know how many % polygons are stored) polys = {}; % index of polygon p = 0; % open file for reading fid = fopen(filename, 'rt'); % use an infinite loop, terminated in case of EOF while true % set of X, and Y coordinates line1 = fgetl(fid); line2 = fgetl(fid); % break loop if end of file is reached if line1 == -1 break; end % create a new polygon by concatenating vertex coordinates p = p + 1; polys{p} = [str2num(line1)' str2num(line2)']; %#ok end % close file fclose(fid); matgeom-1.2.4/inst/polygons2d/PaxHeaders/resamplePolygon.m0000644000000000000000000000013214576357161020657 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/resamplePolygon.m0000644000175000017500000000521214576357161022437 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = resamplePolygon(poly, n) %RESAMPLEPOLYGON Distribute N points equally spaced on a polygon. % % POLY2 = resamplePolygon(POLY, N) % Resample the input polygon POLY such that the resulting polygon POLY2 % has N vertices. All points of POLY2 belong to the initial polygon, but % are not necessarily vertices of the original polygon. % % % Example % % creates a polygon from an ellipse % elli = [20 30 40 20 30]; % poly = ellipseToPolygon(elli, 500); % figure; drawPolygon(poly, 'b'); % % resample the polygon with a fixed number of vertices % poly2 = resamplePolygon(poly, 20); % drawPolygon(poly2, 'm'); % drawPoint(poly2, 'mo'); % axis equal; axis([-20 60 0 60]); % % See also % polygons2d, resamplePolygonByLength, smoothPolygon, resamplePolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform poly2 = resamplePolyline(poly([1:end 1],:), n+1); poly2(end, :) = []; matgeom-1.2.4/inst/polygons2d/PaxHeaders/densifyPolygon.m0000644000000000000000000000013214576357161020510 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/densifyPolygon.m0000644000175000017500000000572014576357161022274 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = densifyPolygon(poly, N) %DENSIFYPOLYGON Add several points on each edge of the polygon. % % POLY2 = densifyPolygon(POLY, N) % POLY is a NV-by-2 array containing polygon coordinates. The function % iterates on polygon edges, divides it into N subedges (by inserting N-1 % new vertices on each edges), and return the resulting polygon. % The new polygon POLY has therefore N*NV vertices. % % Example % % Densifies a simple polygon % poly = [0 0 ; 10 0;5 10;15 15;5 20;-5 10]; % poly2 = densifyPolygon(poly, 10); % figure; drawPolygon(poly); axis equal % hold on; drawPoint(poly2); % % See also % drawPolygon, edgeToPolyline % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-11-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % number of vertices, and of edges Nv = size(poly, 1); % number of vertices in new polygon N2 = N * Nv; poly2 = zeros(N2, 2); % iterate on polygon edges for i = 1:Nv % extract current edge v1 = poly(i, :); v2 = poly(mod(i, Nv) + 1, :); % convert current edge to polyline newVertices = edgeToPolyline([v1 v2], N); % indices of current polyline to resulting polygon i1 = (i-1)*N + 1; i2 = i * N; % fill up polygon poly2(i1:i2, :) = newVertices(1:end-1, :); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonArea.m0000644000000000000000000000013214576357161017757 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonArea.m0000644000175000017500000000775014576357161021550 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function area = polygonArea(poly, varargin) %POLYGONAREA Compute the signed area of a polygon. % % A = polygonArea(POINTS); % Compute area of a polygon defined by POINTS. POINTS is a N-by-2 array % of double containing coordinates of vertices. % % Vertices of the polygon are supposed to be oriented Counter-Clockwise % (CCW). In this case, the signed area is positive. % If vertices are oriented Clockwise (CW), the signed area is negative. % % If polygon is self-crossing, the result is undefined. % % Examples % % compute area of a simple shape % poly = [10 10;30 10;30 20;10 20]; % area = polygonArea(poly) % area = % 200 % % % compute area of CW polygon % area2 = polygonArea(poly(end:-1:1, :)) % area2 = % -200 % % % Computes area of a paper hen % x = [0 10 20 0 -10 -20 -10 -10 0]; % y = [0 0 10 10 20 10 10 0 -10]; % poly = [x' y']; % area = polygonArea(poly) % area = % 400 % % % Area of unit square with 25% hole % pccw = [0 0; 1 0; 1 1; 0 1]; % pcw = pccw([1 4 3 2], :) * .5 + .25; % polygonArea ([pccw; nan(1,2); pcw]) % ans = % 0.75 % % References % algo adapted from P. Bourke web page % http://paulbourke.net/geometry/polygonmesh/ % % See also % polygons2d, polygonCentroid, polygonSecondAreaMoments, triangleArea % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-05 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE %% Process special cases % in case of polygon sets, computes the sum of polygon areas if iscell(poly) area = 0; for i = 1:length(poly) area = area + polygonArea(poly{i}); end return; end % check there are enough points if size(poly, 1) < 2 area = 0; return; end % case of polygons with holes -> computes the sum of areas if any(isnan(poly)) area = sum(polygonArea(splitPolygons(poly))); return; end %% Process single polygons or single rings % extract coordinates if nargin == 1 % polygon given as N-by-2 array px = poly(:, 1); py = poly(:, 2); elseif nargin == 2 % poylgon given as two N-by-1 arrays px = poly; py = varargin{1}; end % indices of next vertices N = length(px); iNext = [2:N 1]; % compute area (vectorized version) area = sum(px .* py(iNext) - px(iNext) .* py) / 2; matgeom-1.2.4/inst/polygons2d/PaxHeaders/writePolygonSet.m0000644000000000000000000000013214576357161020655 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/writePolygonSet.m0000644000175000017500000000502114576357161022433 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function writePolygonSet(polys, filename) %WRITEPOLYGONSET Write a set of simple polygons into a file. % % writePolygonSet(POLYS, FILENAME); % Writes the set of polygons in the file FILENAME. % Following format is used: % X11 X12 X13 ... X1N % Y11 Y12 Y13 ... Y1N % X21 X22 X23 ... X2N % Y21 Y22 Y23 ... Y2N % Each polygon may have a different number of vertices. % % See also % polygons2d, readPolygonSet % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-01-14 % Copyright 2013-2023 INRA - TPV URPOI - BIA IMASTE % open file for reading fid = fopen(filename, 'wt'); for i = 1:length(polys) poly = polys{i}; n = size(poly, 1); % precompute format format = [repmat('%g ', 1, n) '\n']; % write one line for x, then one line for y fprintf(fid, format, poly(:,1)'); fprintf(fid, format, poly(:,2)'); end % close file fclose(fid); matgeom-1.2.4/inst/polygons2d/PaxHeaders/contourMatrixToPolylines.m0000644000000000000000000000013214576357161022557 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/contourMatrixToPolylines.m0000644000175000017500000000536114576357161024344 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polys = contourMatrixToPolylines(C) %CONTOURMATRIXTOPOLYLINES Converts a contour matrix array into a polyline set. % % POLYS = contourMatrixToPolylines(C) % Converts the contour matrix array, as given as the result of the % contourc function, into a set of polylines. % % Example % img = imread('circles.png'); % C = contourc(img, 1); % polys = contourMatrixToPolylines(C); % imshow(img); hold on; % drawPolyline(polys, 'Color', 'r', 'LineWidth', 2); % % See also % polygons2d, contour, contourc % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-08-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % size of the contour matrix array nCoords = size(C, 2); % first, compute the number of contours nContours = 0; offset = 1; while offset < nCoords nContours = nContours + 1; offset = offset + C(2, offset) + 1; end % extract each contour as a polygon or polyline polys = cell(nContours, 1); offset = 1; for iContour = 1:nContours nv = C(2, offset); polys{iContour} = C(:, offset + (1:nv))'; offset = offset + nv + 1; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/splitPolygons.m0000644000000000000000000000013214576357161020365 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/splitPolygons.m0000644000175000017500000000530014576357161022143 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polygons = splitPolygons(polygon) %SPLITPOLYGONS Convert a NaN separated polygon list to a cell array of polygons. % % POLYGONS = splitPolygons(POLYGON); % POLYGON is a N-by-2 array of points, possibly with pairs of NaN values. % The functions separates each component separated by NaN values, and % returns a cell array of polygons. % % See also % polygons2d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-12, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas if iscell(polygon) % case of a cell array polygons = polygon; elseif sum(isnan(polygon(:))) == 0 % single polygon -> no break polygons = {polygon}; else % find indices of NaN couples inds = find(sum(isnan(polygon), 2) > 0); % number of polygons N = length(inds) + 1; polygons = cell(N, 1); % iterate over NaN-separated regions to create new polygon inds = [0; inds; size(polygon, 1)+1]; for i = 1:N polygons{i} = polygon((inds(i)+1):(inds(i+1)-1), :); end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/intersectLinePolygon.m0000644000000000000000000000013214576357161021657 xustar0030 mtime=1710874225.138193345 30 atime=1710874225.138193345 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/intersectLinePolygon.m0000644000175000017500000001536714576357161023453 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [points, edgeInds, linePositions] = intersectLinePolygon(line, poly, varargin) %INTERSECTLINEPOLYGON Intersection points between a line and a polygon. % % P = intersectLinePolygon(LINE, POLY) % Returns the intersection points of the lines LINE with polygon POLY. % LINE is a 1-by-4 row vector containing parametric representation of the % line (in the format [x0 y0 dx dy], see the function 'createLine' for % details). % POLY is a NV-by-2 array containing coordinates of the polygon vertices % P is a K-by-2 array containing the coordinates of the K intersection % points. % % P = intersectLinePolygon(LINE, POLY, TOL) % Specifies the tolerance for geometric tests. Default is 1e-14. % % [P, INDS] = intersectLinePolygon(...) % Also returns the indices of edges involved in intersections. INDS is a % K-by-1 column vector, such that P(i,:) corresponds to intersection of % the line with the i-th edge of the polygon. If the intersection occurs % at a polygon vertex, the index of only one of the two neighbor edges is % returned. % Note that due to numerical approximations, the use of function % 'isPointOnEdge' may give results not consistent with this function. % % [P, INDS, POS] = intersectLinePolygon(...) % Also returns the relative position of each intersection point along the % line. The position can be used to sort the points. % % Examples % % compute intersections between a square and an horizontal line % poly = [0 0;10 0;10 10;0 10]; % line = [5 5 1 0]; % intersectLinePolygon(line, poly) % ans = % 10 5 % 0 5 % % also return indices of edges % [inters, inds] = intersectLinePolygon(line, poly) % inters = % 10 5 % 0 5 % inds = % 4 % 2 % % % Potentially prolematic case % % create a polygon with various configurations at y=50 % poly = [10 30;30 50;45 30; 50 50; 60 70; 70 50; ... % 90 30; 80 80; 50 80; 40 50; 30 80; 20 80]; % figure; axis([0 100 0 100]); hold on; % drawPolygon(poly, 'b'); drawPoint(poly, 'b.'); % % Computes intersection with horizontal line at y=50 % line = [10 50 2 0]; drawLine(line, 'm'); % points = intersectLinePolygon(line, poly); % % result is a 6-by-2 numeric array, with a double intersection % % (indices 2 and 3), resulting in five displayed intersections. % drawPoint(points, 'ko'); % % sort intersection points according to x-coordinate % points2 = sortrows(points, 1); % % display pairs of successive intersection points as colored lines % for i = 1:2:size(points2, 1) % drawEdge(points2(i,:), points2(i+1,:), 'linewidth', 2); % end % % References % https://web.cs.ucdavis.edu/~ma/ECS175_S00/Notes/0411_b.pdf % https://alienryderflex.com/polygon_fill/ % % See also % lines2d, polygons2d, intersectLines, intersectRayPolygon, polygonEdges % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-10-31, using Matlab 7.9.0.529 (R2009b) % Copyright 2003-2023 INRA - Cepia Software Platform % line origin and angle ox = line(1); oy = line(2); dx = line(3); dy = line(4); % create transform matrix that project line onto the horizontal axis % (then, computation of intersections rely only on the y-coordinate) theta = atan2(dy, dx); s = hypot(dx, dy); cot = cos(theta) / s; sit = sin(theta) / s; transfo = [cot sit 0; -sit cot 0; 0 0 1] * [1 0 -ox; 0 1 -oy; 0 0 1]; % number of vertices in polygon nVertices = size(poly, 1); % create arrays for storing x-coordinates and edge inds of intersections linePositions = []; edgeInds = []; % retrieve previous vertex and its y-coordinate ivp = nVertices; previousVertex = transformPoint(poly(ivp,:), transfo); yvp = previousVertex(2); % iterate over indices of first edge vertex for iv = 1:nVertices % current vertex and its y-coordinate currentVertex = transformPoint(poly(iv,:), transfo); yv = currentVertex(2); % check conditions for intersection % either if: % 1) previous vertex is above or on, and current vertex is strictly below % 2) previous vertex is strictly below, and current vertex is above or on if yvp >= 0 && yv < 0 || yvp < 0 && yv >= 0 % slope of current edge (dy cannot be zero due to above condition) edgeDx = currentVertex(1) - previousVertex(1); edgeDy = currentVertex(2) - previousVertex(2); % position of intersection on the horizontal line currentPos = currentVertex(1) - yv * edgeDx / edgeDy ; % add to list of intersections linePositions = [linePositions ; currentPos]; %#ok % keep list if edge indices edgeInds = [edgeInds ; ivp]; %#ok end % switch current vertex to previous vertex previousVertex = currentVertex; ivp = iv; % keep edge index for optional output yvp = yv; end % format output result into a N-by-2 array of points if ~isempty(linePositions) points = [linePositions zeros(size(linePositions))]; points = transformPoint(points, inv(transfo)); else points = []; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/resamplePolylineByLength.m0000644000000000000000000000013214576357161022460 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/resamplePolylineByLength.m0000644000175000017500000000676214576357161024253 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = resamplePolylineByLength(poly, step) %RESAMPLEPOLYLINEBYLENGTH Resample a polyline with a fixed sampling step. % % RES = resamplePolyline(POLY, STEP) % Resample the input polyline POLY by distributing new vertices on the % original polyline such that the (curvilinear) distance between the new % vertices is approximately equal to STEP. % % Example % poly = [0 10;0 0;10 0; 10 10; 20 10;20 0]; % figure; drawPolyline(poly, 'k'); % poly2 = resamplePolylineByLength(poly, 4); % hold on; % drawPolyline(poly2, 'm'); % drawPoint(poly2, 'mo'); % axis equal; axis([-10 30 -10 20]); % legend('Original polyline', 'Resampled polyline'); % % See also % polygons2d, drawPolyline, resamplePolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % parametrisation of the curve s = parametrize(poly); % compute the number of points for sampling the polygon % (equal to the number of segments plus one) Lmax = s(end); n = round(Lmax / step) + 1; % distribute N points equally spaced pos = linspace(0, Lmax, n); poly2 = zeros(n, size(poly, 2)); for i = 1:n % index of surrounding vertices before and after ind0 = find(s <= pos(i), 1, 'last'); ind1 = find(s >= pos(i), 1, 'first'); if ind0 == ind1 % get position of a vertex in input polyline poly2(i, :) = poly(ind0, :); continue; end % position of surrounding vertices pt0 = poly(ind0, :); pt1 = poly(ind1, :); % weights associated to each neighbor l0 = pos(i) - s(ind0); l1 = s(ind1) - pos(i); % linear interpolation of neighbor positions if (l0 + l1) > Lmax * 1e-12 poly2(i, :) = (pt0 * l1 + pt1 * l0) / (l0 + l1); else % if neighbors are too close, do not use interpolation poly2(i, :) = pt0; end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/projPointOnPolygon.m0000644000000000000000000000013214576357161021330 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/projPointOnPolygon.m0000644000175000017500000000632014576357161023111 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = projPointOnPolygon(point, poly, varargin) %PROJPOINTONPOLYGON Compute position of a point projected on a polygon. % % POS = projPointOnPolygon(POINT, POLYGON) % Compute the position of the orthogonal projection of a point on a % polygon. % POINT is a 1-by-2 row vector containing point coordinates % POLYGON is a N-by-2 array containing coordinates of polygon vertices % % When POINT is an array of points, returns a column vector with as many % rows as the number of points. % % [POS, DIST] = projPointOnPolygon(...) % Also returns the distance between POINT and POLYGON. The distance is % negative if the point is located inside of the polygon. % % Example % poly = [10 10; 20 10;20 20;10 20]; % projPointOnPolygon([15 0], poly) % ans = % 0.5000 % projPointOnPolygon([0 16], poly) % ans = % 3.4000 % % See also % points2d, polygons2d, polygonPoint, projPointOnPolyline % distancePointpolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % eventually copy first point at the end to ensure closed polygon if sum(poly(end, :) == poly(1,:)) ~= 2 poly = [poly; poly(1,:)]; end % compute position wrt outline [pos, minDist] = projPointOnPolyline(point, poly); % process output arguments if nargout <= 1 varargout{1} = pos; elseif nargout == 2 varargout{1} = pos; if inpolygon(point(:,1), point(:,2), poly(:,1), poly(:,2)) minDist = -minDist; end varargout{2} = minDist; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/removeMultipleVertices.m0000644000000000000000000000013214576357161022215 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/removeMultipleVertices.m0000644000175000017500000000622414576357161024001 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly = removeMultipleVertices(poly, varargin) %REMOVEMULTIPLEVERTICES Remove multiple vertices of a polygon or polyline. % % POLY2 = removeMultipleVertices(POLY, EPS) % Remove adjacent vertices that are closer than the distance EPS to each % other and merge them to a unique vertex. % % POLY2 = removeMultipleVertices(POLY, EPS, CLOSED) % If CLOSED is true, also check if first and last vertices need to be % merged. If not specified, CLOSED is false. % % Example % poly = [10 10; 20 10;20 10;20 20;10 20; 10 10]; % poly2 = removeMultipleVertices(poly, true); % size(poly2, 1) % ans = % 4 % % See also % polygons2d, mergeClosePoints % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % default values eps = 1e-14; closed = false; % process input options while ~isempty(varargin) var = varargin{1}; if islogical(var) closed = var; elseif isnumeric(var) eps = var; else error('MatGeom:removeMultipleVertices:IllegalArgument',... 'Can not interpret optional argument'); end varargin(1) = []; end % distance between adjacent vertices dist = sqrt(sum((poly(2:end,:) - poly(1:end-1,:)).^2, 2)); multi = dist < eps; % process extremities if closed dist = sqrt(sum((poly(end,:) - poly(1,:)).^2, 2)); multi = [multi ; dist < eps]; else multi = [multi ; false]; end % remove multiple vertices poly(multi, :) = []; matgeom-1.2.4/inst/polygons2d/PaxHeaders/intersectRayPolygon.m0000644000000000000000000000013214576357161021523 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/intersectRayPolygon.m0000644000175000017500000000520414576357161023304 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [intersects, edgeIndices] = intersectRayPolygon(ray, poly, varargin) %INTERSECTRAYPOLYGON Intersection points between a ray and a polygon. % % PTS = intersectRayPolygon(RAY, POLY) % Returns the intersection points of the ray RAY with polygon POLY. % RAY is a 1x4 array containing parametric representation of the ray % (in the form [x0 y0 dx dy], see createRay for details). % POLY is a N-by-2 array containing coordinates of polygon vertices. % % [PTS, INDS] = intersectRayPolygon(...) % Also returns index of polygon intersected edge(s). See % intersectLinePolygon for details. % % See also % rays2d, polygons2d, intersectLinePolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-01-26 % Copyright 2010-2023 % compute intersections with supporting line [intersects, edgeIndices, pos] = intersectLinePolygon(ray, poly, varargin{:}); % keep only intersects with non-negative position on line indPos = pos >= 0; intersects = intersects(indPos, :); edgeIndices = edgeIndices(indPos); matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonCurvature.m0000644000000000000000000000013214576357161021067 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonCurvature.m0000644000175000017500000000701414576357161022651 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function curv = polygonCurvature(poly, M) %POLYGONCURVATURE Estimate curvature on polygon vertices using polynomial fit. % % CURV = polygonCurvature(POLY, M) % Estimate the curvature for each vertex of a polygon, using polynomial % fit from the M vertices located around current vertex. M is usually an % odd value, resulting in a symmetric neighborhood. % % Polynomial fitting is of degree 2. % % % Example % img = imread('circles.png'); % img = imfill(img, 'holes'); % imgf = imfilter(double(img), fspecial('gaussian', 7, 2)); % figure(1), imshow(imgf); % contours = imContours(imgf, .5); poly = contours{1}; % poly2 = smoothPolygon(poly, 7); % hold on; drawPolygon(poly2); % curv = polygonCurvature(poly2, 11); % figure; plot(curv); % minima = bwlabel(imextendedmin(curv, .05)); % centroids = imCentroid(minima); % inds = round(centroids(:,2)); % figure(1); hold on; drawPoint(poly2(inds, :), 'g*') % % See also % polygons2d, polylineCurvature % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-03-02, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018-2023 INRA - Cepia Software Platform % number of vertices of polygon n = size(poly, 1); % allocate memory for result curv = zeros(n, 1); % number of vertices before and after current vertex s1 = floor((M - 1) / 2); s2 = ceil((M - 1) / 2); % parametrisation basis % As we recenter the points, the constant factor is omitted ti = (-s1:s2)'; X = [ti ti.^2]; % Iteration on vertex indices for i = 1:n % coordinate of current vertex, for recentring neighbor vertices x0 = poly(i,1); y0 = poly(i,2); % indices of neighbors inds = i-s1:i+s2; inds = mod(inds-1, n) + 1; % Least square estimation using mrdivide xc = X \ (poly(inds,1) - x0); yc = X \ (poly(inds,2) - y0); % compute curvature curv(i) = 2 * (xc(1)*yc(2) - xc(2)*yc(1) ) / power(xc(1)^2 + yc(1)^2, 3/2); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/smoothPolygon.m0000644000000000000000000000013214576357161020360 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/smoothPolygon.m0000644000175000017500000000544214576357161022145 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = smoothPolygon(poly, M) %SMOOTHPOLYGON Smooth a polygon using local averaging. % % RES = smoothPolygon(POLY, M) % POLY contains the polygon vertices, and M is the size of smoothing % (given as the length of the convolution window). % % % Example % img = imread('circles.png'); % img = imfill(img, 'holes'); % contours = bwboundaries(img'); % contour = contours{1}; % imshow(img); hold on; drawPolygon(contour, 'b'); % contourf = smoothPolygon(contour, 11); % drawPolygon(contourf, 'm'); % % See also % polygons2d, smoothPolyline, simplifyPolygon, resamplePolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-02-17, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform % compute the number of elements before and after M1 = floor((M - 1) / 2); M2 = ceil((M - 1) / 2); % repeat beginning and end of contour poly2 = [poly(end-M1+1:end, :) ; poly ; poly(1:M2,:)]; % create convolution vector v2 = ones(M, 1) / M; % apply contour filtering res(:,1) = conv(poly2(:,1), v2, 'same'); res(:,2) = conv(poly2(:,2), v2, 'same'); % keep the interesting part res = res(M1+1:end-M2, :); matgeom-1.2.4/inst/polygons2d/PaxHeaders/curveMoment.m0000644000000000000000000000013214576357161020003 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/curveMoment.m0000644000175000017500000000505514576357161021570 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function m = curveMoment(curve, p, q) %CURVEMOMENT Compute inertia moment of a 2D curve. % M = curveMoment(CURVE, P, Q) % % Example % curveMoment % % See also % polygons2d, curveCMoment, curveCSMoment % % Reference % Based on ideas and references in: % "Affine curve moment invariants for shape recognition" % Dongmin Zhao and Jie Chen % Pattern Recognition, 1997, vol. 30, pp. 865-901 % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-03-25, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % coordinate of vertices px = curve(:,1); py = curve(:,2); % compute centroids of line segments cx = (px(1:end-1)+px(2:end))/2; cy = (py(1:end-1)+py(2:end))/2; % compute length of each line segment dl = hypot(px(2:end)-px(1:end-1), py(2:end)-py(1:end-1)); % compute moment m = zeros(size(p)); for i=1:length(p(:)) m(i) = sum(cx(:).^p(i) .* cy(:).^q(i) .* dl(:)); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonSecondAreaMoments.m0000644000000000000000000000013214576357161022456 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonSecondAreaMoments.m0000644000175000017500000000544514576357161024246 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [Ixx, Iyy, Ixy] = polygonSecondAreaMoments(poly) %POLYGONSECONDAREAMOMENTS Compute second-order area moments of a polygon. % % [IXX, IYY, IXY] = polygonSecondAreaMoments(POLY) % Compute the second-order inertia moments of a polygon. The polygon is % specified by the N-by-2 list of vertex coordinates. % % Example % polygonSecondAreaMoments % % References % * http://paulbourke.net/geometry/polygonmesh/ % * https://en.wikipedia.org/wiki/Second_moment_of_area % % See also % polygons2d, polygonEquivalentEllipse, polygonArea, polygonCentroid % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-09-08, using Matlab 9.1.0.441655 (R2016b) % Copyright 2017-2023 INRA - Cepia Software Platform poly = parsePolygon(poly, 'repetition'); px = poly(:,1); py = poly(:,2); % vertex indices N = length(px); iNext = [2:N 1]; % compute twice signed area of each triangle common = px .* py(iNext) - px(iNext) .* py; % compute each term Ixx = sum( (py.^2 + py .* py(iNext) + py(iNext).^2) .* common) / 12; Iyy = sum( (px.^2 + px .* px(iNext) + px(iNext).^2) .* common) / 12; Ixy = sum( ... (px .* py(iNext) + 2 * px .* py + 2 * px(iNext) .* py(iNext) ... + px(iNext) .* py ) .* common) / 24; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polylineSelfIntersections.m0000644000000000000000000000013214576357161022716 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polylineSelfIntersections.m0000644000175000017500000001632114576357161024501 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = polylineSelfIntersections(poly, varargin) %POLYLINESELFINTERSECTIONS Find self-intersection points of a polyline. % % Computes self-intersections of a polyline, eventually specifying if % polyline is closed or open, and eventually returning position of % intersection points on polyline. % For common use cases, the intersectPolylines function may return the % desired result in a faster way. % % % PTS = polylineSelfIntersections(POLY); % Returns the position of self intersections of the given polyline. % % PTS = polylineSelfIntersections(POLY, CLOSED); % Adds an options to specify if the polyline is closed (i.e., is a % polygon), or open (the default). CLOSED can be a boolean, or one of % 'closed' or 'open'. % % [PTS, POS1, POS2] = polylineSelfIntersections(POLY); % Also return the 2 positions of each intersection point (the position % when meeting point for first time, then position when meeting point % for the second time). % % [...] = polylineSelfIntersections(POLY, 'tolerance', TOL) % Specifies an additional parameter to decide whether two intersection % points should be considered the same, based on their Euclidean % distance. % % % Example % % use a gamma-shaped polyline % poly = [0 0;0 10;20 10;20 20;10 20;10 0]; % polylineSelfIntersections(poly) % ans = % 10 10 % % % use a 'S'-shaped polyline % poly = [10 0;0 0;0 10;20 10;20 20;10 20]; % polylineSelfIntersections(poly) % ans = % Empty matrix: 0-by-2 % polylineSelfIntersections(poly, 'closed') % ans = % 10 10 % % See also % polygons2d, intersectPolylines, polygonSelfIntersections % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform %% Initialisations % flag indicating whether the polyline is closed (polygon) or not closed = false; % the tolerance for comparing positions based on distances tol = 1e-14; % determine whether the polyline is open or closed if ~isempty(varargin) closed = varargin{1}; if ischar(closed) if strcmp(closed, 'closed') closed = true; varargin(1) = []; elseif strcmp(closed, 'open') closed = false; varargin(1) = []; end end end % parse optional arguments while length(varargin) > 1 pname = varargin{1}; if ~ischar(pname) error('Expect optional arguments as name-value pairs'); end if strcmpi(pname, 'tolerance') tol = varargin{2}; else error(['Unknown parameter name: ' pname]); end varargin(1:2) = []; end % if polyline is closed, ensure the last point equals the first one if closed if sum(abs(poly(end, :) - poly(1,:)) < tol) ~= 2 poly = [poly; poly(1,:)]; end end % arrays for storing results points = zeros(0, 2); pos1 = zeros(0, 1); pos2 = zeros(0, 1); % number of edges nEdges = size(poly, 1) - 1; %% Main processing % index of current intersection ip = 0; % iterate over each couple of edge ( (N-1)*(N-2)/2 iterations) for iEdge1 = 1:nEdges-1 % create first edge edge1 = [poly(iEdge1, :) poly(iEdge1+1, :)]; for iEdge2 = iEdge1+2:nEdges % create second edge edge2 = [poly(iEdge2, :) poly(iEdge2+1, :)]; % check conditions on bounding boxes, to avoid computing the % intersections if min(edge1([1 3])) > max(edge2([1 3])) continue; end if max(edge1([1 3])) < min(edge2([1 3])) continue; end if min(edge1([2 4])) > max(edge2([2 4])) continue; end if max(edge1([2 4])) < min(edge2([2 4])) continue; end % compute intersection point inter = intersectEdges(edge1, edge2, tol); if sum(isfinite(inter)) == 2 % add point to the list ip = ip + 1; points(ip, :) = inter; % also compute positions on the polyline pos1(ip, 1) = iEdge1 - 1 + edgePosition(inter, edge1); pos2(ip, 1) = iEdge2 - 1 + edgePosition(inter, edge2); end end end %% Post-processing % if polyline is closed, the first vertex was found as an intersection, so % we need to remove it if closed % identify the intersection between first and last edges using position % indices (pos1 < pos2 by construction) ind = pos1 == 0 & pos2 == size(poly,1)-1; points(ind,:) = []; pos1(ind) = []; pos2(ind) = []; end % remove multiple intersections [points, I, J] = unique(points, 'rows', 'first'); %#ok pos1 = pos1(I); pos2 = pos2(I); % remove multiple intersections, using tolerance on distance iInter = 0; while iInter < size(points, 1) - 1 iInter = iInter + 1; % for iInter = 1:size(points, 1)-1 % determine distance between current point and remaining points inds = iInter+1:size(points, 1); dists = distancePoints(points(iInter,:), points(inds, :)); % identify index of other points located in a close neighborhood inds = inds(dists < tol); % remove redundant intersection points if ~isempty(inds) points(inds, :) = []; pos1(inds) = []; pos2(inds) = []; end end %% process output arguments if nargout <= 1 varargout{1} = points; elseif nargout == 3 varargout{1} = points; varargout{2} = pos1; varargout{3} = pos2; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/signatureToPolygon.m0000644000000000000000000000013214576357161021353 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/signatureToPolygon.m0000644000175000017500000000505114576357161023134 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly = signatureToPolygon(signature, varargin) %SIGNATURETOPOLYGON Reconstruct a polygon from its polar signature. % % POLY = signatureToPolygon(SIGNATURE) % POLY = signatureToPolygon(SIGNATURE, ANGLES) % % Example % signatureToPolygon % % See also % polygonSignature % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-04-28, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform nAngles = length(signature); % compute default signature angleList = linspace(0, 360, nAngles+1); angleList(end) = []; if ~isempty(varargin) angleList = varargin{1}; if length(angleList) ~= nAngles msg = 'signature and angle list must have same length (here %d and %d)'; error(sprintf(msg, nAngles, length(angleList))); %#ok end end poly = zeros(nAngles, 2); for iAngle = 1:nAngles angle = angleList(iAngle); poly(iAngle, :) = signature(iAngle) * [cosd(angle) sind(angle)]; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/convexification.m0000644000000000000000000000013214576357161020667 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/convexification.m0000644000175000017500000000667314576357161022463 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function co = convexification(varargin) %CONVEXIFICATION Compute the convexification of a polygon. % % CO = convexification(H) % Creates convexification from support function. Support function is % supposed to be uniformly distributed over [0 2pi]. % % CO = convexification(POLYGON) % Computes support function of the polygon, then the corresponding % convexification. % % CO = convexification(POLYGON, N) % Uses N points for convexification computation. Note that the number of % points of CO can be lower than N. % % CAUTION: The result will be valid only for convex polygons. % % See also % polygons2d, supportFunction % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-01-12 % Copyright 2005-2023 INRA - Cepia Software Platform if ~isempty(varargin)>0 var = varargin{1}; if size(var, 2)==1 h = var; else poly = var; N = 128; if length(varargin)>1 N = varargin{2}; end h = supportFunction(poly, N); end else error('not enough input arguments'); end N = length(h); u = (0:2*pi/N:2*pi*(1-1/N))'; v = [cos(u) sin(u)].*[h h]; i1 = 1:N; i2 = [2:N 1]; i3 = [3:N 1 2]; circ = zeros(N, 4); for i=1:N circ(i, 1:4) = createDirectedCircle(v(i1(i),:), v(i2(i),:), v(i3(i), :)); end % remove non direct-oriented circles circ = circ(circ(:,4)==0, :); % keep only circles seen several times dp = diff(circ(:,1:2)); dp = sum(dp.*dp, 2); ind1 = [1; find(dp<1e-10)+1]; circ = circ(ind1, :); % keep only one instance of each circle dp = diff(circ(:,1:2)); dp = sum(dp.*dp, 2); ind = [1; find(dp>1e-10)+1]; co = 2*circ(ind, 1:2); % eventually remove the last point if it is the same as the first one if distancePoints(co(1,:), co(end, :))<1e-10 && size(co, 1)>1 co = co(1:end-1,:); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonBounds.m0000644000000000000000000000013214576357161020341 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonBounds.m0000644000175000017500000000541514576357161022126 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function box = polygonBounds(polygon) %POLYGONBOUNDS Computes the bounding box of a polygon. % % BOX = polygonBounds(POLY); % Returns the bounding box of the polygon. % BOX has the format: [XMIN XMAX YMIN YMAX]. % % Input polygon POLY is as a N-by-2 array containing coordinates of each % vertex. % Multiple polygons can be specified either by inserting NaN rows between % vertex coordinates, or by using a cell array, each cell containing the % vertex coordinates of a polygon loop. % % See also % polygons2d, boxes2d, boundingBox % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-12, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - Cepia software platform % transform as a cell array of simple polygons polygons = splitPolygons(polygon); % init extreme values xmin = inf; xmax = -inf; ymin = inf; ymax = -inf; % iterate over loops for i = 1:length(polygons) polygon = polygons{i}; xmin = min(xmin, min(polygon(:,1))); xmax = max(xmax, max(polygon(:,1))); ymin = min(ymin, min(polygon(:,2))); ymax = max(ymax, max(polygon(:,2))); end % format output box = [xmin xmax ymin ymax]; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polylineLength.m0000644000000000000000000000013214576357161020474 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polylineLength.m0000644000175000017500000000701514576357161022257 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function len = polylineLength(poly, varargin) %POLYLINELENGTH Return length of a polyline given as a list of points. % % L = polylineLength(POLY); % POLY should be a N-by-D array, where N is the number of points and D is % the dimension of the points. % % L = polylineLength(..., TYPE); % Specifies if the last point is connected to the first one. TYPE can be % either 'closed' or 'open'. % % L = polylineLength(POLY, POS); % Compute the length of the polyline between its origin and the position % given by POS. POS should be between 0 and N-1, where N is the number of % points of the polyline. % % % Example: % % Compute the perimeter of a circle with radius 1 % polylineLength(circleAsPolygon([0 0 1], 500), 'closed') % ans = % 6.2831 % % See also % polygons2d, polylineCentroid, polygonLength % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % check there are enough points if size(poly, 1) < 2 len = 0; return; end % check whether the curve is closed or not (default is open) closed = false; if ~isempty(varargin) var = varargin{end}; if ischar(var) if strcmpi(var, 'closed') closed = true; end varargin = varargin(1:end-1); end end % if the length is computed between 2 positions, compute only for a % subcurve if ~isempty(varargin) % values for 1 input argument t0 = 0; t1 = varargin{1}; % values for 2 input arguments if length(varargin)>1 t0 = varargin{1}; t1 = varargin{2}; end % extract a portion of the polyline poly = polylineSubcurve(poly, t0, t1); end % compute lengths of each line segment, and sum up if closed len = sum(sqrt(sum(diff(poly([1:end 1],:)).^2, 2))); else len = sum(sqrt(sum(diff(poly).^2, 2))); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/cart2geod.m0000644000000000000000000000013214576357161017351 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/cart2geod.m0000644000175000017500000000527214576357161021137 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = cart2geod(src, curve) %CART2GEOD Convert cartesian coordinates to geodesic coord. % % PT2 = cart2geod(PT1, CURVE) % PT1 is the point to transform, in Cartesian coordinates (same system % used for the curve). % CURVE is a N-by-2 array which represents coordinates of curve vertices. % % The function first compute the projection of PT1 on the curve. Then, % the first geodesic coordinate is the length of the curve to the % projected point, and the second geodesic coordinate is the % distance between PT1 and it projection. % % % See also % polylines2d, geod2cart, curveLength % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-04-08 % Copyright 2004-2023 INRA - Cepia Software Platform % parametrization approximation t = parametrize(curve); % compute distance between each src point and the curve [dist, ind] = minDistancePoints(src, curve); % convert to 'geodesic' coordinate point = [t(ind) dist]; % Old version: % for i=1:size(pt1, 1) % [dist, ind] = minDistance(src(i,:), curve); % point(i,:) = [t(ind) dist]; % end matgeom-1.2.4/inst/polygons2d/PaxHeaders/fillPolygon.m0000644000000000000000000000013214576357161017775 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/fillPolygon.m0000644000175000017500000000650714576357161021565 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = fillPolygon(varargin) %FILLPOLYGON Fill a polygon specified by a list of points. % % fillPolygon(POLY); % Fills the interior of the polygon specified by POLY. The boundary of % the polygon is not drawn, see 'drawPolygon' to do it. % POLY is a single [N*2] array. % If POLY contains NaN-couples, each portion between the [NaN;NaN] will % be filled separately. % % fillPolygon(PX, PY); % Specifies coordinates of the polygon in separate arrays. % % H = fillPolygon(...); % Also returns a handle to the created patch % % Example % oRectangle = [0 0;10 0;10 10;0 10]; % iRectangle = flipud(0.5*oRectangle+1); % pol = {oRectangle, iRectangle}; % figure('color','w') % fillPolygon(pol,'g') % drawPolygon(pol,'r') % % % See also % polygons2d, drawCurve, drawPolygon % ------ % Author: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2005-04-07 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % Check input if isempty(varargin) error('Not enough input arguments.'); end % Check if the polygon is given in two separate arrays. if numel(varargin) > 1 if isnumeric(varargin{2}) varargin{2} = [varargin{1}, varargin{2}]; varargin(1)=[]; end end % Convert into a polyShape polyShape = parsePolygon(varargin{1}, 'polyshape'); varargin(1)=[]; % Set default color format if no color is given. if isempty(varargin) varargin = {'FaceColor', 'b'}; end if ~mod(numel(varargin), 2) == 0 % Assume only the color was given. varargin = ['FaceColor', varargin]; end % Fill the polygon with desired style. h = plot(polyShape, varargin{:}, 'LineStyle', 'none'); % Output if nargout > 0 varargout{1} = h; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polylineCentroid.m0000644000000000000000000000013214576357161021022 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polylineCentroid.m0000644000175000017500000000661514576357161022612 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function center = polylineCentroid(varargin) %POLYLINECENTROID Computes the centroid of a curve defined by a series of points. % % PT = polylineCentroid(POINTS); % Computes center of mass of a polyline defined by POINTS. POINTS is a % N-by-D array of double, representing a set of N points in a % D-dimensional space. % % PT = polylineCentroid(PTX, PTY); % PT = polylineCentroid(PTX, PTY, PTZ); % Specifies points as separate column vectors % % PT = polylineCentroid(..., TYPE); % Specifies if the last point is connected to the first one. TYPE can be % either 'closed' or 'open'. % % Example % poly = [0 0;10 0;10 10;20 10]; % polylineCentroid(poly) % ans = % [10 5] % % See also % polygons2d, centroid, polygonCentroid, polylineLength % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-05-22 % Copyright 2006-2023 INRA - TPV URPOI - BIA IMASTE %% process input arguments % check whether the curve is closed closed = false; var = varargin{end}; if ischar(var) if strcmpi(var, 'closed') closed = true; end % remove last argument varargin(end) = []; end % extract point coordinates if length(varargin)==1 points = varargin{1}; elseif length(varargin)==2 points = [varargin{1} varargin{2}]; end %% Main computation % compute centers and lengths composing the curve if closed centers = (points + points([2:end 1],:))/2; lengths = sqrt(sum(diff(points([1:end 1],:)).^2, 2)); else centers = (points(1:end-1,:) + points(2:end,:))/2; lengths = sqrt(sum(diff(points).^2, 2)); end % centroid of edge centers weighted by edge length %weigths = repmat(lengths/sum(lengths), [1 size(points, 2)]); center = sum(centers .* repmat(lengths, [1 size(points, 2)]), 1) / sum(lengths); matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonPoint.m0000644000000000000000000000013214576357161020200 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonPoint.m0000644000175000017500000000563514576357161021771 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = polygonPoint(poly, pos) %POLYGONPOINT Extract a point from a polygon. % % POINT = polygonPoint(POLYGON, POS) % % % Example % polygonPoint % % See also % polygons2d, polylinePoint % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % eventually copy first point at the end to ensure closed polygon if sum(poly(end, :) == poly(1,:))~=2 poly = [poly; poly(1,:)]; end % number of points to compute nPoints = length(pos(:)); % number of vertices in polygon Nv = size(poly, 1)-1; % allocate memory results point = zeros(nPoints, 2); % iterate on points for i = 1:nPoints % compute index of edge (between 0 and Nv) ind = floor(pos(i)); % special case of last point of polyline if ind==Nv point(i,:) = poly(end,:); continue; end % format index to ensure being on polygon ind = min(max(ind, 0), Nv-1); % position on current edge t = min(max(pos(i)-ind, 0), 1); % parameters of current edge x0 = poly(ind+1, 1); y0 = poly(ind+1, 2); dx = poly(ind+2,1)-x0; dy = poly(ind+2,2)-y0; % compute position of current point point(i, :) = [x0+t*dx, y0+t*dy]; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/drawPolygon.m0000644000000000000000000000013214576357161020004 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/drawPolygon.m0000644000175000017500000001226114576357161021566 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawPolygon (px, varargin) %DRAWPOLYGON Draw a polygon specified by a list of points. % % drawPolygon(POLY); % Packs coordinates in a single N-by-2 array, with N the vertex number. % % drawPolygon(PX, PY); % Specifies coordinates in separate arrays. Both array must be N-by-1, % with N the number of vertices. % % drawPolygon(POLYS) % Packs coordinate of several polygons in a cell array. Each element of % the array is a Ni-by-2 double array. % % drawPolygon(..., NAME, VALUE); % Specifies drawing options by using one or several parameter name-value % pairs, see the doc of plot function for details. % % drawPolygon(AX, ...) % Specifies the axis to draw the polygon on. % % H = drawPolygon(...); % Also return a handle to the list of line objects. % % Example % % draw a red rectangle % poly = [10 10;40 10;40 30;10 30]; % figure; drawPolygon(poly, 'r'); % axis equal; axis([0 50 0 50]); % % % Draw two squares % px = [10 20 20 10 NaN 30 40 40 30]'; % py = [10 10 20 20 NaN 10 10 20 20]'; % figure; % drawPolygon([px py], 'lineWidth', 2); % axis equal; axis([0 50 0 50]); % % See also % polygons2d, drawPolyline % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-05-05 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % Store hold state state = ishold(gca); hold on; %% Check input if nargin < 1 error ('should specify at least one argument'); end % check for empty polygons if isempty (px) return end % extract handle of axis to draw on ax = gca; if isAxisHandle(px) ax = px; px = varargin{1}; varargin(1) = []; end %% Manage cell arrays of polygons % case of a set of polygons stored in a cell array if iscell(px) h = cellfun(@(x) drawPolygon(ax, x, varargin{:}), px, 'UniformOutput', 0); h = horzcat(h{:}); else % Check size vs number of arguments if size(px, 2) == 2 % Case of polygon specified as a N-by-2 array (most standard case) py = px(:, 2); px = px(:, 1); elseif size(px, 2) == 1 % Case of polygon specified as two N-by-1 arrays with same length if nargin < 2 || nargin == 2 && ~isnumeric(varargin{1}) error('Matgeom:invalid_input_arg', ... 'Should specify either a N-by-2 array, or 2 N-by-1 vectors'); end % Extract coordinates of polygon vertices py = varargin{1}; varargin(1) = []; if length(py) ~= length(px) error('Matgeom:invalid_input_arg', ... 'X and Y coordinate arrays should have same lengths (%d,%d)', ... length(px), length(py)) end else error('Matgeom:invalid_input_arg', 'Should specify a N-by-2 array'); end % set default line format if isempty (varargin) varargin = {'b-'}; end % Check case of polygons with holes if any (isnan (px(:)) ) polygons = splitPolygons ([px py]); h = drawPolygon (ax, polygons, varargin{:}); else % ensure last point is the same as the first one px(end+1, :) = px(1,:); py(end+1, :) = py(1,:); % draw the polygon outline h = plot(ax, px, py, varargin{:}); end % whether there where holes end % whether input arg was a cell if ~state hold off end % avoid returning argument if not required if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/Contents.m0000644000000000000000000000013214576357161017274 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/Contents.m0000644000175000017500000002650514576357161021064 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. %CONTENTS POLYGONS Manipulation of planar polygons and polylines. % Version 1.24 07-Jun-2018 . % % The 'polygons' module contains functions operating on shapes composed % of a vertex list, like polygons or polylines. % % We call 'polyline' the curve defined by a series of vertices. % A polyline can be either closed or open, depending on whether the last % vertex is connected to the first one or not. This can be given as an % option is some functions in the module. % A 'polygon' is the planar domain delimited by a closed polyline. We % sometimes want to consider 'complex polygons', whose boundary is % composed of several disjoint domains. The domain defined by a single % closed polyline is called 'simple polygon'. % We call 'curve' a polyline with many vertices, such that the polyline % can be considered as a discrete approximation of a "real" curve. % % A simple polygon or polyline is represented by a N-by-2 array, each row % of the array representing the coordinates of a vertex. % Simple polygons are assumed to be closed, so there is no need to repeat % the first vertex at the end. % As both polygons and polylines can be represented by a list of vertex % coordinates, some functions also consider the vertex list itself. Such % functions are prefixed by 'pointSet'. Also, many functions prefixed by % 'polygon' or 'polyline' works also on the other type of shape. % % For multiple-connected polygons, the different connected boundaries are % separated by a row [NaN NaN]. % % For some functions, the orientation of the polygon can be relevant: CCW % stands for 'Conter-Clockwise' (positive orientation), CW stands for % 'Clockwise'. % % Polylines are parametrized in the following way: % * the i-th vertex is located at position i-1 % * points of the i-th edge have positions ranging linearly from i-1 to i % The parametrization domain for an open polyline is from 0 to Nv-1, and % from 0 to Nv for a closed polyline (positions 0 and Nv correspond to % the same point). % % Example: % % Simple polygon: % P1 = [1 1;2 1;2 2;1 2]; % drawPolygon(P1); % axis([0 5 0 5]); % % Multiple polygon: % P2 = [10 10;40 10;40 40;10 40;NaN NaN;20 20;20 30;30 30;30 20]; % figure; drawPolygon(P2); axis([0 50 0 50]); % % % Polylines % polylinePoint - Extract a point from a polyline. % polylineLength - Return length of a polyline given as a list of points. % polylineCentroid - Computes the centroid of a curve defined by a series of points. % polylineSubcurve - Extract a portion of a polyline. % resamplePolyline - Distribute N points equally spaced on a polyline. % resamplePolylineByLength - Resample a polyline with a fixed sampling step. % reversePolyline - Reverse a polyline, by iterating vertices from the end. % isPointOnPolyline - Test if a point belongs to a polyline. % projPointOnPolyline - Compute position of a point projected on a polyline. % distancePointPolyline - Compute shortest distance between a point and a polyline. % distancePolylines - Compute the shortest distance between 2 polylines. % intersectLinePolyline - Intersection points between a line and a polyline. % intersectPolylines - Find the common points between 2 polylines. % clipPolyline - Clip an open polyline with a rectangular box. % polylineSelfIntersections - Find self-intersection points of a polyline. % simplifyPolyline - Douglas-Peucker simplification of a polyline. % smoothPolyline - Smooth a polyline using local averaging. % polylineCurvature - Estimate curvature on polyline vertices using polynomial fit. % removeMultipleVertices - Remove multiple vertices of a polygon or polyline. % padPolyline - Add vertices at each extremity of the polyline. % % Polygon basic manipulation % reversePolygon - Reverse a polygon, by iterating vertices from the end. % smoothPolygon - Smooth a polygon using local averaging. % simplifyPolygon - Douglas-Peucker simplification of a polygon. % projPointOnPolygon - Compute position of a point projected on a polygon. % splitPolygons - Convert a NaN separated polygon list to a cell array of polygons. % polygonLoops - Divide a possibly self-intersecting polygon into a set of simple loops. % polygonPoint - Extract a point from a polygon. % polygonSubcurve - Extract a portion of a polygon. % polygonEdges - Return the edges of a simple or multiple polygon. % polygonVertices - Extract all vertices of a (multi-)polygon. % % Polygon clipping and intersections % intersectLinePolygon - Intersection points between a line and a polygon. % intersectRayPolygon - Intersection points between a ray and a polygon. % intersectEdgePolygon - Intersection point of an edge with a polygon. % polygonSelfIntersections - Find self-intersection points of a polygon. % clipPolygon - Clip a polygon with a rectangular box. % clipPolygonByLine - Clip a polygon with a directed line. % % Point Sets % pointSetsAverage - Compute the average of several point sets. % minimumCaliperDiameter - Minimum caliper diameter of a set of points. % findPoint - Find index of a point in an set from its coordinates. % convexHull - Convex hull of a set of points. % randomPointInPolygon - Generate random point(s) in a polygon. % % Measures on Polygons % isPointInPolygon - Test if a point is located inside a polygon. % polygonContains - Test if a point is contained in a multiply connected polygon. % polygonCentroid - Computes the centroid (center of mass) of a polygon. % polygonArea - Compute the signed area of a polygon. % polygonEquivalentEllipse - Compute equivalent ellipse with same second order moments as polygon. % polygonSecondAreaMoments - Compute second-order area moments of a polygon. % polygonLength - Perimeter of a polygon. % polygonNormalAngle - Normal angle at each vertex of a polygon. % polygonBounds - Computes the bounding box of a polygon. % polygonOuterNormal - Outer normal vector for a given vertex(ices). % distancePointPolygon - Shortest distance between a point and a polygon. % distancePolygons - Compute the shortest distance between 2 polygons. % distancePolygonsNoCross - Compute the shortest distance between 2 polygons. % polygonSignature - Polar signature of a polygon (polar distance to origin). % signatureToPolygon - Reconstruct a polygon from its polar signature. % polygonCurvature - Estimate curvature on polygon vertices using polynomial fit. % % More complex operations on polygons % resamplePolygon - Distribute N points equally spaced on a polygon. % resamplePolygonByLength - Resample a polygon with a fixed sampling step. % densifyPolygon - Add several points on each edge of the polygon. % expandPolygon - Expand a polygon by a given (signed) distance. % triangulatePolygon - Computes a triangulation of the input polygon. % polygonSymmetryAxis - Try to identify symmetry axis of polygon. % polygonSkeleton - Skeletonization of a polygon with a dense distribution of vertices. % medialAxisConvex - Compute medial axis of a convex polygon. % % Curves (polylines with lot of vertices) % parametrize - Parametrization of a polyline, based on edges lengths. % curvature - Estimate curvature of a polyline defined by points. % cart2geod - Convert cartesian coordinates to geodesic coord. % geod2cart - Convert geodesic coordinates to cartesian coord. % curveMoment - Compute inertia moment of a 2D curve. % curveCMoment - Compute centered inertia moment of a 2D curve. % curveCSMoment - Compute centered scaled moment of a 2D curve. % % Functions from stochastic geometry % steinerPoint - Compute steiner point (weighted centroid) of a polygon. % steinerPolygon - Create a Steiner polygon from a set of vectors. % supportFunction - Compute support function of a polygon. % convexification - Compute the convexification of a polygon. % % Input, Output and conversions % contourMatrixToPolylines - Converts a contour matrix array into a polyline set. % parsePolygon - Conversion between different polygon formats. % polygonToPolyshape - Convert a matGeom polygon to a MATLAB polyshape object. % polygonToRow - Convert polygon coordinates to a row vector. % rowToPolygon - Create a polygon from a row vector. % readPolygonSet - Read a set of simple polygons stored in a file. % writePolygonSet - Write a set of simple polygons into a file. % % Drawing functions % drawPolyline - Draw a polyline specified by a list of points. % drawPolygon - Draw a polygon specified by a list of points. % fillPolygon - Fill a polygon specified by a list of points. % drawVertices - Draw the vertices of a polygon or polyline. % % % Credits: % * function intersectPolylines uses the 'interX' contribution from "NS" % (file exchange 22441, called 'curve-intersections') % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-07 % Copyright 2005-2023 INRAE help(mfilename); matgeom-1.2.4/inst/polygons2d/PaxHeaders/steinerPolygon.m0000644000000000000000000000013214576357161020520 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/steinerPolygon.m0000644000175000017500000000440414576357161022302 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function nodes = steinerPolygon(points) %STEINERPOLYGON Create a Steiner polygon from a set of vectors. % % NODES = steinerPolygon(VECTORS); % Builds the (convex) polygon which contains an edge for each one of the % vectors given by VECTORS. % % Example % n = steinerPolygon([1 0;0 1;1 1]); % drawPolygon(n); % % See also % polygons2d, drawPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-04-28 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) nodes = [0 0]; for i=1:length(points) nodes = [nodes; nodes+repmat(points(i,:), [size(nodes, 1) 1])]; %#ok end K = convhull(nodes(:,1), nodes(:,2)); nodes = nodes(K, :); matgeom-1.2.4/inst/polygons2d/PaxHeaders/simplifyPolyline.m0000644000000000000000000000013214576357161021047 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/simplifyPolyline.m0000644000175000017500000000762514576357161022641 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [poly2, keepInds] = simplifyPolyline(poly, tol) %SIMPLIFYPOLYLINE Douglas-Peucker simplification of a polyline. % % POLY2 = simplifyPolyline(POLY, TOL) % Simplifies the input polyline using the Douglas-Peucker algorithm. % % Example % elli = [20 30 40 20 30]; % poly = ellipseToPolygon(elli, 500); % poly2 = simplifyPolyline(poly, 1); % use a tolerance equal to 1 % figure; hold on; % drawEllipse(elli); % drawPoint(poly2, 'mo'); % % See also % polygons2d, simplifyPolygon, resamplePolyline, smoothPolyline % % References % http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-05-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % number of vertices n = size(poly, 1); % initial call to the recursive function keepInds = recurseSimplify(1, n); % keep first and last vertices keepInds = [1 keepInds n]; % create the resulting polyline poly2 = poly(keepInds, :); %% Inner function that is called recursively on polyline portions function innerInds = recurseSimplify(i0, i1) % find the furthest vertex mid = furthestPointIndex(i0, i1); % case of no further simplification if isempty(mid) innerInds = mid; return; end % recursively subdivide each portion mid1 = recurseSimplify(i0, mid); mid2 = recurseSimplify(mid, i1); % concatenate indices of all portions innerInds = [mid1 mid mid2]; end %% Inner function for finding index of furthest point in POLY function ind = furthestPointIndex(i0, i1) % for single edges, return empty result if i1 - i0 < 2 ind = []; return; end % vertices of the current edge v0 = poly(i0, :); v1 = poly(i1, :); % find vertex with the greatest distance dists = distancePointEdge(poly(i0+1:i1-1, :), [v0 v1]); [maxi, ind] = max(dists); % update index only if distance criterion is verified if maxi > tol ind = i0 + ind; else ind = []; end end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonToRow.m0000644000000000000000000000013214576357161020161 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonToRow.m0000644000175000017500000000574114576357161021750 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function row = polygonToRow(polygon, varargin) %POLYGONTOROW Convert polygon coordinates to a row vector. % % ROW = polygonToRow(POLY); % where POLY is a N-by-2 array of points representing vertices of the % polygon, converts the vertex coordinates into a linear array: % ROW = [X1 Y1 X2 Y2 .... XN YN] % % ROW = polygonToRow(POLY, TYPE); % Can coose another format for converting polygon. Possibilities are: % 'interlaced' (default}, as described above % 'packed': ROW has format [X1 X2 ... XN Y1 Y2 ... YN]. % % Example % square = [10 10 ; 20 10 ; 20 20 ; 10 20]; % row = polygonToRow(square) % row = % 10 10 20 10 20 20 10 20 % % % the same with different ordering % row = polygonToRow(square, 'packed') % row = % 10 20 20 10 10 10 20 20 % % % See also % polygons2d, rowToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % determines ordering type type = 'interlaced'; if ~isempty(varargin) type = varargin{1}; end if strcmp(type, 'interlaced') % ordering is [X1 Y1 X2 X2... XN YN] Np = size(polygon, 1); row = reshape(polygon', [1 2*Np]); elseif strcmp(type, 'packed') % ordering is [X1 X2 X3... XN Y1 Y2 Y3... YN] row = polygon(:)'; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/minimumCaliperDiameter.m0000644000000000000000000000013214576357161022125 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/minimumCaliperDiameter.m0000644000175000017500000001157414576357161023715 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [min_width, min_angle] = minimumCaliperDiameter(points) %MINIMUMCALIPERDIAMETER Minimum caliper diameter of a set of points. % % WIDTH = minimumCaliperDiameter(POINTS) % Computes the minimum width of a set of points. As polygons and % polylines are represented as point lists, this function works also for % polygons and polylines. % % [WIDTH THETA] = minimumCaliperDiameter(POINTS) % Also returns the direction of minimum width. The direction corresponds % to the horizontal angle of the edge that minimizes the width. THETA is % given in radians, between 0 and PI. % % % Example % % Compute minimal caliper diameter, and check coords of rotated points % % have expected extent % points = randn(30, 2); % [width theta] = minimumCaliperDiameter(points); % points2 = transformPoint(points, createRotation(-theta)); % diff = max(points2) - min(points2); % abs(width - diff(2)) < 1e-10 % ans = % 1 % % References % Algorithms use rotating caliper. Implementation was based on that of % Wikipedia: % http://en.wikipedia.org/wiki/Rotating_calipers % % See also % polygons2d, convexHull, orientedBox % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-04-08, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % first, compute convex hull of the polygon inds = convhull(points(:,1), points(:,2)); hull = points(inds, :); % if first and last points are the same, remove the last one if inds(1) == inds(end) hull = hull(1:end-1, :); end % number of hull vertices nV = size(hull, 1); % default values rotated_angle = 0; min_width = inf; min_angle = 0; % avoid degenerated cases if nV < 3 return; end [tmp, p_a] = min(hull(:, 2)); %#ok [tmp, p_b] = max(hull(:, 2)); %#ok caliper_a = [ 1 0]; % Caliper A points along the positive x-axis caliper_b = [-1 0]; % Caliper B points along the negative x-axis while rotated_angle < pi % compute the direction vectors corresponding to each edge ind_a2 = mod(p_a, nV) + 1; vector_a = hull(ind_a2, :) - hull(p_a, :); ind_b2 = mod(p_b, nV) + 1; vector_b = hull(ind_b2, :) - hull(p_b, :); % Determine the angle between each caliper and the next adjacent edge % in the polygon angle_a = vectorAngle(caliper_a, vector_a); angle_b = vectorAngle(caliper_b, vector_b); % Determine the smallest of these angles minAngle = min(angle_a, angle_b); % Rotate the calipers by the smallest angle caliper_a = rotateVector(caliper_a, minAngle); caliper_b = rotateVector(caliper_b, minAngle); rotated_angle = rotated_angle + minAngle; % compute current width, and update opposite vertex if angle_a < angle_b line = createLine(hull(p_a, :), hull(ind_a2, :)); width = distancePointLine(hull(p_b, :), line); p_a = mod(p_a, nV) + 1; else line = createLine(hull(p_b, :), hull(ind_b2, :)); width = distancePointLine(hull(p_a, :), line); p_b = mod(p_b, nV) + 1; end % update minimum width and corresponding angle if needed if width < min_width min_width = width; min_angle = rotated_angle; end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/medialAxisConvex.m0000644000000000000000000000013214576357161020742 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/medialAxisConvex.m0000644000175000017500000001331514576357161022525 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges] = medialAxisConvex(points) %MEDIALAXISCONVEX Compute medial axis of a convex polygon. % % [N, E] = medialAxisConvex(POLYGON); % where POLYGON is given as a set of points [x1 y1;x2 y2 ...], returns % the medial axis of the polygon as a graph. % N is a set of nodes. The first elements of N are the vertices of the % original polygon. % E is a set of edges, containing indices of source and target nodes. % Edges are sorted according to order of creation. Index of first vertex % is lower than index of last vertex, i.e. edges always point to newly % created nodes. % % Notes: % - Is not fully implemented, need more development (usually crashes for % polygons with more than 6-7 points...) % - Works only for convex polygons. % - Complexity is not optimal: this algorithm is O(n*log n), but linear % algorithms exist. % % See also % polygons2d, bisector % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-07-07 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE % eventually remove the last point if it is the same as the first one if points(1,:) == points(end, :) nodes = points(1:end-1, :); else nodes = points; end % special case of triangles: % compute directly the gravity center, and simplify computation. if size(nodes, 1)==3 nodes = [nodes; mean(nodes, 1)]; edges = [1 4;2 4;3 4]; return end % number of nodes, and also of initial rays N = size(nodes, 1); % create ray of each vertex rays = zeros(N, 4); rays(1, 1:4) = bisector(nodes([2 1 N], :)); rays(N, 1:4) = bisector(nodes([1 N N-1], :)); for i=2:N-1 rays(i, 1:4) = bisector(nodes([i+1, i, i-1], :)); end % add indices of edges producing rays (indices of first vertex, second % vertex is obtained by adding one modulo N). rayEdges = [[N (1:N-1)]' (1:N)']; pint = intersectLines(rays, rays([2:N 1], :)); % compute the distance between each intersection point and the closest % edge. This distance is used as marker to propagate processing front. ti = zeros(N, 1); for i = 1:N line = createLine(points(mod(i-2, N)+1, :), points(i, :)); ti(i) = abs(distancePointLine(pint(i,:), line)); end % create list of events. % terms are : R1 R2 X Y t0 % R1 and R2 are indices of involved rays % X and Y is coordinate of intersection point % t0 is position of point on rays events = sortrows([ (1:N)' [2:N 1]' pint ti], 5); % initialize edges edges = zeros(0, 2); %% process each event until there is no more % start after index of last vertex, and process N-3 intermediate rays for i = N+1:2*N-3 % add new node at the rays intersection nodes(i,:) = events(1, 3:4); % add new couple of edges edges = [edges; events(1,1) i; events(1,2) i]; %#ok % find the two edges creating the new emanating ray n1 = rayEdges(events(1, 1), 1); n2 = rayEdges(events(1, 2), 2); % create the new ray line1 = createLine(nodes(n1, :), nodes(mod(n1,N)+1, :)); line2 = createLine(nodes(mod(n2,N)+1, :), nodes(n2, :)); ray0 = bisector(line1, line2); % set its origin to emanating point ray0(1:2) = nodes(i, :); % add the new ray to the list rays = [rays; ray0]; %#ok rayEdges(size(rayEdges, 1)+1, 1:2) = [n1 n2]; % find the two neighbour rays ind = sum(ismember(events(:,1:2), events(1, 1:2)), 2) ~= 0; ir = unique(events(ind, 1:2)); ir = ir(~ismember(ir, events(1,1:2))); % create new intersections pint = intersectLines(ray0, rays(ir, :)); ti = abs(distancePointLine(pint, line1)); % remove all events involving old intersected rays ind = sum(ismember(events(:,1:2), events(1, 1:2)), 2) == 0; events = events(ind, :); % add the newly formed events events = [events; ir(1) i pint(1,:) ti(1); ir(2) i pint(2,:) ti(2)]; %#ok % and sort them according to 'position' parameter events = sortrows(events, 5); end % centroid computation for last 3 rays nodes = [nodes; mean(events(:, 3:4))]; edges = [edges; [unique(events(:,1:2)) ones(3, 1)*(2*N-2)]]; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonEquivalentEllipse.m0000644000000000000000000000013214576357161022542 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonEquivalentEllipse.m0000644000175000017500000000671114576357161024327 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function elli = polygonEquivalentEllipse(poly) %POLYGONEQUIVALENTELLIPSE Compute equivalent ellipse with same second order moments as polygon. % % ELLI = polygonEquivalentEllipse(POLY) % % Example % % convert an ellipse to polygon, and check that it equivalent ellipse % is close to original ellipse % elli = [50 50 50 30 20]; % poly = ellipseToPolygon(elli, 1000); % polygonEquivalentEllipse(poly) % ans = % 50.0000 50.0000 49.9998 29.9999 20.0000 % % % compute equivalent ellipse of more complex figure % img = imread('circles.png'); % img = imfill(img, 'holes'); % figure; imshow(img); hold on; % B = bwboundaries(img); % poly = B{1}(:,[2 1]); % drawPolygon(poly, 'r'); % elli = polygonEquivalentEllipse(poly); % drawEllipse(elli, 'color', 'g', 'linewidth', 2); % % % See also % polygons2d, polygonSecondAreaMoments, polygonCentroid, % equivalentEllipse, ellipseToPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-09-08, using Matlab 9.1.0.441655 (R2016b) % Copyright 2017-2023 INRA - Cepia Software Platform % first re-center the polygon centroid = polygonCentroid(poly); poly = bsxfun(@minus, poly, centroid); % compute non-normalized inertia moments [Ix, Iy, Ixy] = polygonSecondAreaMoments(poly); % normalize with polygon area area = polygonArea(poly); Ix = Ix / area; Iy = Iy / area; Ixy = Ixy / area; % compute ellipse semi-axis lengths common = sqrt((Ix - Iy)^2 + 4 * Ixy^2); ra = sqrt(2) * sqrt(Ix + Iy + common); rb = sqrt(2) * sqrt(Ix + Iy - common); % compute ellipse angle and convert into degrees % (different formula from the equivalentEllipse function, as the definition % for Ix and Iy do not refer to same axes) theta = atan2(2 * Ixy, Iy - Ix) / 2; theta = theta * 180 / pi; % compute centroid and concatenate results into ellipse format elli = [centroid ra rb theta]; matgeom-1.2.4/inst/polygons2d/PaxHeaders/polylinePoint.m0000644000000000000000000000013214576357161020344 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polylinePoint.m0000644000175000017500000000610114576357161022122 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function point = polylinePoint(poly, pos) %POLYLINEPOINT Extract a point from a polyline. % % POINT = polylinePoint(POLYLINE, POS) % POLYLINE is a N*2 array containing coordinate of polyline vertices % POS is comprised between 0 (first point of polyline) and Nv-1 (last % point of the polyline). % % % Example % poly = [10 10;20 10;20 20;30 30]; % polylinePoint(poly, 0) % [10 10] % polylinePoint(poly, 3) % [30 30] % polylinePoint(poly, 1.4) % [20 14] % % % See also % polygons2d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % number of points to compute Np = length(pos(:)); % number of vertices in polyline Nv = size(poly, 1); % allocate memory results point = zeros(Np, 2); % iterate on points for i=1:Np % compute index of edge (between 0 and Nv) ind = floor(pos(i)); % special case of last point of polyline if ind==Nv-1 point(i,:) = poly(end,:); continue; end % format index to ensure being on polyline ind = min(max(ind, 0), Nv-2); % position on current edge t = min(max(pos(i)-ind, 0), 1); % parameters of current edge x0 = poly(ind+1, 1); y0 = poly(ind+1, 2); dx = poly(ind+2,1)-x0; dy = poly(ind+2,2)-y0; % compute position of current point point(i, :) = [x0+t*dx, y0+t*dy]; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/randomPointInPolygon.m0000644000000000000000000000013214576357161021630 xustar0030 mtime=1710874225.142193342 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/randomPointInPolygon.m0000644000175000017500000001021614576357161023410 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = randomPointInPolygon(poly, varargin) %RANDOMPOINTINPOLYGON Generate random point(s) in a polygon. % % POINT = randomPointInPolygon(POLY) % POINTS = randomPointInPolygon(POLY, NPTS) % Generate random point(s) within the specified polygon. If the number of % points is not specified, only one point is generated. % % POINT = randomPointInPolygon(POLY, NPTS, QRS) % Specifies a Quasi-random number generator QRS used to generate point. % coordinates (requires the statistics toolbox). % % Example % % generate an ellipse-like polygon, and fill it with points % elli = [50 50 50 30 30]; % poly = ellipseToPolygon(elli, 200); % pts = randomPointInPolygon(poly, 500); % figure; hold on; % drawPolygon(poly, 'k'); % drawPoint(pts, 'b.'); % axis equal; axis([0 100 0 100]); % % % use halton sequence to distribute points within the polygon % qrs = haltonset(2, 'Skip', 1e3, 'Leap', 1e2); % pts = randomPointInPolygon(poly, 500, qrs); % figure; hold on; % drawPolygon(poly, 'k'); % drawPoint(pts, 'b.'); % axis equal; axis([0 100 0 100]); % % See also % polygons2d, randomPointInBox, drawPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-08-28, using Matlab 9.1.0.441655 (R2016b) % Copyright 2017-2023 INRA - Cepia Software Platform % determine number of points to generate nPts = 1; if nargin > 1 nPts = varargin{1}; varargin(1) = []; end % if additional input arg is provided, use it as quasi-random generator stream = []; if ~isempty(varargin) stream = qrandstream(varargin{1}); end % polygon extreme coordinates box = polygonBounds(poly); xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % compute size of box boxSizeX = xmax - xmin; boxSizeY = ymax - ymin; % allocate memory for result points = zeros(nPts, 2); % contains indices of remaining points to process ind = (1:nPts)'; % iterate until all points have been sampled within the polygon if isempty(stream) % use default random number generator while ~isempty(ind) NI = length(ind); x = rand(NI, 1) * boxSizeX + xmin; y = rand(NI, 1) * boxSizeY + ymin; points(ind, :) = [x y]; ind = ind(~polygonContains(poly, points(ind, :))); end else % use specified quasi-random generator while ~isempty(ind) NI = length(ind); pts = qrand(stream, NI); x = pts(:, 1) * boxSizeX + xmin; y = pts(:, 2) * boxSizeY + ymin; points(ind, :) = [x y]; ind = ind(~polygonContains(poly, points(ind, :))); end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonSkeleton.m0000644000000000000000000000013214576357161020673 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.142193342 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonSkeleton.m0000644000175000017500000001442414576357161022460 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = polygonSkeleton(poly, varargin) %POLYGONSKELETON Skeletonization of a polygon with a dense distribution of vertices. % % [V, ADJ] = polygonSkeleton(POLY) % POLY is given as a N-by-2 array of polygon vertex coordinates. The % result is given a Nv-by-2 array of skeleton vertex coordinates, and an % adjacency list, as a NV-by-1 cell array. Each cell contains indices of % vertices adjacent to the vertex indexed by the cell. % % [V, ADJ, RAD] = polygonSkeleton(POLY) % Also returns the radius of each vertex, corresponding to the distance % between the vertex and the closest point of the original contour % polygon. % % SKEL = polygonSkeleton(POLY) % Concatenates the results in a struct SKEL with following fields: % * vertices the Nv-by-2 array of skeleton vertex coordinates % * adjList the adjacency list of each vertex, as a Nv-by-1 cell array. % * radius the Nv-by-1 array of radius for each vertex % % Example % % start from a binary shape % img = imread('circles.png'); % img = imFillHoles(img); % figure; imshow(img); hold on; % % compute a smooth contour % cntList = imContours(img); % cnts = smoothPolygon(cntList{1}, 5); % drawPolygon(cnts, 'g'); % % compute skeleton % [vertices, adjList] = polygonSkeleton(poly); % % convert adjacency list to an edge array % edges = adjacencyListToEdges(adjList); % % draw the skeleton graph % drawGraphEdges(vertices, edges); % % See also % graphs, adjacencyListToEdges % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-05-29, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Voronoi Diagram computation % Compute Voronoi Diagram, using polygon vertices as germs. [V, C] = voronoin(poly); % compute number of elements of each array nVertices = size(V, 1); nCells = size(C, 1); % Detection of the vertices located inside the contour insideFlag = inpolygon(V(:,1), V(:,2), poly(:,1), poly(:,2)); innerVertices = V(insideFlag, :); % indices of inner vertices indsInside = find(insideFlag); nInnerVertices = length(indsInside); % compute map between voronoi vertex indices and skeleton vertex indices. vertexIndexMap = zeros(nVertices, 1); for iVertex = 1:length(indsInside) vertexIndexMap(indsInside(iVertex)) = iVertex; end %% Compute the topology of the skeleton % % Compute the topology as a list of adjacent vertex indices for each vertex % inside the polygon. % Need to convert between voronoi indices and skeleton indices. % allocate adjacncy list adjList = cell(nInnerVertices, 1); vertexGermInds = zeros(nInnerVertices, 1); % iterate on voronoi cells to compute skeleton by linking adjacent vertices % (avoiding first cell which is located at infinity by convention) for iGerm = 2:nCells % vertices of current cell cellVertices = C{iGerm}; nCellVertices = length(cellVertices); % iterate on vertices of current cell for k = 1:nCellVertices % index of current voronoi vertex iVertex = cellVertices(k); % process only vertices within the contour if insideFlag(iVertex) == 0 continue; end % convert voronoi vertex index to skeleton vertex index indV1 = vertexIndexMap(iVertex); % update the reference germ associated to current skeleton vertex vertexGermInds(indV1) = iGerm; % compute indices of adjacent vertices (in cell) iPrev = cellVertices(mod(k - 2, nCellVertices) + 1); iNext = cellVertices(mod(k, nCellVertices) + 1); % keep only the neighbors within the polygon if insideFlag(iPrev) == 1 adjList{indV1} = [adjList{indV1} vertexIndexMap(iPrev)]; end if insideFlag(iNext) == 1 adjList{indV1} = [adjList{indV1} vertexIndexMap(iNext)]; end end end % cleanup to avoid duplicate indices for iVertex = 1:nInnerVertices adjList{iVertex} = unique(adjList{iVertex}); end %% Compute radius list % for each voronoi vertex inside the polygon, compute the distance to % original polygon. % Find indices of germs associated to each vertex. % By construction, each vertex is the circumcenter of three germs. radiusList = zeros(nInnerVertices, 1); for iVertex = 1:nInnerVertices radiusList(iVertex) = norm(poly(vertexGermInds(iVertex),:) - innerVertices(iVertex,:)); end %% Format output if nargout <= 1 % format output to a struct varargout{1} = struct('vertices', {innerVertices}, 'adjList', {adjList}, 'radius', {radiusList}); elseif nargout == 2 varargout = {innerVertices, adjList}; elseif nargout == 3 varargout = {innerVertices, adjList, radiusList}; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/distancePolygons.m0000644000000000000000000000013214576357161021024 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/distancePolygons.m0000644000175000017500000000572114576357161022611 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function dist = distancePolygons(poly1, poly2) %DISTANCEPOLYGONS Compute the shortest distance between 2 polygons. % % DIST = distancePolygons(POLY1, POLY2) % Computes the shortest distance between the boundaries of the two % polygons. Each polygon is given by a N-by-2 array containing the vertex % coordinates. % % In the case the two polygons are known not to intersect, the function % 'distancePolygonsNoCross' may be used more efficiently (no test for % crossing is done). % % Example % % Computes the distance between a square and a triangle % poly1 = [10 10;20 10;20 20;10 20]; % poly2 = [30 20;50 20;40 45]; % distancePolygons(poly1, poly2) % ans = % 10 % % See also % polygons2d, distancePolygonsNoCross, distancePolylines, % distancePointPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-17, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % cjeck if the two polygons intersect pts = intersectPolylines(poly1([1:end 1], :), poly2([1:end 1], :)); if size(pts, 1) > 0 dist = 0; return; end % compute distance of each vertex of a polygon to the other polygon dist1 = min(distancePointPolygon(poly1, poly2)); dist2 = min(distancePointPolygon(poly2, poly1)); % keep the minimum of the two distances dist = min(dist1, dist2); matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonLoops.m0000644000000000000000000000013214576357161020203 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonLoops.m0000644000175000017500000001363014576357161021766 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function loops = polygonLoops(poly, varargin) %POLYGONLOOPS Divide a possibly self-intersecting polygon into a set of simple loops. % % LOOPS = polygonLoops(POLYGON); % POLYGON is a polygone defined by a series of vertices, % LOOPS is a cell array of polygons, containing the same vertices of the % original polygon, but no loop self-intersect, and no couple of loops % intersect each other. % % Example: % poly = [0 0;0 10;20 10;20 20;10 20;10 0]; % loops = polygonLoops(poly); % figure(1); hold on; % drawPolygon(loops); % polygonArea(loops) % % See also % polygons2d, polygonSelfIntersections % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % tolerance for detecting two vertices as equal tol = 1e-14; % parse optional arguments while length(varargin) > 1 pname = varargin{1}; if ~ischar(pname) error('Expect optional arguments as name-value pairs'); end if strcmpi(pname, 'tolerance') tol = varargin{2}; else error(['Unknown parameter name: ' pname]); end varargin(1:2) = []; end %% Initialisations % compute intersections [inters, pos1, pos2] = polygonSelfIntersections(poly, 'tolerance', tol); % case of a polygon without self-intersection if isempty(inters) loops = {poly}; return; end % array for storing loops loops = cell(0, 1); % sort intersection points with respect to their position on the polygon [positions, order] = sortrows([pos1 pos2 ; pos2 pos1]); inters = [inters ; inters]; inters = inters(order, :); %% First loop % initialize the beginning of the loop pos0 = 0; loop = polygonSubcurve(poly, pos0, positions(1, 1)); loop(end, :) = inters(1,:); vertex = inters(1,:); % prepare iteration on positions pos = positions(1, 2); positions(1, :) = []; inters(1,:) = []; while true % index of next intersection point ind = find(positions(:,1) > pos, 1, 'first'); % if not index is found, the current loop is complete if isempty(ind) break; end % compute the portion of curve between the two intersection points portion = polygonSubcurve(poly, pos, positions(ind, 1)); % ensure extremities have been computed only once portion(1, :) = vertex; vertex = inters(ind, :); portion(end, :) = vertex; % add the current portion of curve loop = [loop; portion]; %#ok % update current position on the polygon pos = positions(ind, 2); % remove processed intersection positions(ind, :) = []; inters(ind,:) = []; end % append the last portion of curve loop = [loop ; polygonSubcurve(poly, pos, pos0)]; % remove redundant vertices loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = []; if sum(diff(loop([1 end], :)) == 0) == 2 loop(end, :) = []; end % add current loop to the list of loops loops{1} = loop; %% Other loops Nl = 1; while ~isempty(positions) % initialize the next loop loop = []; pos0 = positions(1, 2); pos = positions(1, 2); vertex = inters(1,:); while true % index of next intersection point ind = find(positions(:,1) > pos, 1, 'first'); % compute the portion of curve between the two intersection points portion = polygonSubcurve(poly, pos, positions(ind, 1)); % ensure extremities have been computed only once portion(1, :) = vertex; vertex = inters(ind, :); portion(end, :) = vertex; % append the current portion of curve loop = [loop ; portion]; %#ok % update current position on the polygon pos = positions(ind, 2); % remove processed intersection positions(ind, :) = []; inters(ind,:) = []; % if not found, current loop is processed if pos == pos0 break; end end % remove redundant vertices loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = []; %#ok if sum(diff(loop([1 end], :))==0) == 2 loop(end, :) = []; end % add current loop to the list of loops Nl = Nl + 1; loops{Nl} = loop; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/isPointInPolygon.m0000644000000000000000000000013214576357161020763 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/isPointInPolygon.m0000644000175000017500000000673014576357161022551 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isPointInPolygon(point, poly) %ISPOINTINPOLYGON Test if a point is located inside a polygon. % % B = isPointInPolygon(POINT, POLYGON) % Returns true if the point is located within the given polygon. % % This function is simply a wrapper for the function inpolygon, to avoid % decomposition of point and polygon coordinates. % % Example % pt1 = [30 20]; % pt2 = [30 5]; % poly = [10 10;50 10;50 50;10 50]; % isPointInPolygon([pt1;pt2], poly) % ans = % 1 % 0 % % poly = [0 0; 10 0;10 10;0 10;NaN NaN;3 3;3 7;7 7;7 3]; % pts = [5 1;5 4]; % isPointInPolygon(pts, poly); % ans = % 1 % 0 % % % See also % points2d, polygons2d, inpolygon, isPointInTriangle % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-19, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % In case of a multiple polygon, decompose into a set of contours, and % performs test for each contour if iscell(poly) || any(isnan(poly(:))) % transform as a cell array of simple polygons polygons = splitPolygons(poly); N = length(polygons); Np = size(point, 1); % compute orientation of polygon, and format to have Np*N matrix areas = zeros(N, 1); for i = 1:N areas(i) = polygonArea(polygons{i}); end ccw = areas > 0; ccw = repmat(ccw', Np, 1); % test if point inside each polygon in = false(size(point, 1), N); for i = 1:N poly = polygons{i}; in(:, i) = inpolygon(point(:,1), point(:,2), poly(:,1), poly(:,2)); end % count polygons containing point, weighted by polygon orientation b = sum(in.*(ccw==1) - in.*(ccw==0), 2) > 0; else % standard test for simple polygons b = inpolygon(point(:,1), point(:,2), poly(:,1), poly(:,2)); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/rowToPolygon.m0000644000000000000000000000013214576357161020161 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/rowToPolygon.m0000644000175000017500000000706114576357161021745 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly = rowToPolygon(row, varargin) %ROWTOPOLYGON Create a polygon from a row vector. % % POLY = rowToPolygon(ROW) % Convert a 1-by-2*N row vector that concatenates all polygon vertex % coordinates into a N-by-2 array of coordinates. % Default ordering of coordinates in ROW is: % [X1 Y1 X2 Y2 X3 Y3 .... XN YN]. % % POLY = rowToPolygon(ROW, METHOD) % Specifies the method for concatenating coordinates. METHOS is one of: % 'interlaced': default method, described above. % 'packed': the vector ROW has format: % [X1 X2 X3 ... XN Y1 Y2 Y3 ... YN]. % % POLYS = rowToPolygon(ROWS, ...) % When ROWS is a NP-by-NV array containing the vertex coordinates of NP % polygons, returns a 1-by-NP cell array containing in each cell the % coordinates of the polygon. % % % Example % % Concatenate coordinates of a circle and draw it as a polygon % t = linspace (0, 2*pi, 200); % row = [cos(t) sin(t)]; % poly = rowToPolygon(row, 'packed'); % figure;drawPolygon(poly) % % See also % polygons2d, polygonToRow % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform type = 'interlaced'; if ~isempty(varargin) type = varargin{1}; end % number of polygons nPolys = size(row, 1); % polygon vertex number Np = size(row, 2) / 2; if strcmp(type, 'interlaced') % ordering is [X1 Y1 X2 X2... XN YN] if nPolys == 1 poly = reshape(row, [2 Np])'; else poly = cell(1, nPolys); for i = 1:nPolys poly{i} = reshape(row(i,:), [2 Np])'; end end elseif strcmp(type, 'packed') % ordering is [X1 X2 X3... XN Y1 Y2 Y3... YN] if nPolys == 1 poly = [row(1:Np)' row(Np+1:end)']; else poly = cell(1, nPolys); for i = 1:nPolys poly{i} = [row(i, 1:Np)' row(i, Np+1:end)']; end end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/private0000644000000000000000000000013214576357160016715 xustar0030 mtime=1710874224.518193937 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/private/0000755000175000017500000000000014576357160020552 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/polygons2d/private/PaxHeaders/InterX.m0000644000000000000000000000013214576357161020362 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/private/InterX.m0000644000175000017500000001207614576357161022150 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function P = InterX(L1,varargin) %INTERX Intersection of curves. % P = INTERX(L1,L2) returns the intersection points of two curves L1 % and L2. The curves L1,L2 can be either closed or open and are described % by two-row-matrices, where each row contains its x- and y- coordinates. % The intersection of groups of curves (e.g. contour lines, multiply % connected regions etc) can also be computed by separating them with a % column of NaNs as for example % % L = [x11 x12 x13 ... NaN x21 x22 x23 ...; % y11 y12 y13 ... NaN y21 y22 y23 ...] % % P has the same structure as L1 and L2, and its rows correspond to the % x- and y- coordinates of the intersection points of L1 and L2. If no % intersections are found, the returned P is empty. % % P = INTERX(L1) returns the self-intersection points of L1. To keep % the code simple, the points at which the curve is tangent to itself are % not included. P = INTERX(L1,L1) returns all the points of the curve % together with any self-intersection points. % % Example: % t = linspace(0,2*pi); % r1 = sin(4*t)+2; x1 = r1.*cos(t); y1 = r1.*sin(t); % r2 = sin(8*t)+2; x2 = r2.*cos(t); y2 = r2.*sin(t); % P = InterX([x1;y1],[x2;y2]); % plot(x1,y1,x2,y2,P(1,:),P(2,:),'ro') % % Two words about the algorithm: Most of the code is self-explanatory. % The only trick lies in the calculation of C1 and C2. To be brief, this % is essentially the two-dimensional analog of the condition that needs % to be satisfied by a function F(x) that has a zero in the interval % [a,b], namely % F(a)*F(b) <= 0 % C1 and C2 exactly do this for each segment of curves 1 and 2 % respectively. If this condition is satisfied simultaneously for two % segments then we know that they will cross at some point. % Each factor of the 'C' arrays is essentially a matrix containing % the numerators of the signed distances between points of one curve % and line segments of the other. % % Source % https://mathworks.com/matlabcentral/fileexchange/22441 % ------ % Author: NS % E-mail: N/A % Created: 2010-09-21 % Copyright 2010-2023 %...Argument checks and assignment of L2 narginchk(1,2); if nargin == 1 L2 = L1; hF = @lt; %...Avoid the inclusion of common points else L2 = varargin{1}; hF = @le; end %...Preliminary stuff x1 = L1(1,:)'; x2 = L2(1,:); y1 = L1(2,:)'; y2 = L2(2,:); dx1 = diff(x1); dy1 = diff(y1); dx2 = diff(x2); dy2 = diff(y2); %...Determine 'signed distances' S1 = dx1.*y1(1:end-1) - dy1.*x1(1:end-1); S2 = dx2.*y2(1:end-1) - dy2.*x2(1:end-1); C1 = feval(hF,D(bsxfun(@times,dx1,y2)-bsxfun(@times,dy1,x2),S1),0); C2 = feval(hF,D((bsxfun(@times,y1,dx2)-bsxfun(@times,x1,dy2))',S2'),0)'; %...Obtain the segments where an intersection is expected [i,j] = find(C1 & C2); if isempty(i),P = zeros(2,0);return; end; %...Transpose and prepare for output i=i'; dx2=dx2'; dy2=dy2'; S2 = S2'; L = dy2(j).*dx1(i) - dy1(i).*dx2(j); i = i(L~=0); j=j(L~=0); L=L(L~=0); %...Avoid divisions by 0 %...Solve system of eqs to get the common points P = unique([dx2(j).*S1(i) - dx1(i).*S2(j), ... dy2(j).*S1(i) - dy1(i).*S2(j)]./[L L],'rows')'; function u = D(x,y) u = bsxfun(@minus,x(:,1:end-1),y).*bsxfun(@minus,x(:,2:end),y); end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/resamplePolygonByLength.m0000644000000000000000000000013214576357161022314 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/resamplePolygonByLength.m0000644000175000017500000000524714576357161024104 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function poly2 = resamplePolygonByLength(poly, step) %RESAMPLEPOLYGONBYLENGTH Resample a polygon with a fixed sampling step. % % RES = resamplePolygon(POLY, STEP) % Resample the input polygon POLY by distributing new vertices on the % original polygon such that the (curvilinear) distance between the new % vertices is approximately equal to STEP. % % Example % % creates a polygon from an ellipse % elli = [20 30 40 20 30]; % poly = ellipseToPolygon(elli, 500); % figure; drawPolygon(poly, 'b'); % poly2 = resamplePolygonByLength(poly, 10); % hold on; % drawPolygon(poly2, 'm'); % drawPoint(poly2, 'mo'); % axis equal; axis([-20 60 0 60]); % legend('Original polygon', 'Resampled polygon', 'Location', 'NorthWest'); % % See also % polygons2d, simplifyPolygon, resamplePolygon, % resamplePolylineByLength % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform poly2 = resamplePolylineByLength(poly([1:end 1],:), step); poly2(end, :) = []; matgeom-1.2.4/inst/polygons2d/PaxHeaders/intersectPolylines.m0000644000000000000000000000013214576357161021376 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/intersectPolylines.m0000644000175000017500000001515614576357161023166 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function pts = intersectPolylines(poly1, varargin) %INTERSECTPOLYLINES Find the common points between 2 polylines. % % INTERS = intersectPolylines(POLY1, POLY2) % Returns the intersection points between two polylines. Each polyline is % defined by a N-by-2 array representing coordinates of its vertices: % [X1 Y1 ; X2 Y2 ; ... ; XN YN] % INTERS is a NP-by-2 array containing coordinates of intersection % points. % % INTERS = intersectPolylines(POLY1) % Compute self-intersections of the polyline. % % Example % % Compute intersection points between 2 simple polylines % poly1 = [20 10 ; 20 50 ; 60 50 ; 60 10]; % poly2 = [10 40 ; 30 40 ; 30 60 ; 50 60 ; 50 40 ; 70 40]; % pts = intersectPolylines(poly1, poly2); % figure; hold on; % drawPolyline(poly1, 'b'); % drawPolyline(poly2, 'm'); % drawPoint(pts); % axis([0 80 0 80]); % % This function is largely based on the 'interX' function, found on the % FileExchange: % https://fr.mathworks.com/matlabcentral/fileexchange/22441-curve-intersections % % See also % polygons2d, polylineSelfIntersections, intersectLinePolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % The code is a slight rewritting of the interX function, consisting in % avoiding argument transposition in the begining of the function. Comment % of original submission are kept here for information. % %INTERX Intersection of curves % P = INTERX(L1,L2) returns the intersection points of two curves L1 % and L2. The curves L1,L2 can be either closed or open and are described % by two-row-matrices, where each row contains its x- and y- coordinates. % The intersection of groups of curves (e.g. contour lines, multiply % connected regions etc) can also be computed by separating them with a % column of NaNs as for example % % L = [x11 x12 x13 ... NaN x21 x22 x23 ...; % y11 y12 y13 ... NaN y21 y22 y23 ...] % % P has the same structure as L1 and L2, and its rows correspond to the % x- and y- coordinates of the intersection points of L1 and L2. If no % intersections are found, the returned P is empty. % % P = INTERX(L1) returns the self-intersection points of L1. To keep % the code simple, the points at which the curve is tangent to itself are % not included. P = INTERX(L1,L1) returns all the points of the curve % together with any self-intersection points. % % Example: % t = linspace(0,2*pi); % r1 = sin(4*t)+2; x1 = r1.*cos(t); y1 = r1.*sin(t); % r2 = sin(8*t)+2; x2 = r2.*cos(t); y2 = r2.*sin(t); % P = InterX([x1;y1],[x2;y2]); % plot(x1,y1,x2,y2,P(1,:),P(2,:),'ro') % % Author : NS % Version: 3.0, 21 Sept. 2010 % % Two words about the algorithm: Most of the code is self-explanatory. % The only trick lies in the calculation of C1 and C2. To be brief, this % is essentially the two-dimensional analog of the condition that needs % to be satisfied by a function F(x) that has a zero in the interval % [a,b], namely % F(a)*F(b) <= 0 % C1 and C2 exactly do this for each segment of curves 1 and 2 % respectively. If this condition is satisfied simultaneously for two % segments then we know that they will cross at some point. % Each factor of the 'C' arrays is essentially a matrix containing % the numerators of the signed distances between points of one curve % and line segments of the other. % Check number of inputs narginchk(1, 2); % Specific init depending on number of inputs if nargin == 1 % Compute self-intersections % -> Avoid the inclusion of common points poly2 = poly1; hF = @lt; else % Compute intersections between distinct lines poly2 = varargin{1}; hF = @le; end % Get coordinates of polyline vertices x1 = poly1(:,1); x2 = poly2(:,1)'; y1 = poly1(:,2); y2 = poly2(:,2)'; % differentiate coordinate arrays dx1 = diff(x1); dy1 = diff(y1); dx2 = diff(x2); dy2 = diff(y2); % Determine 'signed distances' S1 = dx1 .* y1(1:end-1) - dy1 .* x1(1:end-1); S2 = dx2 .* y2(1:end-1) - dy2 .* x2(1:end-1); C1 = feval(hF, D(bsxfun(@times,dx1,y2) - bsxfun(@times,dy1,x2), S1), 0); C2 = feval(hF, D((bsxfun(@times,y1,dx2) - bsxfun(@times,x1,dy2))', S2'), 0)'; % Obtain the segments where an intersection is expected [i, j] = find(C1 & C2); % Process case of no intersection if isempty(i) pts = zeros(0, 2); return; end % Transpose and prepare for output i=i'; dx2=dx2'; dy2=dy2'; S2 = S2'; L = dy2(j).*dx1(i) - dy1(i).*dx2(j); % Avoid divisions by zero i = i(L~=0); j = j(L~=0); L = L(L~=0); % Solve system of eqs to get the common points res = [dx2(j).*S1(i) - dx1(i).*S2(j), dy2(j).*S1(i) - dy1(i).*S2(j)] ./ [L L]; pts = unique(res, 'rows'); % Innre function computing a kind of cross-product function u = D(x,y) u = bsxfun(@minus, x(:,1:end-1), y) .* bsxfun(@minus, x(:,2:end), y); end end matgeom-1.2.4/inst/polygons2d/PaxHeaders/supportFunction.m0000644000000000000000000000013214576357161020721 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/supportFunction.m0000644000175000017500000000511714576357161022505 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function h = supportFunction(polygon, varargin) %SUPPORTFUNCTION Compute support function of a polygon. % % H = supportFunction(POLYGON, N) % uses N points for suport function approximation % % H = supportFunction(POLYGON) % assume 24 points for approximation % % H = supportFunction(POLYGON, V) % where V is a vector, uses vector V of angles to compute support % function. % % See also % polygons2d, convexification % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-12-20 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE N = 24; u = 0:2*pi/N:2*pi*(1-1/N); if length(varargin)==1 var = varargin{1}; if length(var)==1 N = var; u = 0:2*pi/N:2*pi*(1-1/N); else u = var; end end % ensure u vertical vector if size(u, 1)==1 u=u'; end h = zeros(size(u)); for i=1:length(u) v = repmat([cos(u(i)) sin(u(i))], [size(polygon, 1), 1]); h(i) = max(dot(polygon, v, 2)); end matgeom-1.2.4/inst/polygons2d/PaxHeaders/polygonEdges.m0000644000000000000000000000013214576357161020136 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/polygonEdges.m0000644000175000017500000000555014576357161021723 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges = polygonEdges(poly) %POLYGONEDGES Return the edges of a simple or multiple polygon. % % EDGES = polygonEdges(POLY) % Return the set of edges of the polygon specified by POLY. POLY may be % either a simple polygon given as a N-by-2 array of vertices, or a % multiple polygon given by a cell array of linear rings, each ring being % given as N-by-2 array of vertices. % % % Example % poly = [50 10;60 10;60 20;50 20]; % polygonEdges(poly) % ans = % 50 10 60 10 % 60 10 60 20 % 60 20 50 20 % 50 20 50 10 % % See also % polygons2d, polygonVertices % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-08-29, using Matlab 9.1.0.441655 (R2016b) % Copyright 2017-2023 INRA - Cepia Software Platform % test presence of NaN values if isnumeric(poly) && any(isnan(poly(:))) poly = splitPolygons(poly); end % create the array of polygon edges if iscell(poly) % process multiple polygons edges = zeros(0, 4); for i = 1:length(poly) pol = poly{i}; N = size(pol, 1); edges = [edges; pol(1:N, :) pol([2:N 1], :)]; %#ok end else % get edges of a simple polygon N = size(poly, 1); edges = [poly(1:N, :) poly([2:N 1], :)]; end matgeom-1.2.4/inst/polygons2d/PaxHeaders/curvature.m0000644000000000000000000000013214576357161017517 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/polygons2d/curvature.m0000644000175000017500000001304214576357161021277 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function kappa = curvature(varargin) %CURVATURE Estimate curvature of a polyline defined by points. % % KAPPA = curvature(T, PX, PY, METHOD, DEGREE) % First compute an approximation of the curve given by PX and PY, with % the parametrization T. METHOD used for approximation can be only: % 'polynom', with specified degree % Further methods will be provided in a future version. % T, PX, and PY are N*1 array of the same length. % Then compute the curvature of approximated curve for each point. % % For example: % KAPPA = curvature(t, px, py, 'polynom', 6) % % KAPPA = curvature(T, POINTS, METHOD, DEGREE) % specify curve as a suite of points. POINTS is size [N*2]. % % KAPPA = curvature(PX, PY, METHOD, DEGREE) % KAPPA = curvature(POINTS, METHOD, DEGREE) % compute implicite normalization of the curve, based on euclidian % distance between 2 consecutive points, and normalized between 0 and 1. % % % See also % polygons2d, parametrize % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-04-07 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % default values degree = 5; t=0; % parametrization of curve tc=0; % indices of points wished for curvature % Extract method and degree nargin = length(varargin); varN = varargin{nargin}; varN2 = varargin{nargin-1}; if ischar(varN2) % method and degree are specified method = varN2; degree = varN; varargin = varargin(1:nargin-2); elseif ischar(varN) % only method is specified, use degree 6 as default method = varN; varargin = varargin{1:nargin-1}; else % method and degree are implicit : use 'polynom' and 6 method = 'polynom'; end % extract input parametrization and curve nargin = length(varargin); if nargin==1 % parameters are just the points -> compute caracterization. var = varargin{1}; px = var(:,1); py = var(:,2); elseif nargin==2 var = varargin{2}; if size(var, 2)==2 % parameters are t and POINTS px = var(:,1); py = var(:,2); t = varargin{1}; else % parameters are px and py px = varargin{1}; py = var; end elseif nargin==3 var = varargin{2}; if size(var, 2)==2 % parameters are t, POINTS, and tc px = var(:,1); py = var(:,2); t = varargin{1}; else % parameters are t, px and py t = varargin{1}; px = var; py = varargin{3}; end elseif nargin==4 % parameters are t, px, py and tc t = varargin{1}; px = varargin{2}; py = varargin{3}; tc = varargin{4}; end % compute implicit parameters % if t and/or tc are not computed, use implicit definition if t==0 t = parametrize(px, py); t = t/t(length(t)); % normalize between 0 and 1 end % if tc not defined, compute curvature for all points if tc==0 tc = t; else % else convert from indices to parametrization values tc = t(tc); end %% compute curvature for each point of the curve if strcmp(method, 'polynom') % compute coefficients of interpolation functions x0 = polyfit(t, px, degree); y0 = polyfit(t, py, degree); % compute coefficients of first and second derivatives. In the case of a % polynom, it is possible to compute coefficient of derivative by % multiplying with a matrix. derive = diag(degree:-1:0); xp = circshift(x0*derive, [0 1]); yp = circshift(y0*derive, [0 1]); xs = circshift(xp*derive, [0 1]); ys = circshift(yp*derive, [0 1]); % compute values of first and second derivatives for needed points xprime = polyval(xp, tc); yprime = polyval(yp, tc); xsec = polyval(xs, tc); ysec = polyval(ys, tc); % compute value of curvature kappa = (xprime.*ysec - xsec.*yprime)./ ... power(xprime.*xprime + yprime.*yprime, 3/2); else error('unknown method'); end matgeom-1.2.4/inst/PaxHeaders/Contents.m0000644000000000000000000000013214576357161015174 xustar0030 mtime=1710874225.086193394 30 atime=1710874225.086193394 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/Contents.m0000644000175000017500000000537314576357161016764 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. %CONTENTS MATGEOM Geometric Computing Toolbox. % Version 1.0 26-07-2017. % % MatGeom Provides low-level functions for geometric computing. It is % possible to create, display, compute intersections... of various % geometrical primitives, in 2D and 3D. % % The library is organized into several modules: % geom2d - General function in euclidean plane % polygons2d - Functions operating on point lists % graphs - Manipulation of geometric graphs % polynomialCurves2d - Representation of smooth polynomial curves % geom3d - General function in 3D euclidean space % meshes3d - Manipulation of 3D surfacic meshes % % Type 'help(MODULENAME)' for further info. % % To install the library, with all sub-directories, run the script % 'setupMatGeom'. % % More information on the project homepage: % https://github.com/mattools/matGeom % % Online documentation: % https://github.com/mattools/matGeom % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-03-21, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform help(mfilename); matgeom-1.2.4/inst/PaxHeaders/utils0000644000000000000000000000013214576357160014303 xustar0030 mtime=1710874224.682193781 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/utils/0000755000175000017500000000000014576357160016140 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/utils/PaxHeaders/parseAxisHandle.m0000644000000000000000000000013214576357161017612 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/utils/parseAxisHandle.m0000644000175000017500000000445214576357161021377 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [ax, varargin] = parseAxisHandle(varargin) %PARSEAXISHANDLE Parse handle to axis, or return current axis. % % Usage: % [ax, varargin] = parseAxisHandle(varargin{:}); % % Example % parseAxisHandle % % See also % isAxisHandle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2023-09-05, using Matlab 9.14.0.2206163 (R2023a) % Copyright 2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % varargin can not be empty if isempty(varargin) error('Requires at least one input argument'); end % extract handle of axis to draw on var1 = varargin{1}; if isscalar(var1) && ishandle(var1) && strcmp(get(var1, 'type'), 'axes') ax = varargin{1}; varargin(1) = []; else ax = gca; end matgeom-1.2.4/inst/utils/PaxHeaders/isAxisHandle.m0000644000000000000000000000013214576357161017113 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/utils/isAxisHandle.m0000644000175000017500000000474514576357161020705 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function b = isAxisHandle(arg) %ISAXISHANDLE Check if the input corresponds to a valid axis handle. % % B = isAxisHandle(VAR) % If the value of VAR is scalar, corresponds to a valid MATLAB handle, % and has type equal to 'axis', then returns TRUE. Otherwise, returns % FALSE. % This function is used to check if first argument of drawing functions % corresponds to data or to axis handle to draw in. % % NOTE: The 'parseAxisHandle' function performs a similar task, but % provides a single line interface. % % Example % isAxisHandle(gca) % ans = % 1 % % See also % parseAxisHandle, drawPoint, drawLine, drawEdge % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-09-21, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform b = isscalar(arg) && ishandle(arg) && strcmp(get(arg, 'type'), 'axes'); matgeom-1.2.4/inst/utils/PaxHeaders/parseDrawInput.m0000644000000000000000000000013214576357161017507 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/utils/parseDrawInput.m0000644000175000017500000000631414576357161021273 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [hAx, prim, varargin] = parseDrawInput(prim, valFun, type, defOpts, varargin) %PARSEDRAWINPUT Parse input arguments for drawing functions: draw*. % % INPUT: % PRIM: The primitive object: line, plane, ... % VALFUN: An anonymous Function to validate PRIM % TYPE: The drawing type of PRIM: 'line', 'patch', ... % DEFOPTS: The default drawing options for PRIM as struct % % OUTPUT: % HAX: The current or specified axes for drawing % PRIM: validated PRIM % ------ % Author: oqilipo % E-mail: N/A % Created: 2017-10-13, using R2017b % Copyright 2017-2023 % Check if first input argument is an axes handle if isAxisHandle(prim) hAx = prim; prim = varargin{1}; varargin(1) = []; else hAx = gca; end % Check if the primitive is valid p=inputParser; addRequired(p,'prim',valFun) parse(p,prim) % parse input arguments if there are any if ~isempty(varargin) if length(varargin) == 1 if isstruct(varargin{1}) % if options are specified as struct, need to convert to % parameter name-value pairs varargin = [fieldnames(varargin{1}) struct2cell(varargin{1})]'; varargin = varargin(:)'; else % if option is a single argument, assume it is the color switch type case 'line' varargin = {'Color', varargin{1}}; case 'patch' varargin = {'FaceColor', varargin{1}}; end end end else % If no arguments are given, use the default options varargin = [fieldnames(defOpts) struct2cell(defOpts)]'; varargin = varargin(:)'; end end matgeom-1.2.4/inst/PaxHeaders/meshes3d0000644000000000000000000000013214576357160014656 xustar0030 mtime=1710874224.682193781 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/0000755000175000017500000000000014576357160016513 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/meshes3d/PaxHeaders/triangulateMesh.m0000644000000000000000000000013214576357161020246 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/triangulateMesh.m0000644000175000017500000000626514576357161022037 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = triangulateMesh(varargin) %TRIANGULATEMESH Convert a non-triangle mesh into a triangle mesh. % % [V2, F2] = triangulateMesh(V, F) % Convert the mesh represented by vertices V and faces F into a triangle % mesh. V is N-by-3 numeric array containing vertex coordinates. F is an % array representing faces: either a N-by-4 or N-by-3 numeric array, or a % cell array for meshes with non homogeneous face vertex counts. % The result is a mesh with same vertices (V == F), and F2 represented as % a N-by-3 numeric array. If the input mesh is already a triangular mesh, % the result is the same as the input. % % [V2, F2] = triangulateMesh(MESH) % Specifies the mesh as a structure with at least two fields 'vertices' % and 'faces'. % % MESH2 = triangulateMesh(...) % Returns the result as a mesh data structure with two fields 'vertices' % and 'faces'. % % Example % % create a basic shape % [v, f] = createCubeOctahedron; % % draw with plain faces % figure; hold on; axis equal; view(3); % drawMesh(v, f); % % draw as a triangulation % [v2, f2] = triangulateMesh(v, f); % figure; hold on; axis equal; view(3); % drawMesh(v2, f2, 'facecolor', 'r'); % % See also % meshes3d, triangulateFaces, drawMesh % % ------ % Author: David Legland % e-mail: david.legland@inrae.fr % INRAE - BIA Research Unit - BIBS Platform (Nantes) % Created: 2024-02-16, using Matlab 23.2.0.2459199 (R2023b) Update 5 % Copyright 2024 INRAE. [vertices, faces] = parseMeshData(varargin{:}); faces2 = triangulateFaces(faces); varargout = formatMeshOutput(nargout, vertices, faces2); matgeom-1.2.4/inst/meshes3d/PaxHeaders/mergeCoplanarFaces.m0000644000000000000000000000013214576357161020633 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/mergeCoplanarFaces.m0000644000175000017500000001623114576357161022416 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = mergeCoplanarFaces(nodes, varargin) %MERGECOPLANARFACES Merge coplanar faces of a polyhedral mesh. % % [NODES, FACES] = mergeCoplanarFaces(NODES, FACES) % [NODES, EDGES, FACES] = mergeCoplanarFaces(NODES, EDGES, FACES) % NODES is a set of 3D points (as a nNodes-by-3 array), % and FACES is one of: % - a nFaces-by-X array containing vertex indices of each face, with each % face having the same number of vertices, % - a nFaces-by-1 cell array, each cell containing indices of a face. % The function groups faces which are coplanar and contiguous, resulting % in a "lighter" mesh. This can be useful for visualizing binary 3D % images for example. % % FACES = mergeCoplanarFaces(..., PRECISION) % Adjust the threshold for deciding if two faces are coplanar or % parallel. Default value is 1e-5. % % Example % [v, e, f] = createCube; % f = triangulateFaces(f); % figure; drawMesh(v, f); % view(3); axis equal tight; % [v2, f2] = mergeCoplanarFaces(v, f); % figure; drawMesh(v2, f2); % view(3); axis equal tight; % % See also % meshes3d, drawMesh, minConvexHull, triangulateFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-07-05 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) %% Process input arguments % set up precision acc = 1e-5; if ~isempty(varargin) var = varargin{end}; if length(var) == 1 acc = var; varargin(end) = []; end end % extract faces and edges if length(varargin) == 1 faces = varargin{1}; else faces = varargin{2}; end %% Initialisations % number of faces nNodes = size(nodes, 1); nFaces = size(faces, 1); % compute number of vertices of each face Fn = ones(nFaces, 1) * size(faces, 2); % compute normal of each faces normals = meshFaceNormals(nodes, faces); % initialize empty faces and edges faces2 = cell(0, 1); edges2 = zeros(0, 2); % Processing flag for each face % 1: face to process, 0: already processed % in the beginning, every triangle face need to be processed flag = ones(nFaces, 1); %% Main iteration % iterate on each face for iFace = 1:nFaces % check if face was already performed if ~flag(iFace) continue; end % indices of faces with same normal ind = find(vectorNorm3d(crossProduct3d(normals(iFace, :), normals)) < acc); % keep only coplanar faces (test coplanarity of points in both face) ind2 = false(size(ind)); for j = 1:length(ind) ind2(j) = isCoplanar(nodes([faces(iFace,:) faces(ind(j),:)], :), acc); end ind2 = ind(ind2); % compute edges of all faces in the plane planeEdges = zeros(sum(Fn(ind2)), 2); pos = 1; for i = 1:length(ind2) face = faces(ind2(i), :); faceEdges = sort([face' face([2:end 1])'], 2); planeEdges(pos:sum(Fn(ind2(1:i))), :) = faceEdges; pos = sum(Fn(ind2(1:i)))+1; end planeEdges = unique(planeEdges, 'rows'); % relabel plane edges [planeNodes, I, J] = unique(planeEdges(:)); %#ok planeEdges2 = reshape(J, size(planeEdges)); % The set of coplanar faces may not necessarily form a single connected % component. The following computes label of each connected component. component = grLabel(nodes(planeNodes, :), planeEdges2); % compute degree (number of adjacent faces) of each edge. Npe = size(planeEdges, 1); edgeDegrees = zeros(Npe, 1); for i = 1:length(ind2) face = faces(ind2(i), :); faceEdges = sort([face' face([2:end 1])'], 2); for j = 1:size(faceEdges, 1) indEdge = find(sum(ismember(planeEdges, faceEdges(j,:)),2)==2); edgeDegrees(indEdge) = edgeDegrees(indEdge)+1; end end % extract unique edges and nodes of the plane planeEdges = planeEdges(edgeDegrees==1, :); planeEdges2 = planeEdges2(edgeDegrees==1, :); % find connected component of each edge planeEdgesComp = zeros(size(planeEdges, 1), 1); for iEdge = 1:size(planeEdges, 1) planeEdgesComp(iEdge) = component(planeEdges2(iEdge, 1)); end % iterate on connected faces for c = 1:max(component) % convert to chains of nodes loops = graph2Contours(nodes, planeEdges(planeEdgesComp==c, :)); % add a simple Polygon for each loop facePolygon = loops{1}; for l = 2:length(loops) facePolygon = [facePolygon, NaN, loops{l}]; %#ok end faces2{length(faces2)+1, 1} = facePolygon; % also add news edges edges2 = unique([edges2; planeEdges], 'rows'); end % mark processed faces flag(ind2) = 0; end %% Additional processing on nodes % select only nodes which appear in at least one edge indNodes = unique(edges2(:)); % for each node, compute index of corresponding new node (or 0 if dropped) refNodes = zeros(nNodes, 1); for i = 1:length(indNodes) refNodes(indNodes(i)) = i; end % changes indices of nodes in edges2 array for i = 1:length(edges2(:)) edges2(i) = refNodes(edges2(i)); end % changes indices of nodes in faces2 array for iFace = 1:length(faces2) face = faces2{iFace}; for i = 1:length(face) if ~isnan(face(i)) face(i) = refNodes(face(i)); end end faces2{iFace} = face; end % keep only boundary nodes nodes2 = nodes(indNodes, :); %% Process output arguments if nargout == 1 varargout{1} = faces2; elseif nargout == 2 varargout{1} = nodes2; varargout{2} = faces2; elseif nargout == 3 varargout{1} = nodes2; varargout{2} = edges2; varargout{3} = faces2; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createTetrahedron.m0000644000000000000000000000013214576357161020555 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createTetrahedron.m0000644000175000017500000000561614576357161022345 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createTetrahedron() %CREATETETRAHEDRON Create a 3D mesh representing a tetrahedron. % % [V, E, F] = createTetrahedron % create a simple tetrahedron, using mesh representation. The tetrahedron % is inscribed in the unit cube. % V is a 4-by-3 array with vertex coordinates, % E is a 6-by-2 array containing indices of neighbour vertices, % F is a 4-by-3 array containing vertices array of each (triangular) face. % % [V, F] = createTetrahedron; % Returns only the vertices and the faces. % % MESH = createTetrahedron; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % % Example % % Create and display a tetrahedron % [V, E, F] = createTetrahedron; % drawMesh(V, F); % % See also % meshes3d, drawMesh % createCube, createOctahedron, createDodecahedron, createIcosahedron % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-03-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE x0 = 0; dx= 1; y0 = 0; dy= 1; z0 = 0; dz= 1; nodes = [... x0 y0 z0; ... x0+dx y0+dy z0; ... x0+dx y0 z0+dz; ... x0 y0+dy z0+dz]; edges = [1 2;1 3;1 4;2 3;3 4;4 2]; faces = [1 2 3;1 3 4;1 4 2;4 3 2]; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/triangulatePolygonPair.m0000644000000000000000000000013214576357161021615 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/triangulatePolygonPair.m0000644000175000017500000001272514576357161023404 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [vertices, faces] = triangulatePolygonPair(poly1, poly2, varargin) %TRIANGULATEPOLYGONPAIR Compute triangulation between a pair of 3D closed curves. % % [V, F] = triangulatePolygonPair(POLY1, POLY2) % % [V, F] = triangulatePolygonPair(..., 'recenter', FLAG) % Where FLAG is a boolean, specifies whether the second curve should be % translated to have the same centroid as the first curve. This can % improve mathcing of vertices. Default is true. % % % Example % % triangulate a surface patch between two ellipses % % create two sample curves % poly1 = ellipseToPolygon([50 50 40 20 0], 36); % poly2 = ellipseToPolygon([50 50 40 20 60], 36); % poly1 = poly1(1:end-1,:); % poly2 = poly2(1:end-1,:); % % transform to 3D polygons / curves % curve1 = [poly1 10*ones(size(poly1, 1), 1)]; % curve2 = [poly2 20*ones(size(poly2, 1), 1)]; % % draw as 3D curves % figure(1); clf; hold on; % drawPolygon3d(curve1, 'b'); drawPoint3d(curve1, 'bo'); % drawPolygon3d(curve2, 'g'); drawPoint3d(curve2, 'go'); % view(3); axis equal; % [vertices, faces] = triangulatePolygonPair(curve1, curve2); % % display the resulting mesh % figure(2); clf; hold on; % drawMesh(vertices, faces); % drawPolygon3d(curve1, 'color', 'b', 'linewidth', 2); % drawPolygon3d(curve2, 'color', 'g', 'linewidth', 2); % view(3); axis equal; % % See also % meshes3D, triangulatePolygonPair3d, triangulateCurvePair, % meshSurfaceArea % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-05-18, using Matlab 9.1.0.441655 (R2016b) % Copyright 2017-2023 INRA - Cepia Software Platform %% Settings recenterFlag = true; while length(varargin) > 1 pname = varargin{1}; if strcmpi(pname, 'recenter') recenterFlag = varargin{2}; else error('Unknown parameter name: %s', pname); end varargin(1:2) = []; end %% Memory allocation % concatenate vertex coordinates for creating mesh vertices = [poly1 ; poly2]; % number of vertices on each polygon n1 = size(poly1, 1); n2 = size(poly2, 1); % allocate the array of facets (each edge of each polygon provides a facet) nFaces = n1 + n2; faces = zeros(nFaces, 3); % Translate the second polygon such that the centroids of the bounding % boxes coincide. This is expected to improve the matching of the two % curves. if recenterFlag box1 = boundingBox3d(poly1); box2 = boundingBox3d(poly2); center1 = (box1(2:2:end) + box1(1:2:end-1)) / 2; center2 = (box2(2:2:end) + box2(1:2:end-1)) / 2; vecTrans = center1 - center2; trans = createTranslation3d(vecTrans); poly2 = transformPoint3d(poly2, trans); end %% Init iteration % find the pair of points with smallest distance. % This will be the current diagonal. [dists, inds] = minDistancePoints(poly1, poly2); [dummy, ind1] = min(dists); %#ok ind2 = inds(ind1); % consider two consecutive vertices on each polygon currentIndex1 = ind1; currentIndex2 = ind2; %% Main iteration % For each diagonal, consider the two possible facets (one for each 'next' % vertex on each polygon), each create current facet according to the % closest one. % Then update current diagonal for next iteration. for iFace = 1:nFaces nextIndex1 = mod(currentIndex1, n1) + 1; nextIndex2 = mod(currentIndex2, n2) + 1; % compute lengths of diagonals dist1 = distancePoints(poly1(currentIndex1, :), poly2(nextIndex2,:)); dist2 = distancePoints(poly1(nextIndex1, :), poly2(currentIndex2,:)); if dist1 < dist2 % keep current vertex of curve1, use next vertex on curve2 face = [currentIndex1 currentIndex2+n1 nextIndex2+n1]; currentIndex2 = nextIndex2; else % keep current vertex of curve2, use next vertex on curve1 face = [currentIndex1 currentIndex2+n1 nextIndex1]; currentIndex1 = nextIndex1; end % create the facet faces(iFace, :) = face; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshVertexNormals.m0000644000000000000000000000013214576357161020600 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshVertexNormals.m0000644000175000017500000000620414576357161022362 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [normals, faceNormals] = meshVertexNormals(varargin) %MESHVERTEXNORMALS Compute normals to a mesh vertices. % % N = meshVertexNormals(V, F) % Computes vertex normals of the mesh given by vertices V and F. % V is a vertex array with 3 columns, F is either a NF-by-3 or NF-by-4 % index array, or a cell array with NF elements. % % Example % % Draw the vertex normals of a sphere % s = [10 20 30 20]; % [v f] = sphereMesh(s); % figure; drawMesh(v, f); % view(3);axis equal; light; lighting gouraud; % normals = meshVertexNormals(v, f); % drawVector3d(v, normals*2); % % See also % meshes3d, meshFaceNormals, triangulateFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-19, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform [vertices, faces] = parseMeshData(varargin{:}); nv = size(vertices, 1); nf = size(faces, 1); % unit normals to the faces faceNormals = normalizeVector3d(meshFaceNormals(vertices, faces)); % compute normal of each vertex: sum of normals to each face normals = zeros(nv, 3); if isnumeric(faces) for i = 1:nf face = faces(i, :); for j = 1:length(face) v = face(j); normals(v, :) = normals(v,:) + faceNormals(i,:); end end else for i = 1:nf face = faces{i}; for j = 1:length(face) v = face(j); normals(v, :) = normals(v,:) + faceNormals(i,:); end end end % normalize vertex normals to unit vectors normals = normalizeVector3d(normals); matgeom-1.2.4/inst/meshes3d/PaxHeaders/readMesh_obj.m0000644000000000000000000000013214576357161017474 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/readMesh_obj.m0000644000175000017500000001567214576357161021267 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function mesh = readMesh_obj(fileName) %READMESH_OBJ Read mesh data stored in OBJ format. % % MESH = readMesh_obj(FILENAME) % Read the data stored in file FILENAME and return the mesh into a struct % with fields 'vertices' and 'faces'. % % Example % mesh = readMesh_obj('teapot.obj'); % figure; drawMesh(mesh, 'facecolor', [.5 .5 .5]); % axis equal; light; % % References % Adapted from Bernard Abayowa (2022). readObj % (https://www.mathworks.com/matlabcentral/fileexchange/18957-readobj), % MATLAB Central File Exchange. Retrieved September 8, 2022. % % See also % meshes3d, readMesh, readMesh_off, drawMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-09-08, using Matlab 9.9.0.1570001 (R2020b) Update 4 % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% initialisations % open file fid = fopen(fileName); if fid == -1 error('matGeom:readMesh_obj:FileNotFound', ... ['Could not open input file: ' fileName]); end % create result arrays for vertices v = []; % vertices vt = []; % vertex textures vn = []; % vertex normals % create result arrays for faces % (uses cell arrays as face may have variable number of vertices) fv = {}; % face vertices fvt = {}; % face texture coordinates fvn = {}; % face normals %% File parsing % parse lines of OBJ file within infinite loop lineIndex = 0; while true % read current line line = fgetl(fid); lineIndex = lineIndex + 1; % check end of file to break the loop if ~ischar(line) break; end % parse element type type = sscanf(line, '%s', 1); if strcmp(type, 'v') % parse vertex v = [v; sscanf(line(2:end), '%f')']; %#ok elseif strcmp(type, 'vt') % parse texture coordinate vt = [vt; sscanf(line(3:end), '%f')']; %#ok elseif strcmp(type, 'vn') % parse normal coordinates vn = [vn; sscanf(line(3:end), '%f')']; %#ok elseif strcmp(type, 'f') % parse face data % transform current line into a matrix of tokens with as many rows % as face vertices, and as many columns as face data type str = textscan(line(2:end), '%s'); tokenMatrix = split(str{1}, '/'); % parse vertex indices (first column of matrix) fv = [fv; {str2double(tokenMatrix(:,1))'}]; %#ok % parse texture coordinates (second column of matrix) if size(tokenMatrix, 2) > 1 && ~isempty(tokenMatrix{1,2}) fvt = [fvt; {str2double(tokenMatrix(:,2))'}]; %#ok end % parse normal coordinates (third column of matrix) if size(tokenMatrix, 2) > 2 && ~isempty(tokenMatrix{1,3}) fvn = [fvn ; str2double(tokenMatrix(:,3)')]; %#ok end % The following code is slightly faster, but does not manage % all possible cases (in particular when face texture is empty) % and is more complicated to maintain. % str = textscan(line(2:end), '%s'); % str = str{1}; % fvi = []; fvti = []; fvni = []; % % % number of fields with this face vertices % nf = length(strfind(str{1}, '/')); % % % vertex indices % [tok, str] = strtok(str, '//'); %#ok % for k = 1:length(tok) % fvi = [fvi str2double(tok{k})]; %#ok % end % fv = [fv; fvi]; %#ok % % % vertex texture coordinates % if nf > 0 % [tok, str] = strtok(str, '//'); %#ok % for k = 1:length(tok) % fvti = [fvti str2double(tok{k})]; %#ok % end % fvt = [fvt; fvti]; %#ok % end % % % vertex normal coordinates % if nf > 1 % tok = strtok(str, '//'); % for k = 1:length(tok) % fvni = [fvni str2double(tok{k})]; %#ok % end % fvn = [fvn; fvni]; %#ok % end elseif any(strcmp(type, {'g', 'o', 's', 'usemtl'})) warning('matGeom:readMesh_obj:UnsupportedElement', ...... 'Element %s at line %d is not (yet) managed', type, lineIndex); elseif isempty(type) || any(strcmp(type(1), {'#', ' '})) % comment or empty line -> do nothing else warning('matGeom:readMesh_obj:UnknownElement', ...... 'Unknown element type at line %d: %s', lineIndex, type); end end % close file fclose(fid); %% Format output % create mesh structure mesh = struct('vertices', v); % add optional vertex data if ~isempty(vn) mesh.vertexNormals = vn; end if ~isempty(vt) mesh.vertexTexture = vt; end mesh.faces = fv; % add optional face data if ~isempty(fvn) mesh.faceVertexNormals = fvn; end if ~isempty(fvt) mesh.faceVertexTexture = fvt; end % if faces have all the same number of vertices, convert to numeric arrays nvf = cellfun(@length, fv); if all(nvf == nvf(1)) mesh.faces = cell2mat(mesh.faces(:)); if ~isempty(fvn) mesh.faceVertexNormals = cell2mat(fvn(:)); end if ~isempty(fvt) mesh.faceVertexTexture = cell2mat(fvt(:)); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/writeMesh_stl.m0000644000000000000000000000013214576357161017743 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/writeMesh_stl.m0000644000175000017500000000512714576357161021530 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function writeMesh_stl(fileName, vertices, faces, varargin) %WRITEMESH_STL Write mesh data in the STL format. % % writeMesh_stl(FNAME, VERTICES, FACES) % % writeMesh_stl(FNAME, MESH) % % writeMesh_stl(FNAME, VERTICES, FACES, ...) see stlwrite for additonal % options % % Example % mesh = cylinderMesh([60 50 40 10 20 30 5], 1); % writeMesh_stl('Cylinder.stl', mesh, 'bin'); % % References % Wrapper function for MATLAB's build-in stlwrite. % % See also % meshes3d, writeMesh, writeMesh_off, writeMesh_ply, readMaesh_stl % ------ % Author: oqilipo % E-mail: N/A % Created: 2021-02-13, using Matlab 9.9.0.1538559 (R2020b) % Copyright 2021-2023 %% Check inputs if ~ischar(fileName) error('First argument must contain the name of the file'); end % optionnaly parses data if isstruct(vertices) if nargin > 2 varargin = [{faces} varargin{:}]; end faces = vertices.faces; vertices = vertices.vertices; end %% Write STL TR = triangulation(faces, vertices); stlwrite(TR,fileName, varargin{:}) end matgeom-1.2.4/inst/meshes3d/PaxHeaders/removeDuplicateVertices.m0000644000000000000000000000013214576357161021747 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/removeDuplicateVertices.m0000644000175000017500000000741314576357161023534 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = removeDuplicateVertices(v,varargin) %REMOVEDUPLICATEVERTICES Remove duplicate vertices of a mesh. % % [V2, F2] = removeDuplicateVertices(V, F) % Remove duplicate vertices of a mesh defined by the vertices V and % faces F. % % [V2, F2] = removeDuplicateVertices(V, F, TOL) % Remove duplicate vertices with the tolerance TOL: % TOL = 0 -> Exact match % TOL = 1e-1 -> Match up to first decimal % TOL = 1 -> Integer match % % [VIDX, FIDX] = removeDuplicateVertices(V, F, TOL, 'indexOutput', true) % Gives the indices instead of the final mesh. This means: % V2 = V(VIDX,:) % F2 = FIDX(F) % V = V2(FIDX,:) % % Example % v = [6-1e-6,0,-5;4,2,-2*pi;0,2,-7;6,0,-5;3,1,-9;0,2,-7;... % 6,0,-5+1e-6;4,2,-2*pi;3,1,-9;4,2,-2*pi;6,4,-6;3,1,-9;... % 4,2,-2*pi;0,2,-7;6,4,-6;6,4,-6;0,2,-7;3,1,-9]; % f = reshape(1:18,3,6)'; % [v, f] = removeDuplicateVertices(v, f); % % See also % trimMesh, removeDuplicateFaces, removeUnreferencedVertices % % Source % patchslim.m by Francis Esmonde-White: % https://mathworks.com/matlabcentral/fileexchange/29986 % remove_duplicate_vertices.m by Alec Jacobson: % https://github.com/alecjacobson/gptoolbox % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-05-14, using Matlab 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 %% Parse input if isstruct(v) [v, f] = parseMeshData(v); else f = varargin{1}; varargin(1) = []; end parser = inputParser; logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addOptional(parser, 'tol', 0, @(x) validateattributes(x, {'numeric'}, {'scalar', '>=',0, '<=',1})); addParameter(parser, 'indexOutput', false, logParValidFunc); parse(parser, varargin{:}); tol = parser.Results.tol; indexOutput = parser.Results.indexOutput; %% Remove duplicate vertices if tol == 0 [~, vIdx, fIdx] = unique(v,'rows','stable'); else [~, vIdx, fIdx] = unique(round(v/(tol)),'rows','stable'); end %% Parse output if indexOutput % If indices are requested varargout = {vIdx, fIdx}; else % Output is the final mesh v2 = v(vIdx,:); f2 = fIdx(f); varargout = formatMeshOutput(nargout, v2, f2); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/intersectPlaneMesh.m0000644000000000000000000000013214576357161020707 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/intersectPlaneMesh.m0000644000175000017500000002404614576357161022475 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [polys, closedFlag] = intersectPlaneMesh(plane, v, f) %INTERSECTPLANEMESH Compute the polylines resulting from plane-mesh intersection. % % POLYS = intersectPlaneMesh(P, V, F) % [POLYS, CLOSED] = intersectPlaneMesh(P, V, F) % Computes the intersection between a plane and a mesh. % The plane P is given as: % P = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2] % The mesh is given as numeric array V of vertex coordinates and an array % of (triangular) face vertex indices. % The output POLYS is a cell array of polylines, where each cell contains % a NV-by-3 numeric array of coordinates. The (optional) output CLOSED is % a logical array the same size as the POLYS, indicating whether the % corresponding polylines are closed (true), or open (false). % Use the functions 'drawPolygon3d' to display closed polylines, and % 'drawPolyline3d' to display open polylines. % % % Example % % Intersect a cube by a plane % [v, f] = createCube; v = v * 10; % plane = createPlane([5 5 5], [3 4 5]); % % draw the primitives % figure; hold on; set(gcf, 'renderer', 'opengl'); % axis([-10 20 -10 20 -10 20]); view(3); % drawMesh(v, f); drawPlane3d(plane); % % compute intersection polygon % polys = intersectPlaneMesh(plane, v, f); % drawPolygon3d(polys, 'LineWidth', 2); % % % Intersect a torus by a set of planes, and draw the results % % first creates a torus slightly shifted and rotated % torus = [.5 .6 .7 30 10 3 4]; % figure('color','w'); % % convert to mesh representation % [v, f] = torusMesh(torus, 'nTheta', 64, 'nPhi', 64); % f = triangulateFaces(f); % drawMesh(v, f); % hold on; view (3); axis equal; light; % % compute intersections with collection of planes % xList = -50:5:50; % polySet = cell(length(xList), 1); % for i = 1:length(xList) % x0 = xList(i); % plane = createPlane([x0 .5 .5], [1 .2 .3]); % polySet{i} = intersectPlaneMesh(plane, v, f); % end % % draw the resulting 3D polygons % drawPolygon3d(polySet, 'lineWidth', 2, 'color', 'y') % % % Demonstrate ability to draw open mesh intersections % poly = circleArcToPolyline([10 0 5 90 180], 33); % [x, y, z] = revolutionSurface(poly, linspace(-pi, pi, 65)); % [v, f] = surfToMesh(x, y, z); % f = triangulateFaces(f); % plane = createPlane([0 0 0], [5 2 -4]); % figure; hold on; axis equal; view(3); % drawMesh(v, f, 'linestyle', 'none', 'facecolor', [0.0 0.8 0.0], 'faceAlpha', 0.7); % drawPlane3d(plane, 'facecolor', 'm', 'faceAlpha', 0.5); % % compute and display intersection % [curves, closed] = intersectPlaneMesh(plane, v, f); % drawPolyline3d(curves(~closed), 'linewidth', 2, 'color', 'b') % % % See also % meshes3d, intersectPlanes, intersectEdgePlane % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-07-31, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform e = []; if isstruct(v) f = v.faces; if isfield(v, 'edges') e = v.edges; end v = v.vertices; end %% Computation of crossing edges % compute the edge list if isempty(e) e = meshEdges(f); end edges = [ v(e(:,1), :) v(e(:,2), :) ]; % identify which edges cross the mesh inds = isBelowPlane(v, plane); edgeCrossInds = find(sum(inds(e), 2) == 1); % compute one intersection point for each edge intersectionPoints = intersectEdgePlane(edges(edgeCrossInds, :), plane); %% mapping edges <-> faces % identify for each face the indices of edges that intersect the plane, as % well as for each edge, the indices of the two faces around it. % We expect each face to contain either 0 or 2 intersecting edges. % nFaces = length(f); faceEdges = cell(1, nFaces); nCrossEdges = length(edgeCrossInds); crossEdgeFaces = cell(nCrossEdges, 1); for iEdge = 1:length(edgeCrossInds) % identify index of faces adjacent to edge edge = e(edgeCrossInds(iEdge), :); indFaces = find(sum(ismember(f, edge), 2) == 2); % assert mesh is manifold (no edge connected to more than three faces) if length(indFaces) > 2 error('crossing edge %d (%d,%d) is associated to %d faces', ... iEdge, edge(1), edge(2), length(indFaces)); end crossEdgeFaces{iEdge} = indFaces; % add current edge to list of edges associated to each face for iFace = 1:length(indFaces) indEdges = faceEdges{indFaces(iFace)}; indEdges = [indEdges iEdge]; %#ok faceEdges{indFaces(iFace)} = indEdges; end end % initialize an array indicating which edges need to be processed nCrossEdges = length(edgeCrossInds); remainingCrossEdges = true(nCrossEdges, 1); %% Iterate on edges and faces to form open poylines % create empty cell array of open polylines openPolys = {}; % identify crossing edges at extremity of open polylines extremityEdgeInds = find(cellfun(@length, crossEdgeFaces) == 1); remainingExtremities = true(length(extremityEdgeInds), 1); % iterate while there are remaining extremity crossing edges while any(remainingExtremities) % start from arbitrary remaining extremity extremityIndex = find(remainingExtremities, 1, 'first'); remainingExtremities(extremityIndex) = false; % use extremity as current edge startEdgeIndex = extremityEdgeInds(extremityIndex); currentEdgeIndex = startEdgeIndex; % mark current edge as processed remainingCrossEdges(currentEdgeIndex) = false; % initialize new set of edge indices polyEdgeInds = currentEdgeIndex; % find the unique face adjacent to current edge edgeFaces = crossEdgeFaces{currentEdgeIndex}; currentFace = edgeFaces(1); % iterate along current face-edge couples until back to first edge while true % find the index of next crossing edge inds = faceEdges{currentFace}; currentEdgeIndex = inds(inds ~= currentEdgeIndex); % add index of current edge polyEdgeInds = [polyEdgeInds currentEdgeIndex]; %#ok % mark current edge as processed remainingCrossEdges(currentEdgeIndex) = false; % find the index of the other face containing current edge inds = crossEdgeFaces{currentEdgeIndex}; % check if we found an extremity edge if length(inds) == 1 ind = extremityEdgeInds == currentEdgeIndex; remainingExtremities(ind) = false; break; end % switch to next face currentFace = inds(inds ~= currentFace); end % create polygon, and add it to list of polygons poly = intersectionPoints(polyEdgeInds, :); openPolys = [openPolys, {poly}]; %#ok end %% Iterate on edges and faces to form closed polylines % create empty cell array of polygons rings = {}; % iterate while there are some crossing edges to process while any(remainingCrossEdges) % start at any edge, mark it as current startEdgeIndex = find(remainingCrossEdges, 1, 'first'); currentEdgeIndex = startEdgeIndex; % mark current edge as processed remainingCrossEdges(currentEdgeIndex) = false; % initialize new set of edge indices polyEdgeInds = currentEdgeIndex; % choose one of the two faces around the edge edgeFaces = crossEdgeFaces{currentEdgeIndex}; currentFace = edgeFaces(1); % iterate along current face-edge couples until back to first edge while true % find the index of next crossing edge inds = faceEdges{currentFace}; currentEdgeIndex = inds(inds ~= currentEdgeIndex); % mark current edge as processed remainingCrossEdges(currentEdgeIndex) = false; % check end of current loop if currentEdgeIndex == startEdgeIndex break; end % add index of current edge polyEdgeInds = [polyEdgeInds currentEdgeIndex]; %#ok % find the index of the other face containing current edge inds = crossEdgeFaces{currentEdgeIndex}; currentFace = inds(inds ~= currentFace); end % create polygon, and add it to list of polygons poly = intersectionPoints(polyEdgeInds, :); rings = [rings, {poly}]; %#ok end %% Format output array polys = [rings, openPolys]; closedFlag = [true(1, length(rings)), false(1, length(openPolys))]; matgeom-1.2.4/inst/meshes3d/PaxHeaders/smoothMeshFunction.m0000644000000000000000000000013214576357161020746 xustar0030 mtime=1710874225.146193336 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/smoothMeshFunction.m0000644000175000017500000000546514576357161022540 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function f = smoothMeshFunction(vertices, faces, f, varargin) %#ok %SMOOTHMESHFUNCTION Apply smoothing on a functions defines on mesh vertices. % % FS = smoothMeshFunction(VERTICES, FACES, F, NITERS) % Performs smoothing on the function F defined on vertices of the mesh. % The mesh is specified by VERTICES and FACES array. At each iteration, % the value for each vertex is obtained as the average of values obtained % from neighbor vertices. % NITERS is the number of times the iteration must be repeated. By % default it equals 3. % % Example % smoothMeshFunction % % See also % meshes3d, meshCurvatures % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2021-09-22, using Matlab 9.10.0.1684407 (R2021a) Update 3 % Copyright 2021-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % determines number of iterations nIters = 3; if ~isempty(varargin) nIters = varargin{1}; end % apply smoothing on scalar function nv = max(faces(:)); % compute normalized averaging matrix W = meshAdjacencyMatrix(faces) + speye(nv); D = spdiags(full(sum(W,2).^(-1)), 0, nv, nv); W = D * W; % do averaging to smooth the field for j = 1:size(f, 2) for k = 1:nIters f(:,j) = W * f(:,j); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFacePolygons.m0000644000000000000000000000013214576357161020360 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.146193336 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFacePolygons.m0000644000175000017500000000513614576357161022145 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polys = meshFacePolygons(varargin) %MESHFACEPOLYGONS Returns the set of polygons that constitutes a mesh. % % POLYGONS = meshFacePolygons(V, F) % POLYGONS = meshFacePolygons(MESH) % % Example % [v f] = createCubeOctahedron; % polygons = meshFacePolygons(v, f); % areas = polygonArea3d(polygons); % sum(areas) % ans = % 18.9282 % % See also % meshes3d, meshFace, polygonArea3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-08-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % extract vertices and faces [v, f] = parseMeshData(varargin{:}); % number of faces if iscell(f) nFaces = length(f); else nFaces = size(f, 1); end % allocate cell array for result polys = cell(nFaces, 1); % compute polygon corresponding to each face if iscell(f) for i = 1:nFaces polys{i} = v(f{i}, :); end else for i = 1:nFaces polys{i} = v(f(i,:), :); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/intersectEdgeMesh3d.m0000644000000000000000000000013214576357161020743 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/intersectEdgeMesh3d.m0000644000175000017500000000556114576357161022532 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [points, pos, faceInds] = intersectEdgeMesh3d(edge, varargin) %INTERSECTEDGEMESH3D Intersection points of a 3D edge with a mesh. % % INTERS = intersectEdgeMesh3d(EDGE, VERTICES, FACES) % Compute the intersection points between a 3D edge and a 3D mesh defined % by vertices and faces. % % [INTERS, POS, INDS] = intersectEdgeMesh3d(EDGE, VERTICES, FACES) % Also returns the position of each intersection point on the input edge, % and the index of the intersected faces. % For edges, the values of POS are expected to be comprised between 0 and % 1. % % Example % [V, F] = createCube; % edge = [-1 0.5 0.5 +3 0.5 0.5]; % pts = intersectEdgeMesh3d(edge, V, F) % pts = % 1.0000 0.5000 0.5000 % 0 0.5000 0.5000 % % See also % meshes3d, interesectLineMesh3d, triangulateFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2021-02-24, using Matlab 9.9.0.1570001 (R2020b) Update 4 % Copyright 2021-2023 INRA - Cepia Software Platform % perform computation on supporting line line = edgeToLine3d(edge); [points, pos, faceInds] = intersectLineMesh3d(line, varargin{:}); % identifies intersection points within parameterization bounds inds = pos >= 0 & pos <= 1; % select relevant results points = points(inds, :); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFaceAdjacency.m0000644000000000000000000000013214576357161020427 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFaceAdjacency.m0000644000175000017500000000523714576357161022216 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function adjList = meshFaceAdjacency(vertices, edges, faces) %MESHFACEADJACENCY Compute adjacency list of face around each face. % % % Example % % Create a sample 3D mesh % [v, e, f] = createDodecahedron; % adjList = meshFaceAdjacency(v, e, f); % figure; hold on; axis equal; view([100 40]); % drawMesh(v, f); % % draw sample face in a different color % drawMesh(v, f(1, :), 'faceColor', 'b'); % % draw the neighbors of a sample face % drawMesh(v, f(adjList{1}, :), 'faceColor', 'g') % % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform edgeFaceList = meshEdgeFaces(vertices, edges, faces); % allocate memory for adjacency list nFaces = max(edgeFaceList(:)); adjList = cell(1, nFaces); % iterate over edges to populate adjacency list for iEdge = 1:size(edgeFaceList) f1 = edgeFaceList(iEdge, 1); f2 = edgeFaceList(iEdge, 2); adjList{f1} = [adjList{f1} f2]; adjList{f2} = [adjList{f2} f1]; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/removeMeshFaces.m0000644000000000000000000000013214576357161020166 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/removeMeshFaces.m0000644000175000017500000000706614576357161021757 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = removeMeshFaces(v, f, fI) %REMOVEMESHFACES Remove faces from a mesh by face indices. % [V2, F2] = removeMeshFaces(V, F, FI) removes faces from the mesh by % the face indices FI into faces F of the mesh. The mesh is represented % by the vertex array V and the face array F. The result is the new set % of vertices V2 and faces F2 without the faces indexed by FI. FI can be % either a linear or a logical index. % % [V2, F2] = removeMeshFaces(MESH, FI) with the struct MESH containing % the fields "vertices" (V) and "faces" (F) % % MESH2 = removeMeshFaces(V, F, FI) with the struct MESH2 containing the % fields "vertices" (V2) and "faces" (F2) % % MESH2 = removeMeshFaces(MESH, FI) with the structs MESH and MESH2 % containing the fields "vertices" (V, V2) and "faces" (F, F2) % % Example % [v, f] = createSoccerBall; % f = triangulateFaces(f); % fI = true(length(f),1); % fI(1:length(f)/2) = false; % [v2, f2] = removeMeshFaces(v, f, fI); % drawMesh(v, f, 'faceColor', 'none', 'faceAlpha', .2); % drawMesh(v2, f2, 'faceAlpha', .7); % view(3); axis equal % % See also % meshes3d, drawMesh % ------ % Authors: oqilipo, David Legland % E-mail: david.legland@inrae.fr % Created: 2017-07-04 % Copyright 2017-2023 % parse inputs narginchk(2,3) nargoutchk(1,2) if nargin == 2 fI = f; [v, f] = parseMeshData(v); end p = inputParser; isIndexToFaces = @(x) ... (islogical(x) && isequal(length(x), size(f,1))) || ... (all(floor(x)==x) && min(x)>=1 && max(x)<=size(f,1)); addRequired(p,'fI',isIndexToFaces) parse(p, fI); if ~islogical(p.Results.fI) fI=false(size(f,1),1); fI(p.Results.fI)=true; else fI=p.Results.fI; end % algorithm f2 = f(~fI,:); [unqVertIds, ~, newVertIndices] = unique(f2); v2 = v(unqVertIds,:); f2 = reshape(newVertIndices,size(f2)); % parse outputs if nargout == 1 mesh2.vertices=v2; mesh2.faces=f2; varargout{1}=mesh2; else varargout{1}=v2; varargout{2}=f2; end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshVertexClustering.m0000644000000000000000000000013214576357161021304 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshVertexClustering.m0000644000175000017500000001112514576357161023064 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = meshVertexClustering(vertices, faces, spacing, varargin) %MESHVERTEXCLUSTERING Simplifies a mesh using vertex clustering. % % [V2, F2] = meshVertexClustering(V, F, SPACING) % [V2, F2] = meshVertexClustering(MESH, SPACING) % MESH2 = meshVertexClustering(...) % % Simplifies a mesh using vertex clustering. Input mesh is specified % either by a pair V, F containing the vertex coordinates and the faces % informations, or by a structure with fields 'vertices' and 'faces'. % % The SPACING input defines the size of the grid. It can be either a % scalar (uniform grid) or a 1-by-3 row vector. % % The output is specified either in two outputs, or in a structure with % fields 'vertices' and 'faces'. % % Example % [x, y, z] = meshgrid(1:100, 1:100, 1:100); % img = hypot3(x-51.12, y-52.23, z-53.34); % [faces, vertices] = isosurface(img, 45); % [v2, f2] = meshVertexClustering(vertices, faces, 10); % figure; axis equal; axis([0 100 0 100 0 100]); % drawMesh(v2, f2); % % See also % reducepatch, smoothMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-28, using Matlab 9.5.0.944444 (R2018b) % Copyright 2019-2023 INRA - Cepia Software Platform %% Initialisation if isstruct(vertices) if nargin > 2 varargin = [{spacing} varargin(:)]; end spacing = faces; mesh = vertices; vertices = mesh.vertices; faces = mesh.faces; end % ensure input mesh is a triangulation faces = triangulateFaces(faces); % ensure spacing is a 1-by-3 array if isscalar(spacing) spacing = [spacing spacing spacing]; end % extract grid origin origin = [0 0 0]; if ~isempty(varargin) origin = varargin{1}; end %% Apply grid simplification % identify the vertices belonging to the same grid [v2, I, J] = unique(round(bsxfun(@rdivide, bsxfun(@minus, vertices, origin), spacing)), 'rows'); %% compute reduced vertex coordinates % compute coordinates of new vertices for iVertex = 1:length(I) gridVertices = vertices(J == iVertex, :); v2(iVertex, :) = mean(gridVertices, 1); end %% Compute new faces % create empty array faces2 = zeros(0, 3); % iterate over old faces, and keep only faces whose vertices belong to % different cell grids nFaces = size(faces, 1); for iFace = 1:nFaces % current face face = faces(iFace, :); % equivalent face with new vertices face2 = J(face)'; % some vertices may belong to same cell, so we need to adjust % processing nInds = length(unique(face2)); if nInds == 3 % vertices belong to three different cells -> create a new face % keep smaller vertex at first position [tmp, indMin] = min(face2); %#ok face2 = circshift(face2, [1-indMin 0]); % append the new face to the array faces2 = [faces2 ; face2]; %#ok end end % remove duplicate faces faces2 = unique(faces2, 'rows'); if nargout == 1 varargout{1} = struct('vertices', v2, 'faces', faces2); else varargout = {v2, faces2}; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createSoccerBall.m0000644000000000000000000000013214576357161020307 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createSoccerBall.m0000644000175000017500000000506014576357161022070 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createSoccerBall() %CREATESOCCERBALL Create a 3D mesh representing a soccer ball. % % It is basically a wrapper of the 'bucky' function in matlab. % [V, E, F] = createSoccerBall % return vertices, edges and faces that constitute a soccerball % V is a 60-by-3 array containing vertex coordinates % E is a 90-by-2 array containing indices of neighbor vertices % F is a 32-by-1 cell array containing vertex indices of each face % Example % [v, f] = createSoccerBall; % drawMesh(v, f); % % See also % meshes, drawMesh, bucky % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-08-09 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % get vertices and adjacency matrix of the buckyball [b, n] = bucky; % compute edges [i, j] = find(b); e = [i j]; e = unique(sort(e, 2), 'rows'); % compute polygons that correspond to each 3D face f = minConvexHull(n)'; % format output varargout = formatMeshOutput(nargout, n, e, f); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshEdgeFaces.m0000644000000000000000000000013214576357161017575 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshEdgeFaces.m0000644000175000017500000001164214576357161021361 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edgeFaces = meshEdgeFaces(vertices, edges, faces) %#ok %MESHEDGEFACES Compute index of faces adjacent to each edge of a mesh. % % EF = meshEdgeFaces(V, E, F) % Compute index array of faces adjacent to each edge of a mesh. % V, E and F define the mesh: V is vertex array, E contains vertex % indices of edge extremities, and F contains vertex indices of each % face, either as a numerical array or as a cell array. % The result EF has as many rows as the number of edges, and two column. % The first column contains index of faces located on the left of the % corresponding edge, whereas the second column contains index of the % face located on the right. Some indices may be 0 if the mesh is not % 'closed'. % % Note: a faster version is available for triangular meshes. % % Example % meshEdgeFaces % % See also % meshes3d, trimeshEdgeFaces, meshDihedralAngles, polyhedronMeanBreadth % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform Ne = size(edges, 1); % indices of faces adjacent to each edge edgeFaces = zeros(Ne, 2); % different method for extracting current face depending if faces are % stored as index 2D array or as cell array of 1D arrays. if isnumeric(faces) Nf = size(faces, 1); for i = 1:Nf face = faces(i, :); processFace(face, i) end elseif iscell(faces) Nf = length(faces); for i = 1:Nf face = faces{i}; processFace(face, i) end end function processFace(face, indFace) % iterate on face edges for j = 1:length(face) % build edge: array of vertices j2 = mod(j, length(face)) + 1; % do not process edges with same vertices if face(j) == face(j2) continue; end % vertex indices of current edge currentEdge = [face(j) face(j2)]; % find index of current edge, assuming face is left-located b1 = ismember(edges, currentEdge, 'rows'); indEdge = find(b1); if ~isempty(indEdge) if edgeFaces(indEdge, 1) ~= 0 error('meshes3d:IllegalTopology', ... 'Two faces were found on left side of edge %d ', indEdge); end edgeFaces(indEdge, 1) = indFace; continue; end % otherwise, assume the face is right-located b2 = ismember(edges, currentEdge([2 1]), 'rows'); indEdge = find(b2); if ~isempty(indEdge) if edgeFaces(indEdge, 2) ~= 0 error('meshes3d:IllegalTopology', ... 'Two faces were found on left side of edge %d ', indEdge); end edgeFaces(indEdge, 2) = indFace; continue; end % If face was neither left nor right, error warning('meshes3d:IllegalTopology', ... 'Edge %d of face %d was not found in edge array', ... j, indFace); continue; end end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/intersectLineMesh3d.m0000644000000000000000000000013214576357161020766 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/intersectLineMesh3d.m0000644000175000017500000001304714576357161022553 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [points, pos, faceInds, lineInds] = intersectLineMesh3d(line, vertices, varargin) %INTERSECTLINEMESH3D Intersection points of a 3D line with a mesh. % % INTERS = intersectLineMesh3d(LINE, VERTICES, FACES) % Compute the intersection points between a 3D line and a 3D mesh defined % by vertices and faces. The mesh data is provided as a pair of arrays, % with VERTICES being a NV-by-3 array of vertex coordinates, and FACES % being a NF-by-3 or NF-by-4 array of face vertex indices. % The LINE data correspond to a 1-by-6 row vector concatenating the line % origin and direction. LINE can also be a NL-by-6 array representing a % collection of lines with various origins and directions. % % INTERS = intersectLineMesh3d(LINE, MESH) % Provides the mesh data as a struct with the fields 'vertices' and % 'faces'. % % [INTERS, POS, IFACES] = intersectLineMesh3d(...) % Also returns the position of each intersection point on the input line, % and the index of the intersected faces. % If POS > 0, the point is also on the ray corresponding to the line. % % [INTERS, POS, IFACES, ILINES] = intersectLineMesh3d(...) % Also returns the index of the line each intersection point belong to. % % Example % [V, F] = createCube; % line = [.2 .3 .4 1 0 0]; % pts = intersectLineMesh3d(line, V, F) % pts = % 1.0000 0.3000 0.4000 % 0 0.3000 0.4000 % % See also % meshes3d, triangulateFaces, intersectLineTriangle3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % tolerance for detecting if a point is on line or within edge bounds tol = 1e-12; % parsing if ~isempty(varargin) if isscalar(varargin{1}) tol = varargin{1}; [vertices, faces] = parseMeshData(vertices); else faces = varargin{1}; varargin(1) = []; if ~isempty(varargin) tol = varargin{1}; end end else [vertices, faces] = parseMeshData(vertices); end % ensure the mesh has triangular faces tri2Face = []; if iscell(faces) || size(faces, 2) ~= 3 [faces, tri2Face] = triangulateFaces(faces); end % find triangle edge vectors t0 = vertices(faces(:,1), :); u = vertices(faces(:,2), :) - t0; v = vertices(faces(:,3), :) - t0; % triangle normal n = crossProduct3d(u, v); % direction vectors of lines and origins of lines dv = permute(line(:,4:6), [3 2 1]); d0 = permute(line(:,1:3), [3 2 1]); % vector between triangle origin and line origin w0 = d0 - t0; a = -sum(n .* w0, 2); % negative dot product b = sum(n .* dv, 2); % dot product valid = abs(b) > tol & vectorNorm3d(n) > tol; % compute intersection point of line with supporting plane % If pos < 0: point before ray % IF pos > |dir|: point after edge pos = a ./ b; % coordinates of intersection point points = d0 + (pos .* dv); %% test if intersection point is inside triangle % normalize direction vectors of triangle edges uu = dot(u, u, 2); uv = dot(u, v, 2); vv = dot(v, v, 2); % coordinates of vector v in triangle basis w = points - t0; wu = sum(w .* u, 2); wv = sum(w .* v, 2); % normalization constant D = uv.^2 - uu .* vv; % test first coordinate s = (uv .* wv - vv .* wu) ./ D; ind1 = s < -tol | s > (1.0 + tol); % test second coordinate, and third triangle edge t = (uv .* wu - uu .* wv) ./ D; ind2 = t < -tol | (s + t) > (1.0 + tol); % keep only interesting points inds = ~ind1 & ~ind2 & valid; [faceInds, lineInds] = find(permute(inds, [1 3 2])); % Bit of an indexing trick to get points in appropriate order points = points(sub2ind(size(points), ... faceInds+[0 0 0], faceInds*0+(1:3), lineInds+[0 0 0]) ); if nargout > 1 pos = pos(inds); % convert to face indices of original mesh if ~isempty(tri2Face) faceInds = tri2Face(faceInds); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/steinerPolytope.m0000644000000000000000000000013214576357161020317 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/steinerPolytope.m0000644000175000017500000000633014576357161022101 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [vertices, faces] = steinerPolytope(vectors) %STEINERPOLYTOPE Create a steiner polytope from a set of vectors. % % [VERTICES FACES] = steinerPolygon(VECTORS) % Creates the Steiner polytope defined by the set of vectors VECTORS. % % Example % % Creates and display a planar Steiner polytope (ie, a polygon) % [v f] = steinerPolytope([1 0;0 1;1 1]); % fillPolygon(v); % % % Creates and display a 3D Steiner polytope % [v f] = steinerPolytope([1 0 0;0 1 0;0 0 1;1 1 1]); % drawMesh(v, f); % view(3); axis vis3d % % See also % meshes3d, drawMesh, steinerPolygon, mergeCoplanarFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-04-28 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % compute vectors dimension nd = size(vectors, 2); % create candidate vertices vertices = zeros(1, size(vectors, 2)); for i = 1:length(vectors) nv = size(vertices, 1); vertices = [vertices; vertices+repmat(vectors(i,:), [nv 1])]; %#ok end if nd == 2 % for planar case, use specific function convhull K = convhull(vertices(:,1), vertices(:,2)); vertices = vertices(K, :); faces = 1:length(K); else % Process the general case (tested only for nd==3) % compute convex hull K = convhulln(vertices); % keep only relevant points, and update faces indices ind = unique(K); for i = 1:length(ind) K(K==ind(i)) = i; end % return results vertices = vertices(ind, :); faces = K; % in case of 3D meshes, merge coplanar faces if nd == 3 faces = mergeCoplanarFaces(vertices, faces); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/writeMesh_ply.m0000644000000000000000000000013214576357161017745 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/writeMesh_ply.m0000644000175000017500000001262414576357161021532 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function writeMesh_ply(fileName, vertices, faces, varargin) %WRITEMESH_PLY Write a mesh into a file in PLY format. % % writeMesh_ply(FNAME, VERTICES, FACES) % % writeMesh_ply(FNAME, MESH) % % writeMesh_ply(..., FORMAT) also specifies a file format for the written % file. FORMAT can be either 'binary' (default) or 'ascii'. % % Example % mesh = createSoccerBall; % fileName = 'SoccerBall.ply'; % writeMesh_ply(fileName, mesh, 'Bin'); % mesh2 = readMesh(fileName); % drawMesh(mesh2); axis equal % % See also % meshes3d, writeMesh, readMesh_ply, writeMesh_off, writeMesh_stl % ------ % Author: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2018-04-26, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018-2023 INRA - Cepia Software Platform %% Check inputs % optionnaly parses data if isstruct(vertices) if nargin > 2 varargin = [{faces} varargin{:}]; end faces = vertices.faces; vertices = vertices.vertices; end % Parsing p = inputParser; addRequired(p,'fileName',@(x) validateattributes(x,{'char'},{'nonempty'})); suppModes = {'ascii','binary_little_endian'}; addOptional(p,'mode','binary_little_endian',@(x) any(validatestring(x,suppModes))); parse(p,fileName,varargin{:}); fileName = p.Results.fileName; mode = suppModes{startsWith(suppModes, p.Results.mode, 'IgnoreCase',1)}; %% Initializations % number of vertices and faces nVertices = size(vertices, 1); nFaces = size(faces, 1); if iscell(faces) nFaces = length(faces); end % open file for writing text f = fopen(fileName, 'wt'); if (f == -1) error('Couldn''t open the file %s', fileName); end %% Write Header % write the header line fprintf(f, 'ply\n'); % write format (only ASCII supported) fprintf(f, 'format %s 1.0\n', mode); % some comments fprintf(f, 'comment Created by MatGeom for MATLAB\n'); % write declaration for vertices fprintf(f, 'element vertex %d\n', nVertices); fprintf(f, 'property double x\n'); fprintf(f, 'property double y\n'); fprintf(f, 'property double z\n'); % write declaration for faces fprintf(f, 'element face %d\n', nFaces); fprintf(f, 'property list int int vertex_index\n'); % end of header fprintf(f, 'end_header\n'); %% Write data switch mode case 'ascii' % write vertex info format = '%0.17f %0.17f %0.17f\n'; fprintf(f, format, vertices'); % write face info if isnumeric(faces) % simply write face vertex indices ns = size(faces, 2); plyFaces = [ns * ones(nFaces, 1) faces-1]; format = ['%d' repmat(' %d', 1, ns) '\n']; fprintf(f, format, plyFaces'); else % if faces are stored in a cell array, the number of vertices in each % face may be different, and we need to process each face individually for iFace = 1:nFaces ns = length(faces{iFace}); format = ['%d' repmat(' %d', 1, ns) '\n']; fprintf(f, format, ns, faces{iFace} - 1); end end case 'binary_little_endian' % close the file fclose(f); % open file with little-endian format f = fopen(fileName,'a','ieee-le'); % write vertex info fwrite(f, vertices', 'double'); % write face info if isnumeric(faces) % simply write face vertex indices plyFaces = [size(faces, 2) * ones(nFaces, 1) faces-1]; fwrite(f, plyFaces', 'int'); else % if faces are stored in a cell array, the number of vertices in each % face may be different, and we need to process each face individually for iFace = 1:nFaces fwrite(f, [length(faces{iFace}), faces{iFace}-1], 'int'); end end otherwise error(['Format ''' mode ''' is not supported']) end % close the file fclose(f); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/torusMesh.m0000644000000000000000000000013214576357161017103 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/torusMesh.m0000644000175000017500000001025214576357161020663 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = torusMesh(torus, varargin) %TORUSMESH Create a 3D mesh representing a torus. % % [V, F] = torusMesh(TORUS) % Converts the torus in TORUS into a face-vertex quadrangular mesh. % TORUS is given by [XC YC ZY R1 R2 THETA PHI] % where (XC YZ ZC) is the center of the torus, R1 is the main radius, R2 % is the radius of the torus section, and (THETA PHI) is the angle of the % torus normal vector (both in degrees). % % [V, F] = torusMesh(TORUS, 'nTheta', NT, 'nPhi', NP) % Creates a mesh using NP circles, each circle being discretized with NT % vertices. Default are 60 for both parameters. % % [V, F] = torusMesh() % Creates a mesh representing a default torus. % % Example % [v, f] = torusMesh([50 50 50 30 10 30 45]); % figure; drawMesh(v, f, 'linestyle', 'none'); % view(3); axis equal; % lighting gouraud; light; % % % See also % meshes3d, drawTorus, revolutionSurface, cylinderMesh, sphereMesh % drawMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-10-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform %% Extract data for torus % check input number if nargin == 0 torus = [0 0 0 30 10 0 0]; elseif ischar(torus) varargin = [{torus} varargin]; torus = [0 0 0 30 10 0 0]; end if isnumeric(torus) && size(torus, 2) ~= 7 error('First argument must be a numeric row vector with 7 elements'); end center = torus(1:3); r1 = torus(4); r2 = torus(5); if size(torus, 2) >= 7 normal = torus(6:7); end %% Extract data for discretisation % number nTheta = 60; nPhi = 60; while length(varargin) > 1 argName = varargin{1}; switch lower(argName) case 'ntheta' nTheta = varargin{2}; case 'nphi' nPhi = varargin{2}; otherwise error('Unknown optional argument: %s', argName); end varargin(1:2) = []; end %% Discretize torus % create base circle (duplicate last vertex to manage mesh periodicity) circle = circleToPolygon([r1 0 r2], nTheta); circle = circle([1:end 1], :); % create rotation angle list (duplicate last one to manage mesh periodicity) phiList = linspace(0, 2*pi, nPhi + 1); [x, y, z] = revolutionSurface(circle, phiList); % transform torus trans = localToGlobal3d([center normal]); [x, y, z] = transformPoint3d(x, y, z, trans); % convert to FV mesh [vertices, faces] = surfToMesh(x, y, z, 'xPeriodic', true, 'yPeriodic', true); % format output varargout = formatMeshOutput(nargout, vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/sphereMesh.m0000644000000000000000000000013214576357161017215 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/sphereMesh.m0000644000175000017500000000672314576357161021005 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = sphereMesh(sphere, varargin) %SPHEREMESH Create a 3D mesh representing a sphere. % % [V, F] = sphereMesh(S) % Creates a 3D mesh representing the sphere S given by [xc yc zy r]. % % [V, F] = sphereMesh(); % Assumes sphere is the unit sphere centered at the origin. % % [V, F] = sphereMesh(S, 'nTheta', NT, 'nPhi', NP); % Specifies the number of discretisation steps for the meridians and the % parallels. Default values are nTheta = 16 and nPhi = 32. % % % Example % s = [10 20 30 40]; % [v, f] = sphereMesh(s); % drawMesh(v, f); % view(3); axis equal; light; lighting gouraud; % % See also % meshes3d, drawSphere, ellipsoidMesh, cylinderMesh, surfToMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-10-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform if nargin == 0 sphere = [0 0 0 1]; end % number of meridians nPhi = 32; % number of parallels nTheta = 16; % process input arguments while length(varargin) > 1 paramName = varargin{1}; switch lower(paramName) case 'ntheta', nTheta = varargin{2}; case 'nphi', nPhi = varargin{2}; otherwise error(['Could not recognise parameter: ' paramName]); end varargin(1:2) = []; end % extract sphere data xc = sphere(:,1); yc = sphere(:,2); zc = sphere(:,3); r = sphere(:,4); % compute spherical coordinates theta = linspace(0, pi, nTheta+1); phi = linspace(0, 2*pi, nPhi+1); % convert to cartesian coordinates sintheta = sin(theta); x = xc + cos(phi') * sintheta * r; y = yc + sin(phi') * sintheta * r; z = zc + ones(length(phi),1) * cos(theta) * r; % convert to FV mesh [vertices, faces] = surfToMesh(x, y, z, 'yperiodic', true); % format output varargout = formatMeshOutput(nargout, vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/subdivideMesh.m0000644000000000000000000000013214576357161017705 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/subdivideMesh.m0000644000175000017500000001732614576357161021476 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = subdivideMesh(vertices, faces, n) %SUBDIVIDEMESH Subdivides each face of the mesh. % % [V2 F2] = subdivideMesh(V, F, N) % Subdivides the mesh specified by (V,F) such that each face F is divided % into N^2 smaller faces. % % Example % [v, f] = createOctahedron; % figure; drawMesh(v, f); view(3); % [v2, f2] = subdivideMesh(v, f, 4); % figure; drawMesh(v2, f2); view(3) % % See also % meshes3d, drawMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-08-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform %% Initialisations % vertex to vertex edges, will be computed if not provided within mesh % structure edges = []; % The face-to-edge adjacency information is necessary for associating new % faces to vertices (will be computed if not found) faceEdgeIndices = []; % if mesh is provided as structure, retrieve all possible data if isstruct(vertices) % get relevant inputs mesh = vertices; n = faces; % parse fields from a mesh structure vertices = mesh.vertices; faces = mesh.faces; if isfield(mesh, 'edges') edges = mesh.edges; end % The face-to-edge adjacency information is necessary for associating % new faces to vertices % (will be computed if not found) if isfield(mesh, 'faceEdges') faceEdgeIndices = mesh.faceEdges; end end if ~isnumeric(faces) || size(faces, 2) ~= 3 error('Requires a triangular mesh'); end % compute the edge array if isempty(edges) edges = meshEdges(faces); end nEdges = size(edges, 1); % compute index of edges around each face if not already provided if isempty(faceEdgeIndices) faceEdgeIndices = meshFaceEdges(vertices, edges, faces); end %% Process Edges % Create new vertices on existing edges. Each edge is subdivided into n new % edges, creating (n-1) new vertices. % positions to interpolate vertex positions t = linspace(0, 1, n + 1)'; coef2 = t(2:end-1); coef1 = 1 - t(2:end-1); % initialise the array of new vertices vertices2 = vertices; % keep an array containing index of new vertices for each original edge edgeNewVertexIndices = zeros(nEdges, n-1); % create new vertices on each edge for iEdge = 1:nEdges % extract each extremity as a point v1 = vertices(edges(iEdge, 1), :); v2 = vertices(edges(iEdge, 2), :); % compute new points newPoints = coef1 * v1 + coef2 * v2; % add new vertices, and keep their indices edgeNewVertexIndices(iEdge,:) = size(vertices2, 1) + (1:n-1); vertices2 = [vertices2 ; newPoints]; %#ok end %% Process faces % Subdivide each face, by processing 'strips' on parallel faces. Each strip % rely on two vertices of two edges of the original mesh. % create result array (will grow during face iteration) faces2 = zeros(0, 3); % iterate on faces of original mesh nFaces = size(faces, 1); for iFace = 1:nFaces % compute index of each corner vertex face = faces(iFace, :); iv1 = face(1); iv2 = face(2); iv3 = face(3); % compute index of each edge faceEdges = faceEdgeIndices{iFace}; ie1 = faceEdges(1); ie2 = faceEdges(2); ie3 = faceEdges(3); % indices of new vertices on edges edge1NewVertexIndices = edgeNewVertexIndices(ie1, :); edge2NewVertexIndices = edgeNewVertexIndices(ie2, :); edge3NewVertexIndices = edgeNewVertexIndices(ie3, :); % keep vertex 1 as reference for edges 1 and 3 if edges(ie1, 1) ~= iv1 edge1NewVertexIndices = edge1NewVertexIndices(end:-1:1); end if edges(ie3, 1) ~= iv1 edge3NewVertexIndices = edge3NewVertexIndices(end:-1:1); end % create the first new face, on 'top' of the original face topVertexInds = [edge1NewVertexIndices(1) edge3NewVertexIndices(1)]; newFace = [iv1 topVertexInds]; faces2 = [faces2; newFace]; %#ok % iterate over middle strips for iStrip = 2:n-1 % index of extreme vertices of current row ivr1 = edge1NewVertexIndices(iStrip); ivr2 = edge3NewVertexIndices(iStrip); % extreme vertices as points v1 = vertices2(ivr1, :); v2 = vertices2(ivr2, :); % create additional vertices within the bottom row of the strip t = linspace(0, 1, iStrip+1)'; coef2 = t(2:end-1); coef1 = 1 - t(2:end-1); newPoints = coef1 * v1 + coef2 * v2; % compute indices of new vertices in result array newInds = size(vertices2, 1) + (1:iStrip-1); botVertexInds = [ivr1 newInds ivr2]; % add new vertices vertices2 = [vertices2 ; newPoints]; %#ok % create top faces of current strip for k = 1:iStrip-1 newFace = [topVertexInds(k) botVertexInds(k+1) topVertexInds(k+1)]; faces2 = [faces2; newFace]; %#ok end % create bottom faces of current strip for k = 1:iStrip newFace = [topVertexInds(k) botVertexInds(k) botVertexInds(k+1)]; faces2 = [faces2; newFace]; %#ok end % bottom vertices of current strip are top vertices of next strip topVertexInds = botVertexInds; end % for edge 2, keep vertex 2 of the current face as reference if edges(ie2, 1) ~= iv2 edge2NewVertexIndices = edge2NewVertexIndices(end:-1:1); end % consider new vertices together with extremities botVertexInds = [iv2 edge2NewVertexIndices iv3]; % create top faces for last strip for k = 1:n-1 newFace = [topVertexInds(k) botVertexInds(k+1) topVertexInds(k+1)]; faces2 = [faces2; newFace]; %#ok end % create bottom faces for last strip for k = 1:n newFace = [topVertexInds(k) botVertexInds(k) botVertexInds(k+1)]; faces2 = [faces2; newFace]; %#ok end end %% Post-processing % setup output arguments varargout = formatMeshOutput(nargout, vertices2, faces2); matgeom-1.2.4/inst/meshes3d/PaxHeaders/circleMesh.m0000644000000000000000000000013214576357161017170 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/circleMesh.m0000644000175000017500000000720214576357161020751 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = circleMesh(circle, varargin) %CIRCLEMESH Create a mesh defined by a 3D circle. % % [V, F] = cylinderMesh(CYL) % Computes vertex coordinates V and face vertex indices F of a mesh % representing a 3D circle given as [xc yc zc R theta phi psi]. % % [V, F] = cylinderMesh(..., NAME, VALUE); % Specifies one or several options using parameter name-value pairs. % Available options are: % 'nP' the number of points represeting the perimeter % 'nR' the number of points along the radius excluding the center % % Example % c = [10 20 30 50 70 60 50]; % [v, f] = circleMesh(c, 'nP',100, 'nR',50); % figure('color','w'); % drawMesh(v, f, 'facecolor', 'r'); % drawCircle3d(c,'LineWidth',2, 'Color','g'); % view(3); axis equal; % % See also % cylinderMesh, circles3d % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-07-30, using Matlab 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 parser = inputParser; addParameter(parser, 'nP', 60, @(x) validateattributes(x,{'numeric'},... {'integer','scalar','>=',3})); addParameter(parser, 'nR', 10, @(x) validateattributes(x,{'numeric'},... {'integer','scalar','>=',1})); parse(parser, varargin{:}); nP = parser.Results.nP; nR = parser.Results.nR; nR = nR+1; % Radius r = circle(4); % Check that the number of points of the inner circles stay valid if (nP-(nR*2-4))<3 nR = floor(((nP-3)+4)/2); end rr = linspace(0, r, nR); rr = rr(2:end); cp = fliplr(repmat(nP,1,nR-1)-(0:2:2*nR-4)); % Create points of the inner circles and the outer circle center = [0 0]; vertices = nan(sum(cp)+1,2); vertices(1,:) = center; sIdx = 2; eIdx = 1; for i=1:length(rr) eIdx = eIdx+cp(i); vertices(sIdx:eIdx,:) = circleToPolygon([center rr(i)], cp(i)); sIdx = eIdx+1; end % Triangulate points DT = delaunayTriangulation(vertices); faces = DT.ConnectivityList; vertices(:,3) = 0; % Transform points from 2D to 3D tfm = localToGlobal3d([circle(1:3) circle(5:7)]); vertices = transformPoint3d(vertices, tfm); % Format output varargout = formatMeshOutput(nargout, vertices, faces); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/clipConvexPolyhedronByPlane.m0000644000000000000000000000013214576357161022543 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/clipConvexPolyhedronByPlane.m0000644000175000017500000001375014576357161024331 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, faces2] = clipConvexPolyhedronByPlane(nodes, faces, plane) %CLIPCONVEXPOLYHEDRONBYPLANE Clip a convex polyhedron by a plane. % % [NODES2, FACES2] = clipConvexPolyhedronByPlane(NODES, FACES, PLANE) % % return the new (convex) polyhedron whose vertices are 'below' the % specified plane, and with faces clipped accordingly. NODES2 contains % clipped vertices and new created vertices, FACES2 contains references % to NODES2 vertices. % % Example % [N, F] = createCube; % P = createPlane([.5 .5 .5], [1 1 1]); % [N2, F2] = clipConvexPolyhedronByPlane(N, F, P); % figure('color','w'); view(3); axis equal % drawPolyhedron(N2, F2); % % [v, f] = createSoccerBall; % p = createPlane([-.5 .5 -.5], [1 1 1]); % [v2, f2] = clipConvexPolyhedronByPlane(v, f, p); % figure('color','w'); view(3); axis equal % drawMesh(v, f, 'faceColor', 'none'); % drawMesh(v2, f2); % % See also % meshes3d, polyhedra, planes3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-09-14, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas %% Preprocessing % used for identifying identical vertices tol = 1e-10; % if faces is a numeric array, convert it to cell array if isnumeric(faces) faces2 = cell(size(faces, 1), 1); for f = 1:length(faces2) faces2{f} = faces(f,:); end faces = faces2; end % find vertices below the plane b = isBelowPlane(nodes, plane); % initialize results Nn = size(nodes, 1); nodes2 = zeros(0, 3); % list of new nodes faces2 = faces; % list of new faces. Start with initial list, and remove some of them %% Main iteration on faces % iterate on each face, and test if either: % - all points below plane -> keep all face % - all points up plane -> remove face % - both -> clip the polygon keep = true(length(faces), 1); for f = 1:length(faces) % current face face = faces{f}; bf = b(face); % face totally above plane if sum(bf) == 0 keep(f) = false; continue; end % face totally below plane if sum(bf == 1) == length(bf) continue; end % clip polygon formed by face poly = nodes(face, :); clipped = clipPolygonByPlane3d(poly, plane); % identify indices of polygon vertices inds = zeros(1, size(clipped, 1)); faceb = face(bf==1); % indices of vertices still in clipped face [minDists, I] = minDistancePoints(nodes(faceb,:), clipped); %#ok for i = 1:length(I) inds(I(i)) = faceb(i); end % indices of new points in clipped polygon indNews = find(inds == 0); if size(nodes2, 1) < 2 nodes2 = [nodes2; clipped(indNews, :)]; %#ok inds(indNews(1)) = Nn + 1; inds(indNews(2)) = Nn + 2; faces2{f} = inds; continue; end % distances from new vertices to already added vertices [minDists, I] = minDistancePoints(clipped(indNews, :), nodes2); % compute index of first vertex if minDists(1) < tol inds(indNews(1)) = Nn + I(1); else nodes2 = [nodes2; clipped(indNews(1), :)]; %#ok inds(indNews(1)) = Nn + size(nodes2, 1); end % compute index of second vertex if minDists(2) < tol inds(indNews(2)) = Nn + I(2); else nodes2 = [nodes2; clipped(indNews(2), :)]; %#ok inds(indNews(2)) = Nn + size(nodes2, 1); end % stores the modified face faces2{f} = inds; end %% Postprocessing % creates a new face formed by the added nodes [sortedNodes, I] = angleSort3d(nodes2); % compute normal vector of new face, and reverse order if face points in % the opposite direction as plane normal newFaceNormal = meshFaceNormals(sortedNodes, 1:length(sortedNodes)); if dot(newFaceNormal, planeNormal(plane)) < 0 I(2:end) = I(end:-1:2); end % compute vertex indices of new face newFace = I' + Nn; % remove faces outside plane and add the new face faces2 = {faces2{keep}, newFace}; % remove clipped nodes, and add new nodes to list of nodes N2 = size(nodes2, 1); nodes2 = [nodes(b, :); nodes2]; % new nodes are inside half-space by definition b = [b; ones(N2, 1)]; % create look up table between old indices and new indices inds = zeros(size(nodes2, 1), 1); indb = find(b); for i = 1:length(indb) inds(indb(i)) = i; end % update indices of faces for f = 1:length(faces2) face = faces2{f}; faces2{f} = inds(face)'; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/removeMeshEars.m0000644000000000000000000000013214576357161020037 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/removeMeshEars.m0000644000175000017500000000523114576357161021620 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = removeMeshEars(varargin) %REMOVEMESHEARS Remove vertices that are connected to only one face. % % [V, F] = removeMeshEars(V, F) % [V, F] = removeMeshEars(MESH) % Remove vertices that are connected to only one face. This removes also % "pending" faces. % Note that if the mesh has boundary, this may remove some regular faces % located on the boundary. % % Example % removeMeshEars % % See also % meshes3d, ensureManifoldMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-08, using Matlab 8.6.0.267246 (R2015b) % Copyright 2019-2023 INRA - Cepia Software Platform [vertices, faces] = parseMeshData(varargin{:}); nVertices = size(vertices, 1); % for each vertex, determine the number of faces it belongs to vertexDegree = zeros(nVertices, 1); for iv = 1:nVertices vertexDegree(iv) = sum(sum(faces == iv, 2) > 0); end % remove vertices with degree 1 inds = find(vertexDegree == 1); [vertices, faces] = removeMeshVertices(vertices, faces, inds); %% Format output varargout = formatMeshOutput(nargout, vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/drawPolyhedron.m0000644000000000000000000000013214576357161020113 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/drawPolyhedron.m0000644000175000017500000001054014576357161021673 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawPolyhedron(nodes, faces, varargin) %DRAWPOLYHEDRON Draw polyhedron defined by vertices and faces. % % drawPolyhedron(NODES, FACES) % Draws the polyhedron defined by vertices NODES and the faces FACES. % NODES is a NV-by-3 array containing coordinates of vertices, and FACES % is either a NF-by3 or NF-by-4 array containing indices of vertices of % the triangular or rectangular faces. % FACES can also be a cell array, in the content of each cell is an array % of indices to the nodes of the current face. Faces can have different % number of vertices. % % H = drawPolyhedron(...); % Also returns a handle to the created patche. % % Example: % [n f] = createSoccerBall; % drawPolyhedron(n, f); % % See also % polyhedra, drawMesh, drawPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% Initialisations % process input arguments switch length(varargin) case 0 % default color is red varargin = {'facecolor', [1 0 0]}; case 1 % use argument as color for faces varargin = {'facecolor', varargin{1}}; otherwise % otherwise do nothing end % overwrites on current figure hold on; % if nodes are 2D points, add a z=0 coordinate if size(nodes, 2) == 2 nodes(1,3) = 0; end %% main loop : for each face if iscell(faces) % array FACES is a cell array h = zeros(length(faces(:)), 1); for f = 1:length(faces(:)) % get nodes of the cell face = faces{f}; if sum(isnan(face))~=0 % Special processing in case of multiple polygonal face. % each polygonal loop is separated by a NaN. % find indices of loops breaks inds = find(isnan(face)); % replace NaNs by index of first vertex of each polygon face(inds(2:end)) = face(inds(1:end-1)+1); face(inds(1)) = face(1); face(length(face)+1)= face(inds(end)+1); end % draw current face cnodes = nodes(face, :); h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), [1 0 0]); end else % array FACES is a NC*NV indices array, with NV : number of vertices of % each face, and NC number of faces h = zeros(size(faces, 1), 1); for f = 1:size(faces, 1) % get nodes of the cell cnodes = nodes(faces(f,:)', :); h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), [1 0 0]); end end % set up drawing options if ~isempty(varargin) set(h, varargin{:}); end % format output parameters if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/readMesh_stl.m0000644000000000000000000000013214576357161017524 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/readMesh_stl.m0000644000175000017500000001320614576357161021306 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = readMesh_stl(fName) %READMESH_STL Read mesh data stored in STL format. % % [VERTICES, FACES] = readMesh_stl(FNAME) % % MESH = readMesh_stl(FNAME) % % See also % meshes3d, readMesh, readMesh_off, readMesh_ply, writeMesh_stl % % Source % Functions of the stlTools toolbox by Pau Micó are used for STL files % in ASCII format: % https://mathworks.com/matlabcentral/fileexchange/51200-stltools % MATLAB's build-in stlread is used for STL files in binary format. % ------ % Author: oqilipo % E-mail: N/A % Created: 2021-02-12, using Matlab 9.9.0.1538559 (R2020b) % Copyright 2021-2023 format = stlGetFormat(fName); if strcmp(format,'ascii') [vertices,faces] = stlReadAscii(fName); elseif strcmp(format,'binary') TR = stlread(fName); vertices = TR.Points; faces = TR.ConnectivityList; end varargout = formatMeshOutput(nargout, vertices, faces); end function format = stlGetFormat(fileName) %STLGETFORMAT identifies the format of the STL file and returns 'binary' or %'ascii' fid = fopen(fileName); % Check the file size first, since binary files MUST have a size of 84+(50*n) fseek(fid,0,1); % Go to the end of the file fidSIZE = ftell(fid); % Check the size of the file if rem(fidSIZE-84,50) > 0 format = 'ascii'; else % Files with a size of 84+(50*n), might be either ascii or binary... % Read first 80 characters of the file. % For an ASCII file, the data should begin immediately (give or take a few % blank lines or spaces) and the first word must be 'solid'. % For a binary file, the first 80 characters contains the header. % It is bad practice to begin the header of a binary file with the word % 'solid', so it can be used to identify whether the file is ASCII or % binary. fseek(fid,0,-1); % go to the beginning of the file header = strtrim(char(fread(fid,80,'uchar')')); % trim leading and trailing spaces isSolid = strcmp(header(1:min(5,length(header))),'solid'); % take first 5 char fseek(fid,-80,1); % go to the end of the file minus 80 characters tail = char(fread(fid,80,'uchar')'); isEndSolid = contains(tail,'endsolid'); % Double check by reading the last 80 characters of the file. % For an ASCII file, the data should end (give or take a few % blank lines or spaces) with 'endsolid '. % If the last 80 characters contains the word 'endsolid' then this % confirms that the file is indeed ASCII. if isSolid && isEndSolid format = 'ascii'; else format = 'binary'; end end fclose(fid); end function [v, f, n, name] = stlReadAscii(fileName) %STLREADASCII reads a STL file written in ASCII format %V are the vertices %F are the faces %N are the normals %NAME is the name of the STL object (NOT the name of the STL file) %====================== % STL ascii file format %====================== % ASCII STL files have the following structure. Technically each facet % could be any 2D shape, but in practice only triangular facets tend to be % used. The present code ONLY works for meshes composed of triangular % facets. % % solid object_name % facet normal x y z % outer loop % vertex x y z % vertex x y z % vertex x y z % endloop % endfacet % % % % endsolid object_name fid = fopen(fileName); cellcontent = textscan(fid,'%s','delimiter','\n'); % read all the file and put content in cells content = cellcontent{:}(logical(~strcmp(cellcontent{:},''))); % remove all blank lines fclose(fid); % read the STL name line1 = char(content(1)); if (size(line1,2) >= 7) name = line1(7:end); else name = 'Unnamed Object'; end % read the vector normals normals = char(content(logical(strncmp(content,'facet normal',12)))); n = str2num(normals(:,13:end)); %#ok % read the vertex coordinates (vertices) vertices = char(content(logical(strncmp(content,'vertex',6)))); v = str2num(vertices(:,7:end)); %#ok nvert = size(v,1); % number of vertices nfaces = sum(strcmp(content,'endfacet')); % number of faces if (nvert == 3*nfaces) f = reshape(1:nvert,[3 nfaces])'; % create faces end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/removeInvalidBorderFaces.m0000644000000000000000000000013214576357161022016 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/removeInvalidBorderFaces.m0000644000175000017500000000575314576357161023610 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [vertices, faces] = removeInvalidBorderFaces(varargin) %REMOVEINVALIDBORDERFACES Remove faces whose edges are connected to 3, 3, and 1 faces. % % [V2, F2] = removeInvalidBorderFaces(V, F) % % Example % removeInvalidBorderFaces % % See also % isManifoldMesh, collapseEdgesWithManyFaces % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-31, using Matlab 9.5.0.944444 (R2018b) % Copyright 2019-2023 INRA - Cepia Software Platform vertices = varargin{1}; faces = varargin{2}; % compute edge to vertex array if nargin == 3 edges = faces; faces = varargin{3}; else % compute edge to vertex array edges = meshEdges(faces); end % compute face to edge indices array % as a nFaces-by-3 array (each face connected to exactly three edges) faceEdgeInds = meshFaceEdges(vertices, edges, faces); % compute number of faces incident each edge edgeFaces = trimeshEdgeFaces(faces); edgeFaceDegrees = sum(edgeFaces > 0, 2); % for each face, concatenate the face degree of each edge faceEdgeDegrees = zeros(size(faces, 1), 3); for iFace = 1:size(faces, 1) edgeInds = faceEdgeInds{iFace}; faceEdgeDegrees(iFace, :) = edgeFaceDegrees(edgeInds); end % remove faces containing edges connected to 1 face and edges connected to % 3 faces inds = sum(faceEdgeDegrees == 1, 2) > 0 & sum(faceEdgeDegrees == 3, 2); % inds = sum(ismember(faceEdgeDegrees, [1 3 4]), 2) == 3; faces(inds, :) = []; matgeom-1.2.4/inst/meshes3d/PaxHeaders/polyhedronMeanBreadth.m0000644000000000000000000000013214576357161021370 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/polyhedronMeanBreadth.m0000644000175000017500000000712714576357161023157 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function breadth = polyhedronMeanBreadth(vertices, edges, faces) %POLYHEDRONMEANBREADTH Mean breadth of a convex polyhedron. % % BREADTH = polyhedronMeanBreadth(V, E, F) % Return the mean breadth (average of polyhedron caliper diameter over % all direction) of a convex polyhedron. % % The mean breadth is computed using the sum, over the edges of the % polyhedron, of the edge dihedral angles multiplied by the edge length, % the final sum being divided by (4*PI). % % Note: the function assumes that the faces are correctly oriented. The % face vertices should be indexed counter-clockwise when considering the % supporting plane of the plane, with the outer normal oriented outwards % of the polyhedron. % % Typical values for classical polyhedra are: % cube side a breadth = (3/2)*a % cuboid sides a, b, c breadth = (a+b+c)/2 % tetrahedron side a breadth = 0.9123*a % octaedron side a beradth = 1.175*a % dodecahedron, side a breadth = 15*arctan(2)*a/(2*pi) % icosaehdron, side a breadth = 15*arcsin(2/3)*a/(2*pi) % % Example % [v e f] = createCube; % polyhedronMeanBreadth(v, e, f) % ans = % 1.5 % % See also % meshes3d, meshEdgeFaces, meshDihedralAngles, checkMeshAdjacentFaces % trimeshMeanBreadth % % References % Stoyan D., Kendall W.S., Mecke J. (1995) "Stochastic Geometry and its % Applications", John Wiley and Sons, p. 26 % Ohser, J., Muescklich, F. (2000) "Statistical Analysis of % Microstructures in Materials Sciences", John Wiley and Sons, p.352 % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % compute dihedral angle of each edge alpha = meshDihedralAngles(vertices, edges, faces); % compute length of each edge lengths = meshEdgeLength(vertices, edges); % compute product of length by angles breadth = sum(alpha.*lengths)/(4*pi); matgeom-1.2.4/inst/meshes3d/PaxHeaders/polyhedra.m0000644000000000000000000000013214576357161017101 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/polyhedra.m0000644000175000017500000000564714576357161020675 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polyhedra(varargin) %POLYHEDRA Index of classical polyhedral meshes. % % Polyhedra are specific meshes, with additional assumptions: % * the set of faces is assumed to enclose a single 3D domain % * each face has a neighbor face for each edge % * some functions also assume that normals of all faces point outwards % % Most polyhedron creation functions follow the patterns: % * [V, F] = createXXX(); % returns vertex and face arrays % * [V, E, F] = createXXX(); % returns also edge array % * M = createXXX(); % return a data structure with 'vertices', % % 'edges' and 'faces' fields. % % Example % % create a soccer ball mesh and display it % [n, f] = createSoccerBall; % drawMesh(n, f, 'faceColor', 'g', 'linewidth', 2); % axis equal; % % See also % meshes3d % createCube, createCubeOctahedron, createIcosahedron, createOctahedron % createRhombododecahedron, createTetrahedron, createTetrakaidecahedron % createDodecahedron, createSoccerBall, createMengerSponge % steinerPolytope, minConvexHull, drawPolyhedron % polyhedronNormalAngle, polyhedronMeanBreadth % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas matgeom-1.2.4/inst/meshes3d/PaxHeaders/transformMesh.m0000644000000000000000000000013214576357161017742 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/transformMesh.m0000644000175000017500000000475214576357161021532 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = transformMesh(varargin) %TRANSFORMMESH Applies a 3D affine transform to a mesh. % % MESH2 = transformMesh(MESH1, TRANSFO) % MESH2 = transformMesh(VERTICES, FACES, TRANSFO) % [V2, F2] = transformMesh(...) % % Example % mesh1 = createOctahedron; % transfo = eulerAnglesToRotation3d([30 20 10]); % mesh2 = transformMesh(mesh1, transfo); % figure; axis equal; hold on; drawMesh(mesh2, 'faceColor', 'g'); view(3); % % See also % meshes3d, transformPoint3d, drawMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-08-08, using Matlab 9.6.0.1072779 (R2019a) % Copyright 2019-2023 INRA - Cepia Software Platform % parses input arguments [vertices, edges, faces] = parseMeshData(varargin{1:end-1}); transfo = varargin{end}; vertices2 = transformPoint3d(vertices, transfo); % format output varargout = formatMeshOutput(nargout, vertices2, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/mergeMeshVertices.m0000644000000000000000000000013214576357161020533 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/mergeMeshVertices.m0000644000175000017500000000503314576357161022314 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [vertices, faces] = mergeMeshVertices(vertices, faces, vertexInds, varargin) %MERGEMESHVERTICES Merge two vertices and removes eventual degenerated faces. % % output = mergeMeshVertices(input) % % Example % mergeMeshVertices % % See also % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-31, using Matlab 9.5.0.944444 (R2018b) % Copyright 2019-2023 INRA - Cepia Software Platform newPos = vertices(vertexInds(1), :); if nargin > 3 newPos = varargin{1}; end vertices(vertexInds(1), :) = newPos; vertices(vertexInds(2:end), :) = NaN; % replace face-vertex indices by index of first vertex faces(ismember(faces, vertexInds)) = vertexInds(1); % need to check existence of degenerated faces with same vertex twice nFaces = size(faces, 1); dgnFaces = false(nFaces, 1); dims = [1 2;1 3;2 3]; for i = 1:3 dgnFaces = dgnFaces | faces(:,dims(i,1)) == faces(:,dims(i,2)); end % remove degenerated faces faces(dgnFaces, :) = []; matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFaceNormals.m0000644000000000000000000000013214576357161020161 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFaceNormals.m0000644000175000017500000000657014576357161021751 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function normals = meshFaceNormals(varargin) %MESHFACENORMALS Compute normal vector of faces in a 3D mesh. % % NORMALS = meshFaceNormals(VERTICES, FACES) % VERTICES is a set of 3D points (as a N-by-3 array), and FACES is either % a N-by-3 index array or a cell array of indices. The function computes % the normal vector of each face. % The orientation of the normal is defined by the sign of cross product % between vectors joining vertices 1 to 2 and 1 to 3. % % % Example % [v e f] = createIcosahedron; % normals1 = meshFaceNormals(v, f); % centros1 = meshFaceCentroids(v, f); % figure; drawMesh(v, f); % hold on; axis equal; view(3); % drawVector3d(centros1, normals1); % % pts = rand(50, 3); % hull = minConvexHull(pts); % normals2 = meshFaceNormals(pts, hull); % % See also % meshes3d, meshFaceCentroids, meshVertexNormals, drawFaceNormals % drawMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-07-05 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % parse input data [vertices, faces] = parseMeshData(varargin{:}); if isnumeric(faces) % compute vector of first edges v1 = vertices(faces(:,2),1:3) - vertices(faces(:,1),1:3); v2 = vertices(faces(:,3),1:3) - vertices(faces(:,1),1:3); % compute normals using cross product (nodes have same size) normals = cross(v1, v2, 2); else % initialize empty array normals = zeros(length(faces), 3); for i = 1:length(faces) face = faces{i}; % compute vector of first edges v1 = vertices(face(2),1:3) - vertices(face(1),1:3); v2 = vertices(face(3),1:3) - vertices(face(1),1:3); % compute normals using cross product normals(i, :) = cross(v1, v2, 2); end end normals = normalizeVector3d(normals); matgeom-1.2.4/inst/meshes3d/PaxHeaders/writeMesh_off.m0000644000000000000000000000013214576357161017713 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/writeMesh_off.m0000644000175000017500000000632514576357161021501 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function writeMesh_off(fileName, vertices, faces) %WRITEMESH_OFF Write a mesh into a text file in OFF format. % % writeMesh_off(FNAME, V, F) % % Example % writeMesh_off % % See also % meshes3d, writeMesh, readMesh_off, writeMesh_ply % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-04-26, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018-2023 INRA - Cepia Software Platform if ~ischar(fileName) error('First argument must contain the name of the file'); end % optionnaly parses data if isstruct(vertices) faces = vertices.faces; vertices = vertices.vertices; end % open file for writing text f = fopen(fileName, 'wt'); if (f == -1) error('Couldn''t open the file %s', fileName); end % write the header line fprintf(f, 'OFF\n'); % write number of vertices and of faces nVertices = size(vertices, 1); nFaces = size(faces, 1); if iscell(faces) nFaces = length(faces); end fprintf(f, '%d %d 0\n', nVertices, nFaces); % Write vertex info format = '%g %g %g\n'; for iv = 1:nVertices fprintf(f, format, vertices(iv, :)); end % Write face info if isnumeric(faces) % simply write face vertex indices ns = size(faces, 2); format = ['%d' repmat(' %d', 1, ns) '\n']; for iFace = 1:nFaces fprintf(f, format, ns, faces(iFace, :)-1); end else % if faces are stored in a cell array, the number of vertices in each % face may be different, and we need to process each face individually for iFace = 1:nFaces ns = length(faces{iFace}); format = ['%d' repmat(' %d', 1, ns) '\n']; fprintf(f, format, ns, faces{iFace}-1); end end % close the file fclose(f); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshDihedralAngles.m0000644000000000000000000000013214576357161020635 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshDihedralAngles.m0000644000175000017500000000660414576357161022423 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function alpha = meshDihedralAngles(vertices, edges, faces) %MESHDIHEDRALANGLES Dihedral at edges of a polyhedal mesh. % % ALPHA = meshDihedralAngles(V, E, F) % where V, E and F represent vertices, edges and faces of a mesh, % computes the dihedral angle between the two adjacent faces of each edge % in the mesh. ALPHA is a column array with as many rows as the number of % edges. The i-th element of ALPHA corresponds to the i-th edge. % % Note: the function assumes that the faces are correctly oriented. The % face vertices should be indexed counter-clockwise when considering the % supporting plane of the face, with the outer normal oriented outwards % of the mesh. % % Example % [v, e, f] = createCube; % rad2deg(meshDihedralAngles(v, e, f)) % ans = % 90 % 90 % 90 % 90 % 90 % 90 % 90 % 90 % 90 % 90 % 90 % 90 % % See also % meshes3d, polyhedronMeanBreadth, trimeshMeanBreadth, dihedralAngle, meshEdgeFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % compute normal of each face normals = meshFaceNormals(vertices, faces); % indices of faces adjacent to each edge edgeFaces = meshEdgeFaces(vertices, edges, faces); % allocate memory for resulting angles Ne = size(edges, 1); alpha = zeros(Ne, 1); % iterate over edges for i = 1:Ne % indices of adjacent faces indFace1 = edgeFaces(i, 1); indFace2 = edgeFaces(i, 2); % normal vector of adjacent faces normal1 = normals(indFace1, :); normal2 = normals(indFace2, :); % compute dihedral angle of two vectors alpha(i) = vectorAngle3d(normal1, normal2); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshAdjacencyMatrix.m0000644000000000000000000000013214576357161021035 xustar0030 mtime=1710874225.150193333 30 atime=1710874225.150193333 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshAdjacencyMatrix.m0000644000175000017500000000626014576357161022621 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function adj = meshAdjacencyMatrix(faces, varargin) %MESHADJACENCYMATRIX Compute adjacency matrix of a mesh from set of faces. % % ADJMAT = meshAdjacencyMatrix(FACES) % Returns a sparse NV-by-NV matrix (NV being the largest vertex index) % containing vertex adjacency of the mesh represented by FACES. % FACES is either a NF-by-3, a NF-by-4 index array, or a Nf-by-1 cell % array. % % Example % [v f] = createCube; % adj = meshAdjacencyMatrix(f); % % See also % meshes3d, triangulateFaces, smoothMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-04-30, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform % Ensures faces is a N-by-3 or N-by-4 array if iscell(faces) || (isnumeric(faces) && size(faces, 2) > 4) faces = triangulateFaces(faces); end % forces faces to be floating point array, for sparse function if ~isfloat(faces) faces = double(faces); end nv = max(faces(:)); % populate a sparse matrix if size(faces, 2) == 3 adj = sparse(... [faces(:,1); faces(:,1); faces(:,2); faces(:,2); faces(:,3); faces(:,3)], ... [faces(:,3); faces(:,2); faces(:,1); faces(:,3); faces(:,2); faces(:,1)], ... 1.0, nv, nv); elseif size(faces, 2) == 4 adj = sparse(... [faces(:,1); faces(:,1); faces(:,2); faces(:,2); faces(:,3); faces(:,3); faces(:,4); faces(:,4)], ... [faces(:,4); faces(:,2); faces(:,1); faces(:,3); faces(:,2); faces(:,4); faces(:,3); faces(:,1)], ... 1.0, nv, nv); end % remove double adjacencies adj = min(adj, 1); matgeom-1.2.4/inst/meshes3d/PaxHeaders/cylinderMesh.m0000644000000000000000000000013214576357161017540 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/cylinderMesh.m0000644000175000017500000001226514576357161021326 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cylinderMesh(cyl, varargin) %CYLINDERMESH Create a 3D mesh representing a cylinder. % % [V, F] = cylinderMesh(CYL) % Computes vertex coordinates and face vertex indices of a mesh % representing a 3D cylinder given as [X1 Y1 Z1 X2 Y2 Z2 R]. % % [V, F] = cylinderMesh(..., OPT) % with OPT = 'open' (0) (default) or 'closed' (1), specify if the bases % of the cylinder should be included. % % [V, F] = cylinderMesh(..., NAME, VALUE); % Specifies one or several options using parameter name-value pairs. % Available options are: % 'nPerimeter' the number of points represeting the perimeter % 'nRho' the number of circles along the hight % % Example % % Draw a rotated cylinder % cyl = [0 0 0 10 20 30 5]; % [v, f] = cylinderMesh(cyl); % figure;drawMesh(v, f, 'FaceColor', 'r'); % view(3); axis equal; % % % Draw three mutually intersecting cylinders % p0 = [30 30 30]; % p1 = [90 30 30]; % p2 = [30 90 30]; % p3 = [30 30 90]; % [v1, f1] = cylinderMesh([p0 p1 25]); % [v2, f2] = cylinderMesh([p0 p2 25]); % [v3, f3] = cylinderMesh([p0 p3 25],'closed','nPeri',40,'nRho',20); % figure; hold on; % drawMesh(v1, f1, 'FaceColor', 'r'); % drawMesh(v2, f2, 'FaceColor', 'g'); % drawMesh(v3, f3, 'FaceColor', 'b'); % view(3); axis equal % set(gcf, 'renderer', 'opengl') % % See also % drawCylinder, torusMesh, sphereMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-10-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform parser = inputParser; addRequired(parser, 'cyl', @(x) validateattributes(x, {'numeric'},... {'size',[1 7],'real','finite','nonnan'})); capParValidFunc = @(x) (islogical(x) ... || isequal(x,1) || isequal(x,0) || any(validatestring(x, {'open','closed'}))); addOptional(parser,'cap','open', capParValidFunc); addParameter(parser, 'nPerimeter', 20, @(x) validateattributes(x,{'numeric'},... {'integer','scalar','>=',4})); addParameter(parser, 'nRho', 10, @(x) validateattributes(x,{'numeric'},... {'integer','scalar','>=',2})); parse(parser,cyl,varargin{:}); cyl=parser.Results.cyl; cap=lower(parser.Results.cap(1)); NoPP=parser.Results.nPerimeter; nRho=parser.Results.nRho; % extract cylinder data p1 = cyl(:, 1:3); p2 = cyl(:, 4:6); r = cyl(:, 7); % compute length and orientation [theta, phi, rho] = cart2sph2d(p2 - p1); % parametrisation on x t = linspace(0, 2*pi, NoPP+1); lx = r * cos(t); ly = r * sin(t); % parametrisation on z lz = linspace(0, rho, nRho); % generate surface grids x = repmat(lx, [length(lz) 1]); y = repmat(ly, [length(lz) 1]); z = repmat(lz', [1 length(t)]); % transform points trans = localToGlobal3d(p1, theta, phi, 0); [x, y, z] = transformPoint3d(x, y, z, trans); % convert to FV mesh [vertices, faces] = surfToMesh(x, y, z, 'xPeriodic', true); % Close cylinder if cap == 'c' || cap == 1 nR = round(r/(rho/(nRho-1))); % Base at p1 P1 = circleMesh([0 0 0 r 0 0 0], 'nP',NoPP, 'nR',nR); P1 = transformMesh(P1, trans); P1.faces = fliplr(P1.faces); % Base at p2 P2 = circleMesh([transformPoint3d(p2, inv(trans)) r 0 0 0], 'nP',NoPP, 'nR',nR); P2 = transformMesh(P2, trans); % Triangulate the lateral surface of the mesh latSurf.vertices = vertices; latSurf.faces = triangulateFaces(faces); mesh = concatenateMeshes(latSurf, P1, P2); [vertices, faces] = removeDuplicateVertices(mesh, 1e-8); end % format output varargout = formatMeshOutput(nargout, vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/polyhedronNormalAngle.m0000644000000000000000000000013214576357161021415 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/polyhedronNormalAngle.m0000644000175000017500000001030514576357161023174 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function theta = polyhedronNormalAngle(varargin) %POLYHEDRONNORMALANGLE Compute normal angle at a vertex of a 3D polyhedron. % % THETA = polyhedraNormalAngle(NODES, EDGES, FACES, IND); % THETA = polyhedraNormalAngle(NODES, FACES, IND); % where NODES is a set of 3D points, and FACES a set of faces, whose % elements are indices to NODES array, compute the normal angle at the % vertex whose index is given by IND. % % THETA = polyhedraNormalAngle(GRAPH, IND); % Uses a graph structure for definineg polyhedron. GRAPH structure should % contain at least two fields : 'nodes' and 'faces'. % % Example : % % create a simple (irregular) tetrahedra % nodes = [0 0 0;1 0 0;0 1 0;0 0 1]; % faces = [1 2 3;1 2 4;1 3 4;2 3 4]; % % compute normal angle at each vertex % theta = polyhedronNormalAngle(nodes, faces, 1:size(nodes, 1)); % % sum of normal angles should be equal to 4*pi : % sum(theta) % % Note: works only for polyhedra with convex faces! % % See also % polyhedra, polygon3dNormalAngle % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-30 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin)==4 nodes = varargin{1}; faces = varargin{3}; ind = varargin{4}; elseif length(varargin)==3 nodes = varargin{1}; faces = varargin{2}; ind = varargin{3}; elseif length(varargin)==2 graph = varargin{1}; nodes = graph.nodes; faces = graph.faces; ind = varargin{2}; else error('wrong number of arguments'); end % number of angles to compute na = length(ind); theta = zeros(na, 1); for i = 1:na thetaf = []; % find faces containing given vertex, % and compute normal angle at each face containing vertex if iscell(faces) for j = 1:length(faces) if ismember(ind(i), faces{j}) % create 3D polygon face = nodes(faces{j}, :); % index of point in polygon indp = find(faces{j}==i); % compute normal angle of vertex thetaf = [thetaf polygon3dNormalAngle(face, indp)]; %#ok end end else indf = find(sum(ismember(faces, ind(i)), 2)); thetaf = zeros(length(indf), 1); for j = 1:length(indf) ind2 = faces(indf(j), :); face = nodes(ind2, :); indp = find(ind2==ind(i)); thetaf(j) = pi - polygon3dNormalAngle(face, indp); end end % compute normal angle of polyhedron, by use of angle defect formula theta(i) = 2*pi - sum(thetaf); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/icosahedron.ply0000644000000000000000000000013214576357160017757 xustar0030 mtime=1710874224.670193794 30 atime=1710874224.670193794 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/icosahedron.ply0000644000175000017500000000120614576357160021536 0ustar00juanpijuanpi00000000000000ply format ascii 1.0 comment created by platoply element vertex 12 property float32 x property float32 y property float32 z element face 20 property list uint8 int32 vertex_indices end_header 0 -0.525731 0.850651 0.850651 0 0.525731 0.850651 0 -0.525731 -0.850651 0 -0.525731 -0.850651 0 0.525731 -0.525731 0.850651 0 0.525731 0.850651 0 0.525731 -0.850651 0 -0.525731 -0.850651 0 0 -0.525731 -0.850651 0 0.525731 -0.850651 0 0.525731 0.850651 3 6 2 1 3 2 7 1 3 5 4 3 3 8 3 4 3 11 5 6 3 10 6 5 3 2 10 9 3 3 9 10 3 9 8 7 3 0 7 8 3 1 0 11 3 4 11 0 3 10 2 6 3 11 6 1 3 10 5 3 3 11 4 5 3 9 7 2 3 0 1 7 3 8 9 3 3 0 8 4 matgeom-1.2.4/inst/meshes3d/PaxHeaders/smoothMesh.m0000644000000000000000000000013214576357161017240 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/smoothMesh.m0000644000175000017500000001031214576357161021015 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = smoothMesh(varargin) %SMOOTHMESH Smooth mesh by replacing each vertex by the average of its neighbors. % % V2 = smoothMesh(V, F) % [V2, F2] = smoothMesh(V, F) % Performs smoothing of the values given in V, by using adjacency % information given in F. % V is a numeric array representing either vertex coordinate, or value % field associated to each vertex. F is an array of faces, given either % as a NF-by-3 or NF-by-4 numeric array, or as a cell array. % Artifact adjacencies are added if faces have more than 4 vertices. % % ... = smoothMesh(V, F, NITER) % Repeat the smoothing procedure NITER times. This is equivalent to % calling the smoothMesh function NITER times. % % % Example % [v f] = torusMesh([50 50 50 30 10 30 45]); % v = v + randn(size(v)); % [v2 f] = smoothMesh(v, f, 3); % figure; drawMesh(v2, f); % l = light; lighting gouraud % % See also % meshes3d, meshAdjacencyMatrix, triangulateFaces, drawMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-04-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform var1 = varargin{1}; if isstruct(var1) vertices = var1.vertices; faces = var1.faces; varargin(1) = []; else vertices = varargin{1}; faces = varargin{2}; varargin(1:2) = []; end % determine number of iterations nIter = 1; if ~isempty(varargin) nIter = varargin{1}; end % compute adjacency matrix, % result is a Nv-by-Nv matrix with zeros on the diagonal adj = meshAdjacencyMatrix(faces); % ensure the size of the matrix is Nv-by-Nv % (this can not be the case if some vertices are not referenced) nv = size(vertices, 1); if size(adj, 1) < nv adj(nv, nv) = 0; end % Add "self adjacencies" adj = adj + speye(nv); % weight each vertex by the number of its neighbors w = spdiags(full(sum(adj, 2).^(-1)), 0, nv, nv); adj = w * adj; % do averaging to smooth the field v2 = vertices; for k = 1:nIter v2 = adj * v2; end varargout = formatMeshOutput(nargout, v2, faces); %% Old version % % Compute vertex adjacencies % edges = computeMeshEdges(faces); % v2 = zeros(size(vertices)); % % % apply several smoothing % for iter = 1:nIter % % % replace the coords of each vertex by the average coordinate in the % % neighborhood % for i = 1:size(vertices, 1) % edgeInds = sum(edges == i, 2) > 0; % neighInds = unique(edges(edgeInds, :)); % v2(i, :) = mean(vertices(neighInds, :)); % end % % % update for next iteration % vertices = v2; % end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createDodecahedron.m0000644000000000000000000000013214576357161020655 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createDodecahedron.m0000644000175000017500000001005714576357161022440 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createDodecahedron() %CREATEDODECAHEDRON Create a 3D mesh representing a dodecahedron. % % [V, E, F] = createDodecahedron; % Create a 3D mesh representing a dodecahedron % V is the 20-by-3 array of vertex coordinates % E is the 30-by-2 array of edge vertex indices % F is the 12-by-5 array of face vertex indices % % [V, F] = createDodecahedron; % Returns only the vertices and the face vertex indices. % % MESH = createDodecahedron; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % Example % [v, e, f] = createDodecahedron; % drawMesh(v, f); % % Use values given by P. Bourke, see: % http://local.wasp.uwa.edu.au/~pbourke/geometry/platonic/ % faces are re-oriented to have normals pointing outwards. % % See also % meshes3d, drawMesh % createCube, createOctahedron, createIcosahedron, createTetrahedron % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-07-29 % Copyright 2010-2023 INRA - TPV URPOI - BIA IMASTE % golden ratio phi = (1+sqrt(5))/2; % coordinates pre-computations b = 1 / phi ; c = 2 - phi ; % use values given by P. Bourke, see: % http://local.wasp.uwa.edu.au/~pbourke/geometry/platonic/ tmp = [ ... c 0 1 ; b b b ; 0 1 c ; -b b b ; -c 0 1 ; ... -c 0 1 ; -b -b b ; 0 -1 c ; b -b b ; c 0 1 ; ... c 0 -1 ; b -b -b ; 0 -1 -c ; -b -b -b ; -c 0 -1 ; ... -c 0 -1 ; -b b -b ; 0 1 -c ; b b -b ; c 0 -1 ; ... 0 1 -c ; 0 1 c ; b b b ; 1 c 0 ; b b -b ; ... 0 1 c ; 0 1 -c ; -b b -b ; -1 c 0 ; -b b b ; ... 0 -1 -c ; 0 -1 c ; -b -b b ; -1 -c 0 ; -b -b -b ; ... 0 -1 c ; 0 -1 -c ; b -b -b ; 1 -c 0 ; b -b b ; ... 1 c 0 ; b b b ; c 0 1 ; b -b b ; 1 -c 0 ; ... 1 -c 0 ; b -b -b ; c 0 -1 ; b b -b ; 1 c 0 ; ... -1 c 0 ; -b b -b ; -c 0 -1 ; -b -b -b ; -1 -c 0 ; ... -1 -c 0 ; -b -b b ; -c 0 1 ; -b b b ; -1 c 0 ; ... ]; % extract coordinates of unique vertices [verts, M, N] = unique(tmp, 'rows', 'first'); %#ok % compute indices of face vertices, put result in a 12-by-5 index array ind0 = reshape((1:60), [5 12])'; faces = N(ind0); % extract edges from faces edges = [reshape(faces(:, 1:5), [60 1]) reshape(faces(:, [2:5 1]), [60 1])]; edges = unique(sort(edges, 2), 'rows'); % format output varargout = formatMeshOutput(nargout, verts, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/triangulateCurvePair.m0000644000000000000000000000013214576357161021252 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/triangulateCurvePair.m0000644000175000017500000001000214576357161023023 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [vertices, facets] = triangulateCurvePair(curve1, curve2) %TRIANGULATECURVEPAIR Compute triangulation between a pair of 3D open curves. % % [V, F] = testTriangulateCurvePair(CURVE1, CURVE2) % % Example % % triangulate a surface patch between two open curves % % create two sample curves % t = linspace(0, 2*pi, 100); % curve1 = [linspace(0, 10, 100)' 5 * sin(t') zeros(100,1)]; % curve2 = [linspace(0, 10, 100)' 2 * sin(t') 2*ones(100,1)]; % figure; hold on; % drawPolyline3d(curve1, 'b'); % drawPolyline3d(curve2, 'g'); % view(3); axis equal; % [v, f] = triangulateCurvePair(curve1, curve2); % figure; drawMesh(v, f, 'linestyle', 'none'); % view(3); axis equal % % See also % meshes3D, triangulatePolygonPair, meshSurfaceArea % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-05-18, using Matlab 9.1.0.441655 (R2016b) % Copyright 2017-2023 INRA - Cepia Software Platform %% Memory allocation % number of vertices on each curve n1 = size(curve1, 1); n2 = size(curve2, 1); % allocate the array of facets (each edge of each curve provides a facet) nFacets = n1 + n2 - 2; facets = zeros(nFacets, 3); % look for the closest ends of two curves and reverse the second curve if % needed p1 = curve1(1, :); if distancePoints(p1, curve2(1,:)) > distancePoints(p1, curve2(end,:)) curve2 = curve2(end:-1:1,:); end currentIndex1 = 1; currentIndex2 = 1; % concatenate vertex coordinates for creating mesh vertices = [curve1 ; curve2]; %% Main iteration % For each diagonal, consider the two possible facets (one for each 'next' % vertex on each curve), each create current facet according to the closest % one. % Then update current diagonal for next iteration. for i = 1:nFacets nextIndex1 = mod(currentIndex1, n1) + 1; nextIndex2 = mod(currentIndex2, n2) + 1; % compute lengths of diagonals dist1 = distancePoints(curve1(currentIndex1, :), curve2(nextIndex2,:)); dist2 = distancePoints(curve1(nextIndex1, :), curve2(currentIndex2,:)); if dist1 < dist2 % keep current vertex of curve1, use next vertex on curve2 facet = [currentIndex1 currentIndex2+n1 nextIndex2+n1]; currentIndex2 = nextIndex2; else % keep current vertex of curve2, use next vertex on curve1 facet = [currentIndex1 currentIndex2+n1 nextIndex1]; currentIndex1 = nextIndex1; end % create the facet facets(i, :) = facet; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createTetrakaidecahedron.m0000644000000000000000000000013214576357161022057 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createTetrakaidecahedron.m0000644000175000017500000000671514576357161023650 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createTetrakaidecahedron() %CREATETETRAKAIDECAHEDRON Create a 3D mesh representing a tetrakaidecahedron. % % [V, E, F] = createTetrakaidecahedron; % Create a mesh structure representing a tetrakaidecahedron, composed of % both square and hexagonal faces. Tetrakaidecahedron can be used to tile % the 3D Euclidean space. % % V is a 24-by-3 array with vertex coordinates, % E is a 36-by-2 array containing indices of neighbour vertices, % F is a 14-by-1 cell array containing vertex indices array of each face. % % [V, F] = createTetrakaidecahedron; % Returns only the vertices and the face vertex indices. % % MESH = createTetrakaidecahedron; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % Example % [n, e, f] = createTetrakaidecahedron; % drawMesh(n, f); % % See also % meshes3d, drawMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE nodes = [... 1 0 2;0 1 2;-1 0 2;0 -1 2;... 2 0 1;0 2 1;-2 0 1;0 -2 1;... 2 1 0;1 2 0;-1 2 0;-2 1 0;-2 -1 0;-1 -2 0;1 -2 0;2 -1 0;... 2 0 -1;0 2 -1;-2 0 -1;0 -2 -1;... 1 0 -2;0 1 -2;-1 0 -2;0 -1 -2]; edges = [... 1 2;1 4;1 5;2 3;2 6;3 4;3 7;4 8;... 5 9;5 16;6 10;6 11;7 12;7 13;8 14;8 15;... 9 10;9 17;10 18;11 12;11 18;12 19;13 14;13 19;14 20;15 16;15 20;16 17;.... 17 21;18 22;19 23;20 24;21 22;21 24;22 23;23 24]; faces = {... [1 2 3 4], ... [1 4 8 15 16 5], [1 5 9 10 6 2], [2 6 11 12 7 3], [3 7 13 14 8 4],... [5 16 17 9], [6 10 18 11], [7 12 19 13], [8 14 20 15],... [9 17 21 22 18 10], [11 18 22 23 19 12], [13 19 23 24 20 14], [15 20 24 21 17 16], ... [21 24 23 22]}; faces = faces'; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/tetrahedronVolume.m0000644000000000000000000000013214576357161020621 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/tetrahedronVolume.m0000644000175000017500000000556614576357161022415 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vol = tetrahedronVolume(vertices, varargin) %TETRAHEDRONVOLUME Signed volume of a tetrahedron. % % VOL = tetrahedronVolume(TETRA) % Comptues the siged volume of the tetrahedron TETRA defined by a 4-by-4 % array representing the polyhedron vertices. % % Example % vi = [0 0 0;1 0 0;0 1 0;0 0 1]; % tetrahedronVolume(vi) % ans = % 0.1667 % % [V F] = createTetrahedron; % tetrahedronVolume(V) % ans = % -.3333 % % See also % meshes3d, createTetrahedron, meshVolume % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-04-05, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform if nargin == 2 tetras = varargin{1}; nTetras = size(tetras, 1); vol = zeros(nTetras, 1); for i = 1:nTetras tetra = tetras(i,:); vol(i) = det(bsxfun(@minus, vertices(tetra(2:4),:), vertices(tetra(1),:))) / 6; end return; end % control on inputs if nargin == 4 vertices = [vertices ; varargin{1} ; varargin{2} ; varargin{3}]; end if size(vertices, 1) < 4 error('Input vertex array requires at least 4 vertices'); end % compute volume of tetrahedron, using first vertex as origin vol = det(vertices(2:4,:) - vertices([1 1 1],:)) / 6; matgeom-1.2.4/inst/meshes3d/PaxHeaders/createStellatedMesh.m0000644000000000000000000000013214576357161021034 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createStellatedMesh.m0000644000175000017500000000637314576357161022625 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createStellatedMesh(vertices, faces, varargin) %CREATESTELLATEDMESH Replaces each face of a mesh by a pyramid. % % [V2, F2] = createStellatedMesh(V, F) % % Example % [v, f] = createCube % [v2, f2] = createStellatedMesh(v, f); % figure; drawMesh(v2, f2); axis equal; view(3); % % See also % meshes3d, drawMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-11-27, using Matlab 9.5.0.944444 (R2018b) % Copyright 2018-2023 INRA - Cepia Software Platform % properties of mesh nVertices = size(vertices, 1); nFaces = size(faces, 1); % shift coefficients for computing new vertices coeffs = ones(nFaces, 1); if ~isempty(varargin) var1 = varargin{1}; if isnumeric(var1) && isscalar(var1) coeffs = coeffs * var1; elseif isnumeric(var1) && length(var1) == nFaces coeffs = var1(:); else error('Coefficients must be either a scalar or a nFaces-by-1 array'); end end % supporting line of new vertices fc = meshFaceCentroids(vertices, faces); fn = meshFaceNormals(vertices, faces); % position of new vertices nv = fc + bsxfun(@times, fn, coeffs); % create data for new mesh v2 = [vertices ; nv]; f2 = zeros(nFaces * 3, 3); indF = 0; % iterate over faces for iFace = 1:nFaces % indices of vertices of current face face = meshFace(faces, iFace); % face = faces(iFace, :); % iterate over edges to create new triangular faces for ivf = 1:length(face) ind1 = face(ivf); ind2 = face(mod(ivf, length(face)) + 1); indF = indF + 1; f2(indF, :) = [ind1 ind2 iFace+nVertices]; end end % format output varargout = formatMeshOutput(nargout, v2, f2); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFaceEdges.m0000644000000000000000000000013214576357161017575 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFaceEdges.m0000644000175000017500000000546614576357161021370 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function FE = meshFaceEdges(vertices, edges, faces) %MESHFACEEDGES Computes edge indices of each face. % % FE = meshFaceEdges(V, E, F) % Returns a 1-by-NF cell array containing for each face, the set of edge % indices corresponding to adjacent edges. % % Example % meshFaceEdges % % See also % meshes3d, meshEdgeFaces % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-08-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform nFaces = meshFaceNumber(vertices, faces); FE = cell(nFaces, 1); % impose ordering of edge indices edges = sort(edges, 2); for iFace = 1:nFaces % extract vertex indices of current face face = meshFace(faces, iFace); nv = length(face); % for each couple of adjacent vertices, find the index of the matching % row in the edges array fei = zeros(1, nv); for iEdge = 1:nv % compute index of each edge vertex edge = sort([face(iEdge) face(mod(iEdge, nv) + 1)]); v1 = edge(1); v2 = edge(2); % find the matching row ind = find(edges(:,1) == v1 & edges(:,2) == v2); fei(iEdge) = ind; end FE{iFace} = fei; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/dodecahedron.obj0000644000000000000000000000013214576357160020046 xustar0030 mtime=1710874224.682193781 30 atime=1710874224.682193781 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/dodecahedron.obj0000644000175000017500000000203514576357160021626 0ustar00juanpijuanpi00000000000000# OBJ file created by ply_to_obj.c # g Object001 v -0.57735 -0.57735 0.57735 v 0.934172 0.356822 0 v 0.934172 -0.356822 0 v -0.934172 0.356822 0 v -0.934172 -0.356822 0 v 0 0.934172 0.356822 v 0 0.934172 -0.356822 v 0.356822 0 -0.934172 v -0.356822 0 -0.934172 v 0 -0.934172 -0.356822 v 0 -0.934172 0.356822 v 0.356822 0 0.934172 v -0.356822 0 0.934172 v 0.57735 0.57735 -0.57735 v 0.57735 0.57735 0.57735 v -0.57735 0.57735 -0.57735 v -0.57735 0.57735 0.57735 v 0.57735 -0.57735 -0.57735 v 0.57735 -0.57735 0.57735 v -0.57735 -0.57735 -0.57735 f 19 3 2 f 12 19 2 f 15 12 2 f 8 14 2 f 18 8 2 f 3 18 2 f 20 5 4 f 9 20 4 f 16 9 4 f 13 17 4 f 1 13 4 f 5 1 4 f 7 16 4 f 6 7 4 f 17 6 4 f 6 15 2 f 7 6 2 f 14 7 2 f 10 18 3 f 11 10 3 f 19 11 3 f 11 1 5 f 10 11 5 f 20 10 5 f 20 9 8 f 10 20 8 f 18 10 8 f 9 16 7 f 8 9 7 f 14 8 7 f 12 15 6 f 13 12 6 f 17 13 6 f 13 1 11 f 12 13 11 f 19 12 11 matgeom-1.2.4/inst/meshes3d/PaxHeaders/checkMeshAdjacentFaces.m0000644000000000000000000000013214576357161021400 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/checkMeshAdjacentFaces.m0000644000175000017500000000766714576357161023200 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function checkMeshAdjacentFaces(vertices, edges, faces) %CHECKMESHADJACENTFACES Check if adjacent faces of a mesh have similar orientation. % % checkMeshAdjacentFaces(VERTICES, EDGES, FACES) % The functions returns no output, but if two faces share a common edge % with the same direction (meaning that adjacent faces have normals in % opposite direction), a warning is displayed. % % Example % [v e f] = createCube(); % checkMeshAdjacentFaces(v, e, f); % % no output -> all faces have normal outwards of the cube % % v = [0 0 0; 10 0 0; 0 10 0; 10 10 0]; % e = [1 2;1 3;2 3;2 4;3 4]; % f = [1 2 3; 2 3 4]; % checkMeshAdjacentFaces(v, e, f); % Warning: Faces 1 and 2 run through the edge 3 (2-3) in the same direction % % See also % meshes3d, trimeshMeanBreadth % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-06, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % the message pattern that is displayed when an inconsistency is encountered pattern = 'Faces %d and %d run through the edge %d (%d-%d) in the same direction'; % If edges are not specified, compute them if nargin == 2 faces = edges; edges = meshEdges(vertices, faces); end % compute edges to faces map edgeFaces = meshEdgeFaces(vertices, edges, faces); Ne = size(edgeFaces, 1); for i = 1:Ne % indices of extreimty vertices v1 = edges(i, 1); v2 = edges(i, 2); % index of adjacent faces indF1 = edgeFaces(i, 1); indF2 = edgeFaces(i, 2); % if one of the faces has index 0, then the edge is at the boundary if indF1 == 0 || indF2 == 0 continue; end % vertices of adjacent faces face1 = meshFace(faces, indF1); face2 = meshFace(faces, indF2); % position of vertices in face vertex array ind11 = find(face1 == v1); ind12 = find(face1 == v2); ind21 = find(face2 == v1); ind22 = find(face2 == v2); % check if edge is traveled forward or backard direct1 = (ind12 == ind11+1) | (ind12 == 1 & ind11 == length(face1)); direct2 = (ind22 == ind21+1) | (ind22 == 1 & ind21 == length(face2)); % adjacent faces should travel the edge in opposite direction if direct1 == direct2 warning(pattern, indF1, indF2, i, v1, v2); %#ok end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/splitMesh.m0000644000000000000000000000013214576357161017062 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/splitMesh.m0000644000175000017500000001325014576357161020643 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function meshes = splitMesh(vertices, faces, varargin) %SPLITMESH Return the connected components of a mesh. % % MESHES = splitMesh(VERTICES, FACES) returns the connected components of % the mesh defined by vertices and faces as a struct array with the % fields vertices and faces sorted by increasing vertex number % % MESHES = splitMesh(MESH) with the vertices-faces-struct MESH is also % possible % % ... = splitMesh(..., 'mostVertices') returns only the component with % the most vertices. Other options are 'all' (default), % 'maxBoundingBox' that returns the component with the largest bounding % box, and 'maxVolume' returns the component with the largest volume. % % % Example % [v1, f1] = boxToMesh([1 0 -1 0 -1 0]); % [v2, f2] = boxToMesh([-1 0 1 0 -1 0]); % [v3, f3] = createSoccerBall; % f1 = triangulateFaces(f1); % f2 = triangulateFaces(f2); % f3 = triangulateFaces(f3); % [vertices, faces] = concatenateMeshes(v1, f1, v3, f3, v2, f2); % meshes = splitMesh(vertices, faces); % figure('color','w'); view(3); axis equal % cmap=hsv(length(meshes)); % for m=1:length(meshes) % drawMesh(meshes(m), cmap(m,:)) % end % % See also % concatenateMeshes % % Source % Local functions are part of the gptoolbox of Alec Jacobson % https://github.com/alecjacobson/gptoolbox % ------ % Author: oqilipo % E-mail: N/A % Created: 2017-09-17 % Copyright 2017-2023 % input parsing if isstruct(vertices) if nargin > 1; varargin = [faces, varargin]; end [vertices, faces]=parseMeshData(vertices); end parser = inputParser; validStrings = {'all','mostVertices','maxBoundingBox','maxVolume'}; addOptional(parser,'components','all',@(x) any(validatestring(x, validStrings))); parse(parser,varargin{:}); outputComp = validatestring(parser.Results.components, validStrings); % algorithm CC = connected_components(faces); [a,~]=hist(CC,unique(CC)); [~,b] = sort(a); meshes=repmat(struct('vertices',[],'faces',[]),length(b),1); for cc=b meshes(cc)=removeMeshVertices(vertices, faces, ~(CC'==b(cc))); end % output parsing switch outputComp case 'mostVertices' meshes=meshes(end); case 'maxBoundingBox' [~,sortingIndices] = sort(arrayfun(@(x) box3dVolume(boundingBox3d(x.vertices)), meshes)); meshes = meshes(sortingIndices(end)); case 'maxVolume' [~,sortingIndices] = sort(arrayfun(@(x) meshVolume(x.vertices, x.faces), meshes)); meshes = meshes(sortingIndices(end)); end end %% Local functions are part of the gptoolbox by Alec Jacobson function C = connected_components(F) % CONNECTED_COMPONENTS Determine the connected components of a mesh % described by the simplex list F. Components are determined with respect % to the edges of the mesh. That is, a single component may contain % non-manifold edges and vertices. % % C = connected_components(F) % % Inputs: % F #F by simplex-size list of simplices % Outputs: % C #V list of ids for each CC % % Examples: % trisurf(F,V(:,1),V(:,2),V(:,3), ... % connected_components([F;repmat(size(V,1),1,3)])); % build adjacency list A = adjacency_matrix(F); [~,C] = conncomp(A); end function [A] = adjacency_matrix(E) % ADJACENCY_MATRIX Build sparse adjacency matrix from edge list or face list % % [A] = adjacency_matrix(E) % [A] = adjacency_matrix(F) % [A] = adjacency_matrix(T) % % Inputs: % E #E by 2 edges list % or % F #F by 3 triangle list % or % T #F by 4 tet list % Outputs: % A #V by #V adjacency matrix (#V = max(E(:))) % if size(E,2)>2 F = E; E = meshEdges(F); end A = sparse([E(:,1) E(:,2)],[E(:,2) E(:,1)],1); end function [S,C] = conncomp(G) % CONNCOMP Drop in replacement for graphconncomp.m from the bioinformatics % toobox. G is an n by n adjacency matrix, then this identifies the S % connected components C. This is also an order of magnitude faster. % % [S,C] = conncomp(G) % % Inputs: % G n by n adjacency matrix % Outputs: % S scalar number of connected components % C % Transpose to match graphconncomp G = G'; [p,~,r] = dmperm(G+speye(size(G))); S = numel(r)-1; C = cumsum(full(sparse(1,r(1:end-1),1,1,size(G,1)))); C(p) = C; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshEdgeLength.m0000644000000000000000000000013214576357161017775 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshEdgeLength.m0000644000175000017500000000441014576357161021554 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function lengths = meshEdgeLength(varargin) %MESHEDGELENGTH Lengths of edges of a polygonal or polyhedral mesh. % % output = meshEdgeLength(V, E, F) % % Example % meshEdgeLength % % See also % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % parse input arguments [vertices, edges, faces] = parseMeshData(varargin{:}); if isempty(edges) edges = meshEdges(faces); end % extract vertices p1 = vertices(edges(:, 1), :); p2 = vertices(edges(:, 2), :); % compute euclidean distance betwenn the two vertices lengths = sqrt(sum((p2-p1).^2, 2)); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshVoronoiDiagram.m0000644000000000000000000000013214576357161020707 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshVoronoiDiagram.m0000644000175000017500000001222414576357161022470 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [regions, distances] = meshVoronoiDiagram(vertices, faces, germInds) %MESHVORONOIDIAGRAM Voronoi Diagram on the surface of a polygonal mesh. % % REGIONS = meshVoronoiDiagram(V, F, GERM_INDS) % Computes the region associated to each vertex of the input mesh (V,F), % i.e. the index of the germ closest to the vertex. % V is a NV-by-3 array of vertx coordinates, and F is a NF-by-3 array % containing vertex indices of each face. % IGERMS is an array of vertex indices. % REGIONS is a column vector with as many rows as the number of vertices, % containing for each vertex the index of the closest germ. % The regions are computed by propagating distances along edges. % % [REGIONS, DISTANCES] = meshVoronoiDiagram(V, F, GERM_INDS) % Also returns the (geodesic) distance from each vertex to the closest % germ. % % % Example % % Create a triangular mesh based on an icosahedron shape % [v, f] = createIcosahedron; v = v - mean(v); % [v, f] = subdivideMesh(v, f, 10); v = normalizeVector3d(v); % figure; hold on; axis equal; view(3); % drawMesh(v, f, 'faceColor', [.7 .7 .7]); % % generate germs within the mesh (identify with indices) % nGerms = 10; % inds = randperm(size(v, 1), nGerms); % drawPoint3d(v(inds,:), 'bo'); % % Compute Voronoi Diagram % [regions, distances] = meshVoronoiDiagram(v, f, inds); % % Display regions % figure; hold on; axis equal; view(3); % cmap = jet(nGerms); % patch('Vertices', v, 'Faces', f, 'FaceVertexCData', cmap(regions, :), 'FaceColor', 'interp', 'LineStyle', 'none'); % % Display distance maps % figure; hold on; axis equal; view(3); % patch('Vertices', v, 'Faces', f, 'FaceVertexCData', distances, 'FaceColor', 'interp', 'LineStyle', 'none'); % % See also % meshes3d, drawMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-04-16, using Matlab 9.7.0.1247435 (R2019b) Update 2 % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % choose initial germ indices if input is a scalar nVertices = size(vertices, 1); if isscalar(germInds) germInds = randperm(nVertices, germInds); end nGerms = length(germInds); % init info for vertices distances = inf * ones(nVertices, 1); regions = zeros(nVertices, 1); % initialize vertex data for each germ for iGerm = 1:nGerms ind = germInds(iGerm); distances(ind) = 0; regions(ind) = iGerm; end % compute the adjacencey matrix, as a Nv-by-Nv sparse matrix of 0 and 1. adj = meshAdjacencyMatrix(faces); % create the queue of vertex to process, initialized with germ indices. vertexQueue = germInds; processed = false(nVertices, 1); % process vertices in the queue, using distance as priority while ~isempty(vertexQueue) % find the vertex with smallest distance [~, ind] = min(distances(vertexQueue)); iVertex = vertexQueue(ind); vertexQueue(ind) = []; % info for current vertex vertex = vertices(iVertex, :); dist0 = distances(iVertex); % neighbors of current vertex neighbors = find(adj(iVertex,:)); % keep only vertices not yet processed neighbors = neighbors(~processed(neighbors)); for iNeigh = 1:length(neighbors) indNeigh = neighbors(iNeigh); dist = dist0 + distancePoints3d(vertex, vertices(indNeigh, :)); if dist < distances(indNeigh) distances(indNeigh) = dist; regions(indNeigh) = regions(iVertex); vertexQueue = [vertexQueue indNeigh]; %#ok end end % mark current vertex as processed processed(iVertex) = true; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/distancePointMesh.m0000644000000000000000000000013214576357161020533 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/distancePointMesh.m0000644000175000017500000003027014576357161022315 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [dist, proj] = distancePointMesh(points, vertices, faces, varargin) %DISTANCEPOINTMESH Shortest distance between a (3D) point and a triangle mesh. % % DIST = distancePointMesh(POINTS, VERTICES, FACES) % Returns the shortest distance between the query point(s) POINTS and the % triangular mesh defined by the set of vertex coordinates VERTICES and % the set of faces FACES. POINTS is a NP-by-3 array, VERTICES is a % NV-by-3 array, and FACES is a NF-by-3 array of vertex indices. % If FACES is NF-by-4 array, it is converted to a (NF*2)-by-3 array. % DIST is the NP-by-1 vector of distances. % % [DIST, PROJ] = distancePointMesh(...) % Also returns the NP-by-3 projection of the query point(s) on the % triangular mesh. % % ... = distancePointMesh(..., 'algorithm', ALGO) % Allows to choose the type of algorithm. Options are: % * sequential: process each face sequentially, using the function % distancePointTriangle3d % * vectorized: vectorized algorithm, usually faster for large number % of faces % * auto: (default) automatically choose the most appropriate % between sequential and vectorized. % % Example % [V, F] = torusMesh(); % F2 = triangulateFaces(F); % P = [10 20 30]; % [D, PROJ] = distancePointMesh(P, V, F2); % figure; drawMesh(V, F) % view(3); axis equal; lighting gouraud; light; % drawPoint3d(P); % drawPoint3d(PROJ, 'm*'); % drawEdge3d([P PROJ], 'linewidth', 2, 'color', 'b'); % % See also % distancePointTriangle3d % % References % * "Distance Between Point and Triangle in 3D", David Eberly % https://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf % * "Distance between a point and a triangle in 3d", by Gwendolyn Fischer % https://mathworks.com/matlabcentral/fileexchange/22857 % * "Distance Between Point and Triangulated Surface", by Daniel Frisch % https://www.mathworks.com/matlabcentral/fileexchange/52882 % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-03-08, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018-2023 INRA - Cepia Software Platform %% Parses input arguments % check the case of mesh given as structure if isstruct(vertices) faces = vertices.faces; vertices = vertices.vertices; end % default option algo = 'auto'; % check optional arguments while length(varargin) > 1 varName = varargin{1}; if ~ischar(varName) error('Require options as parameter name-value pairs'); end if strcmpi(varName, 'algorithm') algo = varargin{2}; else error(['Unknown option name: ' varName]); end varargin(1:2) = []; end % number of faces nFaces = size(faces, 1); if size(faces, 2) > 3 || iscell(faces) faces = triangulateFaces(faces); end % If algorithm is chosen automatically, choose depending on face number if strcmpi(algo, 'auto') if size(faces, 1) > 30 algo = 'vectorized'; else algo = 'sequential'; end end % switch to vectorized algorithm if necessary if strcmpi(algo, 'vectorized') if nargout > 1 [dist, proj] = distancePointTrimesh_vectorized(points, vertices, faces); else dist = distancePointTrimesh_vectorized(points, vertices, faces); end return; end %% Sequential algorithm % For each point, iterates over the triangular faces % allocate memory for result nPoints = size(points, 1); dist = zeros(nPoints, 1); if nargout > 1 proj = zeros(nPoints, 3); end % iterate over points for i = 1:nPoints % % min distance and projection for current point minDist = inf; projp = [0 0 0]; % iterate over faces for iFace = 1:nFaces % create triange for current face face = faces(iFace, :); triangle = vertices(face, :); [distf, projf] = distancePointTriangle3d(points(i,:), triangle); if distf < minDist minDist = distf; projp = projf; end end dist(i) = minDist; if nargout > 1 proj(i,:) = projp; end end end function [dist, proj] = distancePointTrimesh_vectorized(point, vertices, faces) %DISTANCEPOINTTRIMESH Vectorized version of the distancePointTrimesh function % % output = distancePointTrimesh_vectorized(input) % % This version is vectorized over faces: for each query point, the % minimum distance to each triangular face is computed in parallel. % Then the minimum distance over faces is kept. % % Example % distancePointTrimesh % % ­­­­­‒­­­­‒­­­­‒­­­­‒­­­­‒­­­­‒­­­­­ % Author: David Legland % e-mail: david.legland@inra.fr % Created: 2018-03-08, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018 INRA - Cepia Software Platform % Regions are not numbered as in the original paper of D. Eberly to allow % automated computation of regions from the 3 conditions on lines. % Region indices are computed as follow: % IND = b2 * 2^2 + b1 * 2 + b0 % with: % b0 = 1 if s < 0, 0 otherwise % b1 = 1 if t < 0, 0 otherwise % b2 = 1 if s+t > 1, 0 otherwise % resulting in the following region indices: % /\ t % | % \ R5 | % \ | % \ | % \ | % \| P3 % * % |\ % | \ % R1 | \ R4 % | \ % | R0 \ % | \ % | P1 \ P2 % ­­­­–­­­–­­­–­­­–­­­–­­­–*–­­­–­­­–­­­–­­­–­­­––*–­­­–­­­–­­­–­­­–­­­–> s % | \ % R3 | R2 \ R6 % allocate memory for result nPoints = size(point, 1); dist = zeros(nPoints, 1); proj = zeros(nPoints, 3); % triangle origins and direction vectors p1 = vertices(faces(:,1),:); v12 = vertices(faces(:,2),:) - p1; v13 = vertices(faces(:,3),:) - p1; % identify coefficients of second order equation that do not depend on % query point a = dot(v12, v12, 2); b = dot(v12, v13, 2); c = dot(v13, v13, 2); % iterate on query points for i = 1:nPoints % coefficients of second order equation that depend on query point diffP = bsxfun(@minus, p1, point(i, :)); d = dot(v12, diffP, 2); e = dot(v13, diffP, 2); % compute position of projected point in the plane of the triangle det = a .* c - b .* b; s = b .* e - c .* d; t = b .* d - a .* e; % compute region index (one for each face) regIndex = (s < 0) + 2 * (t < 0) + 4 * (s + t > det); % for each region, process all faces whose projection fall within it % region 0 % the minimum distance occurs inside the triangle inds = regIndex == 0; s(inds) = s(inds) ./ det(inds); t(inds) = t(inds) ./ det(inds); % region 1 (formerly region 3) % The minimum distance must occur on the line s = 0 inds = find(regIndex == 1); s(inds) = 0; t(inds(e(inds) >= 0)) = 0; inds2 = inds(e(inds) < 0); bool3 = c(inds2) <= -e(inds2); t(inds2(bool3)) = 1; inds3 = inds2(~bool3); t(inds3) = -e(inds3) ./ c(inds3); % region 2 (formerly region 5) % The minimum distance must occur on the line t = 0 inds = find(regIndex == 2); t(inds) = 0; s(inds(d(inds) >= 0)) = 0; inds2 = inds(d(inds) < 0); bool3 = a(inds2) <= -d(inds2); s(inds2(bool3)) = 1; inds3 = inds2(~bool3); s(inds3) = -d(inds3) ./ a(inds3); % region 3 (formerly region 4) % The minimum distance must occur % * on the line t = 0 % * on the line s = 0 with t >= 0 % * at the intersection of the two lines inds = find(regIndex == 3); inds2 = inds(d(inds) < 0); % minimum on edge t = 0 with s > 0. t(inds2) = 0; bool3 = a(inds2) <= -d(inds2); s(inds2(bool3)) = 1; inds3 = inds2(~bool3); s(inds3) = -d(inds3) ./ a(inds3); inds2 = inds(d(inds) >= 0); % minimum on edge s = 0 s(inds2) = 0; bool3 = e(inds2) >= 0; t(inds2(bool3)) = 0; bool3 = e(inds2) < 0 & c(inds2) <= -e(inds2); t(inds2(bool3)) = 1; bool3 = e(inds2) < 0 & c(inds2) > -e(inds2); inds3 = inds2(bool3); t(inds3) = -e(inds3) ./ c(inds3); % region 4 (formerly region 1) % The minimum distance must occur on the line s + t = 1 inds = find(regIndex == 4); numer = (c(inds) + e(inds)) - (b(inds) + d(inds)); s(inds(numer <= 0)) = 0; inds2 = inds(numer > 0); numer = numer(numer > 0); denom = a(inds2) - 2 * b(inds2) + c(inds2); s(inds2(numer > denom)) = 1; bool3 = numer <= denom; s(inds2(bool3)) = numer(bool3) ./ denom(bool3); t(inds) = 1 - s(inds); % Region 5 (formerly region 2) % The minimum distance must occur: % * on the line s + t = 1 % * on the line s = 0 with t <= 1 % * or at the intersection of the two (s=0; t=1) inds = find(regIndex == 5); tmp0 = b(inds) + d(inds); tmp1 = c(inds) + e(inds); % minimum on edge s+t = 1, with s > 0 bool2 = tmp1 > tmp0; inds2 = inds(bool2); numer = tmp1(bool2) - tmp0(bool2); denom = a(inds2) - 2 * b(inds2) + c(inds2); bool3 = numer < denom; s(inds2(~bool3)) = 1; inds3 = inds2(bool3); s(inds3) = numer(bool3) ./ denom(bool3); t(inds2) = 1 - s(inds2); % minimum on edge s = 0, with t <= 1 inds2 = inds(~bool2); s(inds2) = 0; t(inds2(tmp1(~bool2) <= 0)) = 1; t(inds2(tmp1(~bool2) > 0 & e(inds2) >= 0)) = 0; inds3 = inds2(tmp1(~bool2) > 0 & e(inds2) < 0); t(inds3) = -e(inds3) ./ c(inds3); % region 6 (formerly region 6) % The minimum distance must occur % * on the line s + t = 1 % * on the line t = 0, with s <= 1 % * at the intersection of the two lines (s=1; t=0) inds = find(regIndex == 6); tmp0 = b(inds) + e(inds); tmp1 = a(inds) + d(inds); % minimum on edge s+t=1, with t > 0 bool2 = tmp1 > tmp0; inds2 = inds(bool2); numer = tmp1(bool2) - tmp0(bool2); denom = a(inds2) - 2 * b(inds2) + c(inds2); bool3 = numer <= denom; t(inds2(~bool3)) = 1; inds3 = inds2(bool3); t(inds3) = numer(bool3) ./ denom(bool3); s(inds2) = 1 - t(inds2); % minimum on edge t = 0 with s <= 1 inds2 = inds(~bool2); t(inds2) = 0; s(inds2(tmp1(~bool2) <= 0)) = 1; s(inds2(tmp1(~bool2) > 0 & d(inds2) >= 0)) = 0; inds3 = inds2(tmp1(~bool2) > 0 & d(inds2) < 0); s(inds3) = -d(inds3) ./ a(inds3); % compute coordinates of closest point on plane projList = p1 + bsxfun(@times, s, v12) + bsxfun(@times, t, v13); % squared distance between point and closest point on plane [dist(i), ind] = min(sum((bsxfun(@minus, point(i,:), projList)).^2, 2)); % keep the valid projection proj(i, :) = projList(ind,:); end % convert squared distance to distance dist = sqrt(dist); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createDurerPolyhedron.m0000644000000000000000000000013214576357161021423 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createDurerPolyhedron.m0000644000175000017500000001000614576357161023200 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createDurerPolyhedron(varargin) %CREATEDURERPOLYHEDRON Create a mesh representing Durer's polyhedron . % % [V, F] = createDurerPolyhedron % [V, E, F] = createDurerPolyhedron % Returns a mesh data structure that represents Durer's polyhedron shown % in "Melancholia". Vertices are stored in V as Nv-by-3 array of 3D % coordinates, faces are stored in Nf-by-1 cell array containing the % vertex indices of each face. % Several hypotheses exist on the exact geometry of the solid. The one % described in Mathworld (see references) is used here. % % Durer's polyhedron is generated from a centered unit cube. Several % transforms are applied succesively: % * Rotation around Oz by PI / 4 % * Rotation around Oy by asec(sqrt(3)) % * z-scaling by sqrt(1 + 3 / sqrt(5) ) % * truncation by two horizontal planes located at a distance of % (3 - sqrt(5)) / 2 from each azimutal vertex. % % Durer's polyhedron is composed of six pentagonal faces and 2 triangular % faces. Pentagonal faces have angles 126, 108, 72, 108, and 126 degrees. % triangular faces are equilateral. % % Example % % Display Durer's polyhedron % [v f] = createDurerPolyhedron; % figure; hold on; set(gcf, 'renderer', 'opengl'); % drawMesh(v, f, 'FaceColor', [.7 .7 .7]); % axis equal; axis([-1 1 -1 1 -1 1]); % view(3) % % See also % meshes3d, createCube, createOctahedron % % References % http://mathworld.wolfram.com/DuerersSolid.html % http://en.wikipedia.org/wiki/Dürer_graph % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-07-31, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % start from a cube basis [v, f] = createCube; % recenter, rotate, and rescale v = v -.5; rot1 = createRotationOz(pi/4); rot2 = createRotationOy(asec(sqrt(3))); sca = createScaling3d([1 1 sqrt(1+3/sqrt(5))]); v = transformPoint3d(v, sca * rot2 * rot1); % compute the height of the two clipping planes d = (3 - sqrt(5)) / 2; zmax = max(v(:,3)); z1 = zmax - d; % clip by two horizontal planes plane1 = createPlane([0 0 z1], [0 0 1]); [v, f] = clipConvexPolyhedronByPlane(v, f, plane1); plane2 = createPlane([0 0 -z1], [0 0 -1]); [v, f] = clipConvexPolyhedronByPlane(v, f, plane2); % complete with edge information e = meshEdges(f); % format output varargout = formatMeshOutput(nargout, v, e, f); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshBoundary.m0000644000000000000000000000013214576357161017552 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshBoundary.m0000644000175000017500000001077714576357161021346 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function polyList = meshBoundary(varargin) %MESHBOUNDARY Boundary of a mesh as a collection of 3D line strings. % % CURVES = meshBoundary(V, F) % % Example % % Example 1 % % create centered icosahedron % [v, f] = createIcosahedron; % v(:,3) = v(:,3) - mean(v(:,3)); % % convert to simili-sphere % [v2, f2] = subdivideMesh(v, f, 3); % v3 = normalizeVector3d(v2); % % clip with plane % plane = createPlane([0 0 0], [-1 -2 3]); % [vc, fc] = clipMeshVertices(v3, f2, plane, 'shape', 'plane'); % figure; drawMesh(vc, fc); axis equal; view(3); % % draw mesh boundary % curves = meshBoundary(vc, fc); % hold on; drawPolygon3d(curves{1}, 'linewidth', 2, 'color', 'b'); % % % Example 2 % mesh = readMesh('mushroom.off'); % plane = createPlane([0 0 0.7], [-1 -2 3]); % mesh = clipMeshVertices(mesh, plane, 'shape', 'plane'); % curves = meshBoundary(mesh); % figure; drawMesh(mesh); axis equal; view(3); % cellfun(@(x) drawPolygon3d(x, 'linewidth', 2, 'color', 'b'), curves) % % See also % meshes3d, meshBoundaryEdgeIndices, meshBoundaryVertexIndices % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-05-01, using Matlab 8.6.0.267246 (R2015b) % Copyright 2019-2023 INRA - Cepia Software Platform [vertices, edges, faces] = parseMeshData(varargin{:}); % Compute edge-vertex map if not specified if isempty(edges) edges = meshEdges(vertices, faces); end bndEdgeInds = meshBoundaryEdgeIndices(vertices, edges, faces); bndEdges = edges(bndEdgeInds, :); if isempty(bndEdgeInds) polyList = {}; return; end % allocate empty array polyList = {}; nPolys = 0; while ~isempty(bndEdges) nPolys = nPolys + 1; % current edge edge = bndEdges(1, :); % initialize new polyline at first vertex ind0 = edge(1); vertexInds = ind0; % current vertex index = edge(2); bndEdges(1, :) = []; % iterate over edges until current vertex becomes ind0 while index ~= ind0 % append current vertex to list of indices for current polygon vertexInds = [vertexInds ; index]; %#ok % index of the next edge containing current vertex edgeInd = find(sum(bndEdges == index, 2) > 0); % check validity if isempty(edgeInd) error('could not find next edge for vertex index %d', index); end if length(edgeInd) > 1 error('two many edges contains vertex index %d', index); end % remove current edge from the list of edges to process edge = bndEdges(edgeInd, :); bndEdges(edgeInd, :) = []; % % check if current edge closes current polygon % if index == ind0 % break; % end % identify the next index index = edge(edge ~= index); end % create the 3D polyline polyList{nPolys} = vertices(vertexInds, :); %#ok end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createOctahedron.m0000644000000000000000000000013214576357161020364 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createOctahedron.m0000644000175000017500000000615314576357161022151 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createOctahedron() %CREATEOCTAHEDRON Create a 3D mesh representing an octahedron. % % [V, E, F] = createOctahedron; % Create a 3D mesh representing an octahedron % V is a 6-by-3 array with vertices coordinate, E is a 12-by-2 array % containing indices of neighbour vertices, and F is a 8-by-3 array % containing array of vertex index for each face. % % [V, F] = createOctahedron; % Returns only the vertices and the face vertex indices. % % MESH = createOctahedron; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % Vertices are located on grid vertices: % ( ±1, 0, 0 ) % ( 0, ±1, 0 ) % ( 0, 0, ±1 ) % % Edge length of returned octahedron is sqrt(2). % Surface area of octahedron is 2*sqrt(3)*a^2, approximately 6.9282 in % this case. % Volume of octahedron is sqrt(2)/3*a^3, approximately 1.3333 in this % case. % % Example % [v, e, f] = createOctahedron; % drawMesh(v, f); % % See also % meshes3d, drawMesh % createCube, createIcosahedron, createDodecahedron, createTetrahedron % createCubeOctahedron % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE nodes = [1 0 0;0 1 0;-1 0 0;0 -1 0;0 0 1;0 0 -1]; edges = [1 2;1 4;1 5; 1 6;2 3;2 5;2 6;3 4;3 5;3 6;4 5;4 6]; faces = [1 2 5;2 3 5;3 4 5;4 1 5;1 6 2;2 6 3;3 6 4;1 4 6]; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshBoundaryVertexIndices.m0000644000000000000000000000013214576357161022247 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshBoundaryVertexIndices.m0000644000175000017500000000525714576357161024040 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function inds = meshBoundaryVertexIndices(varargin) %MESHBOUNDARYVERTEXINDICES Indices of boundary vertices of a mesh. % % INDS = meshBoundaryVertexIndices(V, F) % INDS = meshBoundaryVertexIndices(V, E, F) % % Example % % create centered icosahedron % [v, f] = createIcosahedron; % v(:,3) = v(:,3) - mean(v(:,3)); % % convert to simili-sphere % [v2, f2] = subdivideMesh(v, f, 3); % v3 = normalizeVector3d(v2); % % clip with plane % plane = createPlane([0 0 0], [-1 -2 3]); % [vc, fc] = clipMeshVertices(v3, f2, plane, 'shape', 'plane'); % figure; drawMesh(vc, fc); axis equal; view(3); % % draw boundary vertices % inds = meshBoundaryVertexIndices(vc, fc); % hold on; drawPoint3d(vc(inds,:), 'k*'); % % See also % meshes3d, meshBoundary, meshBoundaryEdgeIndices, meshEdgeFaces % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-05-01, using Matlab 8.6.0.267246 (R2015b) % Copyright 2019-2023 INRA - Cepia Software Platform [vertices, faces] = parseMeshData(varargin{:}); BE = meshBoundaryEdges(vertices, faces); inds = unique(BE(:)); matgeom-1.2.4/inst/meshes3d/PaxHeaders/clipMeshVertices.m0000644000000000000000000000013214576357161020363 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/clipMeshVertices.m0000644000175000017500000001071114576357161022143 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = clipMeshVertices(v, f, b, varargin) %CLIPMESHVERTICES Clip vertices of a surfacic mesh and remove outer faces. % % [V2, F2] = clipMeshVertices(V, F, B) % Clip a mesh represented by vertex array V and face array F, with the % box represented by B. The result is the set of vertices contained in % the box, and a new set of faces corresponding to original faces with % all vertices within the box. % % [V2, F2] = clipMeshVertices(..., 'shape', 'sphere') Specify the shape. % Default is 'box'. But it is also possible to use 'sphere' or 'plane'. % % [V2, F2] = clipMeshVertices(..., 'inside', false) removes the inner % faces instead of the outer faces. % % [V2, F2] = clipMeshVertices(..., 'trimMesh', TF) % Also specifies if the isolated vertices need to be removed (TF=true) or % not (TF=false). Default is false. % % Example % [v, f] = createSoccerBall; % f = triangulateFaces(f); % box = [0 2 -1 2 -.5 2]; % [v2, f2] = clipMeshVertices(v, f, box, 'inside', false); % figure('color','w'); view(3); axis equal % drawMesh(v, f, 'faceColor', 'none', 'faceAlpha', .2); % drawBox3d(box) % drawMesh(v2, f2, 'faceAlpha', .7); % % See also % meshes3d, clipPoints3d % % ------ % Author: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2011-04-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % if input is given as a structure, parse fields if isstruct(v) if nargin > 2 varargin = [b, varargin]; end b = f; f = v.faces; v = v.vertices; end parser = inputParser; validStrings = {'box', 'sphere', 'plane'}; addParameter(parser, 'shape', 'box', @(x) any(validatestring(x, validStrings))); addParameter(parser, 'inside', true, @islogical); addParameter(parser, 'trimMesh', false, @islogical); parse(parser, varargin{:}); % clip the vertices [v2, indVertices] = clipPoints3d(v, b,... 'shape', parser.Results.shape, 'inside', parser.Results.inside); % create index array for face indices relabeling refInds = zeros(size(indVertices)); for i = 1:length(indVertices) refInds(indVertices(i)) = i; end % select the faces with all vertices within the box if isnumeric(f) % Faces given as numeric array indFaces = sum(~ismember(f, indVertices), 2) == 0; f2 = refInds(f(indFaces, :)); elseif iscell(f) % Faces given as cell array nFaces = length(f); indFaces = false(nFaces, 1); for i = 1:nFaces indFaces(i) = sum(~ismember(f{i}, indVertices), 2) == 0; end f2 = f(indFaces, :); % re-label indices of face vertices (keeping horizontal index array) for i = 1:length(f2) f2{i} = refInds(f2{i})'; end end if parser.Results.trimMesh [v2, f2] = trimMesh(v2, f2); end varargout = formatMeshOutput(nargout, v2, f2); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFaceAreas.m0000644000000000000000000000013214576357161017601 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFaceAreas.m0000644000175000017500000000640014576357161021361 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function areas = meshFaceAreas(vertices, faces) %MESHFACEAREAS Surface area of each face of a mesh. % % areas = meshFaceAreas(vertices, faces) % % Example % [v, f] = createOctahedron; % meshFaceAreas(v, f)' % ans = % 1.7321 1.7321 1.7321 1.7321 1.7321 1.7321 1.7321 1.7321 % % See also % meshes3d, meshSurfaceArea, meshFaceCentroids % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-06-21, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018-2023 INRA - Cepia Software Platform if isnumeric(faces) % trimesh or quadmesh nf = size(faces, 1); areas = zeros(nf, 1); if size(vertices, 2) == 2 % planar case for f = 1:nf areas(f,:) = polygonArea(vertices(faces(f,:), :)); end else % 3D case if size(faces, 2) == 3 % For triangular meshes, uses accelerated method v1 = vertices(faces(:,1), :); v12 = vertices(faces(:,2), :) - v1; v13 = vertices(faces(:,3), :) - v1; areas = vectorNorm3d(crossProduct3d(v12, v13))/2; else % for quad (or larger) meshes, use slower but more precise method for f = 1:nf areas(f) = polygonArea3d(vertices(faces(f,:), :)); end end end else % mesh with faces stored as cell array nf = length(faces); areas = zeros(nf, 1); if size(vertices, 2) == 2 % planar case for f = 1:nf areas(f) = polygonArea(vertices(faces{f}, :)); end else % 3D case for f = 1:nf areas(f) = polygonArea3d(vertices(faces{f}, :)); end end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/polyhedronSlice.m0000644000000000000000000000013214576357161020255 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/polyhedronSlice.m0000644000175000017500000000622214576357161022037 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function points = polyhedronSlice(nodes, faces, plane) %POLYHEDRONSLICE Intersect a convex polyhedron with a plane. % % SLICE = polyhedronSlice(NODES, FACES, PLANE) % NODES: a Nx3 array % FACES: either a cell array or a Nf*3 or Nf*4 array % PLANE: a plane representation [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2]. % return the intersection polygon of the polyhedra with the plane, in the % form of a set of ordered points. % % Works only for convex polyhedra. % % Example % polyhedronSlice % % See also % polyhedra, clipConvexPolyhedronByPlane, intersectPlaneMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-09-18, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % if faces is a numeric array, convert it to cell array if isnumeric(faces) faces2 = cell(size(faces, 1), 1); for f = 1:length(faces2) faces2{f} = faces(f,:); end faces = faces2; else % ensure we have face with horizontal vectors... for f = 1:length(faces) face = faces{f}; faces{f} = face(:)'; end end % compute edges of the polyhedron inds = zeros(0, 2); for f = 1:length(faces) face = faces{f}'; inds = [inds ; sort([face face([2:end 1])], 2)]; %#ok end inds = unique(inds, 'rows'); edges = [nodes(inds(:,1), :) nodes(inds(:,2), :)]; % intersection of edges with plane points = intersectEdgePlane(edges, plane); points = points(sum(isfinite(points), 2)==3, :); if ~isempty(points) points = angleSort3d(points); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/averageMesh.m0000644000000000000000000000013214576357161017341 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/averageMesh.m0000644000175000017500000001315314576357161021124 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [avgMesh, distsIters, verticesIters] = averageMesh(meshList, varargin) %AVERAGEMESH Compute average mesh from a list of meshes. % % AVGMESH = averageMesh(MESHLIST) % Where MESHLIST is a cell array of meshes, computes an average mesh that % minimizes the sum of squared distances between average mesh vertices % and all other mesh vertices. % The method is to choose an arbitrary reference mesh, and to iterate a % series of smoothin of the reference mesh, computation of nearest vertex % neighbors, and computing average position of nearest neighbors. % % [AVGMESH, DISTS] = averageMesh(MESHLIST) % Returns also a cell array containing for each iteration, the standard % deviation of distances to other individual meshes. % % [AVGMESH, DISTS, VERT_ITERS] = averageMesh(MESHLIST) % Also returns for each iteration, the positions of the average vertices. % % [AVGMESH, DISTS] = averageMesh(..., PNAME, PVALUE) % Provides addition options are parameter name-value pairs. Available % options are: % * verbose: (logical, default false) display or not information about % process % * nIters: number of smooth-projection iterations to perform. Default % value is 10. % * smoothingIteration: the number of smoothing operations to apply on % average mesh at each iteration. Default value is 3. % % % Example % averageMesh % % See also % meshes3d, smoothMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-01-31, using Matlab 9.7.0.1247435 (R2019b) Update 2 % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Parse input values % default values nIters = 10; verbose = false; smoothingIterations = 3; % parse input arguments while length(varargin) > 1 name = varargin{1}; if ~ischar(name) error('require parameter name-value pairs'); end if strcmpi(name, 'verbose') verbose = varargin{2}; elseif strcmpi(name, 'nIters') nIters = varargin{2}; elseif strcmpi(name, 'smoothingIterations') smoothingIterations = varargin{2}; else error(['Unknown parameter name: ' name]); end varargin(1:2) = []; end %% Initialisations nMeshes = length(meshList); % initialize kd-trees to accelerate nearest-neighbor searches treeList = cell(nMeshes, 1); for iMesh = 1:nMeshes treeList{iMesh} = KDTreeSearcher(meshList{iMesh}.vertices); end % choose arbitrary initial mesh avgMesh = struct('vertices', meshList{1}.vertices, 'faces', meshList{1}.faces); verticesIters = cell(1, nIters); distsIters = cell(1, nIters); %% Main iteration % iterates smoothing + computation of average projections for iIter = 1:nIters if verbose fprintf('iter %d/%d\n', iIter, nIters); end % apply smoothing to current average mesh avgMesh = smoothMesh(avgMesh, smoothingIterations); % create new array for average vertices newVerts = zeros(size(avgMesh.vertices)); dists = zeros(size(avgMesh.vertices, 1), 1); % iterate over all meshes for iMesh = 1:nMeshes if verbose fprintf(' mesh %d/%d\n', iMesh, nMeshes); end % for each vertex of reference mesh, find index of closest vertex % in current mesh inds = knnsearch(treeList{iMesh}, avgMesh.vertices); % keep position of closest vertex to update new position closest = treeList{iMesh}.X(inds,:); newVerts = newVerts + closest; % keep distance to closest index to build variability map dists = dists + sum((closest - avgMesh.vertices).^2, 2); end % update position of new vertices newVerts = newVerts / nMeshes; verticesIters{iIter} = newVerts; avgMesh.vertices = newVerts; % keep list of distances dists = sqrt(dists / nMeshes); distsIters{iIter} = dists; end % figure; drawMesh(refMesh, 'lineStyle', 'none', 'faceColor', [.5 .5 .5]) % axis equal; view(3); hold on; axis([-2.5 2.5 -2 2 -3.5 3.5]); light; % lighting gouraud % title('Average mesh'); % print(gcf, 'averageMesh_initial.png', '-dpng'); matgeom-1.2.4/inst/meshes3d/PaxHeaders/polyhedronCentroid.m0000644000000000000000000000013214576357161020765 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/polyhedronCentroid.m0000644000175000017500000000640414576357161022551 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function centroid = polyhedronCentroid(vertices, faces) %#ok %POLYHEDRONCENTROID Compute the centroid of a 3D convex polyhedron. % % CENTRO = polyhedronCentroid(V, F) % Computes the centroid (center of mass) of the polyhedron defined by % vertices V and faces F. % The polyhedron is assumed to be convex. % % Example % % Creates a polyhedron centered on origin, and add an arbitrary % % translation % [v, f] = createDodecahedron; % v2 = bsxfun(@plus, v, [3 4 5]); % % computes the centroid, that should equal the translation vector % centroid = polyhedronCentroid(v2, f) % centroid = % 3.0000 4.0000 5.0000 % % % See also % meshes3d, meshVolume, meshSurfaceArea, polyhedronMeanBreadth % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-04-05, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % compute set of elementary tetrahedra DT = delaunayTriangulation(vertices); T = DT.ConnectivityList; % number of tetrahedra nT = size(T, 1); % initialize result centroid = zeros(1, 3); vt = 0; % Compute the centroid and the volume of each tetrahedron for i = 1:nT % coordinates of tetrahedron vertices tetra = vertices(T(i, :), :); % centroid is the average of vertices. centi = mean(tetra); % compute volume of tetrahedron vol = det(tetra(1:3,:) - tetra([4 4 4],:)) / 6; % add weighted centroid of current tetraedron centroid = centroid + centi * vol; % compute the sum of tetraedra volumes vt = vt + vol; end % compute by sum of tetrahedron volumes centroid = centroid / vt; matgeom-1.2.4/inst/meshes3d/PaxHeaders/concatenateMeshes.m0000644000000000000000000000013214576357161020543 xustar0030 mtime=1710874225.154193329 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/concatenateMeshes.m0000644000175000017500000001017614576357161022330 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = concatenateMeshes(varargin) %CONCATENATEMESHES Concatenate multiple meshes. % % [V,F] = concatenateMeshes(V1,F1,V2,F2, ...) % Returns one mesh represented by vertices V and faces F by concatenating % the meshes defined by V1, V2, ... and F1, F2, ... % % [V,F] = concatenateMeshes(MESH1, MESH2, ...) % where MESH1, MESH2, ... are structs or struct arrays with the fields % vertices and faces % % See also % splitMesh % ------ % Authors: oqilipo (parsing), Alec Jacobson (loop) % E-mail: N/A % Created: 2017-09-12 % Copyright 2017-2023 %% parsing inputs assert(~isempty(varargin)) if isstruct(varargin{1}) VF_fields = {'vertices','faces'}; errorStructFields=['If the first input argument is a struct '... 'with the fields vertices and faces the additonal ' ... 'arguments must have the same format']; % Check, if all input arguments are structs assert(all(cellfun(@isstruct, varargin)), errorStructFields) % Check, if all structs contain the two fields vertices and faces assert(all(cellfun(@(x) all(ismember(fieldnames(x), ... VF_fields)), varargin)), errorStructFields) if length(varargin)==1 errorArgAndStructLength = ['If the input is only one struct ' ... 'it has to contain more than one mesh.']; assert(length(varargin{1})>1, ... errorArgAndStructLength) end % Order of the fields: vertices, faces varargin = cellfun(@(x) orderfields(x, VF_fields),varargin, 'UniformOutput',0); % Convert the structs into one cell array varargin = ... cellfun(@struct2cell, varargin, 'UniformOutput', false); varargin = cellfun(@squeeze, varargin, 'UniformOutput',0); varargin = reshape([varargin{:}],[],1)'; end NoA = length(varargin); assert(mod(NoA,2)==0); cellfun(@(x) validateattributes(x, {'numeric'},... {'size',[NaN,3],'finite'}), varargin(1:2:end)) cellfun(@(x) validateattributes(x, {'numeric'},... {'integer'}), varargin(2:2:end)) % Check if all faces have the same number of columns errorFacesRows='The faces of all meshes must have the same number of columns'; assert(numel(unique(cellfun(@(x) size(x,2), varargin(2:2:end))))==1, errorFacesRows) %% loop v=[]; f=[]; for m = 1:NoA/2 vm = varargin{2*m-1}; fm = varargin{2*m}; f = [f; fm+size(v,1)]; %#ok v = [v; vm]; %#ok end %% parsing outputs [v, f] = trimMesh(v, f); switch nargout case 1 mesh.vertices=v; mesh.faces=f; varargout{1}=mesh; case 2 varargout{1}=v; varargout{2}=f; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/removeMeshVertices.m0000644000000000000000000000013214576357161020731 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.154193329 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/removeMeshVertices.m0000644000175000017500000000701214576357161022511 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = removeMeshVertices(vertices, faces, indsToRemove) %REMOVEMESHVERTICES Remove vertices and associated faces from a mesh. % % [V2, F2] = removeMeshVertices(VERTS, FACES, VERTINDS) % Removes the vertices specified by the vertex indices VERTINDS, and % remove the faces containing one of the removed vertices. % % Example % % remove some vertices from a soccerball polyhedron % [v, f] = createSoccerBall; % plane = createPlane([.6 0 0], [1 0 0]); % indAbove = find(~isBelowPlane(v, plane)); % [v2, f2] = removeMeshVertices(v, f, indAbove); % drawMesh(v2, f2); % axis equal; hold on; % % See also % meshes3d, trimMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2016-02-03, using Matlab 8.6.0.267246 (R2015b) % Copyright 2016-2023 INRA - Cepia Software Platform % parse inputs if nargin == 2 indsToRemove = faces; [vertices, faces] = parseMeshData(vertices); end % create array of indices to keep nVertices = size(vertices, 1); newInds = (1:nVertices)'; newInds(indsToRemove) = []; % create new vertex array vertices2 = vertices(newInds, :); % compute map from old indices to new indices oldNewMap = zeros(nVertices, 1); for iIndex = 1:size(newInds, 1) oldNewMap(newInds(iIndex)) = iIndex; end % change labels of vertices referenced by faces if isnumeric(faces) faces2 = oldNewMap(faces); if size(faces2,2)==1; faces2=faces2'; end % keep only faces with valid vertices faces2 = faces2(sum(faces2 == 0, 2) == 0, :); elseif iscell(faces) faces2 = cell(1, length(faces)); for iFace = 1:length(faces) newFace = oldNewMap(faces{iFace}); % add the new face only if all vertices are valid if ~any(newFace == 0) faces2{iFace} = newFace; end end % remove empty faces faces2 = faces2(~cellfun(@isempty, faces2)); end % format output arguments varargout = formatMeshOutput(nargout, vertices2, faces2); matgeom-1.2.4/inst/meshes3d/PaxHeaders/mushroom.off0000644000000000000000000000013214576357160017300 xustar0030 mtime=1710874224.642193819 30 atime=1710874224.634193826 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/mushroom.off0000644000175000017500000003036714576357160021071 0ustar00juanpijuanpi00000000000000OFF 226 448 0 0.0184074 0.354329 -0.024123 0.34662 0.338337 -0.0333459 0.619946 0.233133 -0.0410264 0.802164 0.111095 -0.0461463 0.945962 0 -0.0501877 0.933888 -0.0967886 -0.0498478 0.876808 -0.16496 -0.0482442 0.666049 -0.144762 -0.0423219 0.320274 -0.0875299 -0.032606 0.10293 -0.131295 -0.0264984 0.0974423 -0.305513 -0.0263437 0.234654 -0.600927 -0.0301999 0.307102 -0.806286 -0.0322353 0.243436 -0.877825 -0.0304465 0.150131 -0.8854 -0.0278245 0.0184074 -0.881192 -0.024123 0.295122 0.338337 0.103678 0.525565 0.233133 0.210107 0.679193 0.111095 0.28106 0.80043 0 0.337053 0.790249 -0.0967886 0.332351 0.742125 -0.16496 0.310125 0.564434 -0.144762 0.228059 0.272911 -0.0875299 0.0934197 0.0896685 -0.131295 0.00878897 0.0850418 -0.305513 0.00665224 0.200725 -0.600927 0.0600799 0.261806 -0.806286 0.0882906 0.208128 -0.877825 0.0635003 0.129464 -0.8854 0.0271679 0.208881 0.338337 0.165273 0.367504 0.233133 0.322996 0.473253 0.111095 0.428146 0.556706 0 0.511125 0.549698 -0.0967886 0.504157 0.516572 -0.16496 0.471219 0.39426 -0.144762 0.3496 0.193592 -0.0875299 0.15007 0.0674588 -0.131295 0.0246511 0.0642744 -0.305513 0.021484 0.143904 -0.600927 0.100663 0.185948 -0.806286 0.142468 0.149 -0.877825 0.10573 0.0948524 -0.8854 0.0518889 0.103718 0.338337 0.27331 0.174762 0.233133 0.521005 0.222124 0.111095 0.686136 0.259502 0 0.816448 0.256363 -0.0967886 0.805506 0.241527 -0.16496 0.753779 0.186745 -0.144762 0.562785 0.0968705 -0.0875299 0.249435 0.0403771 -0.131295 0.0524739 0.0389509 -0.305513 0.0474993 0.0746154 -0.600927 0.171844 0.0934461 -0.806286 0.237499 0.0768974 -0.877825 0.179803 0.0526457 -0.8854 0.0952486 0.0184074 0.338337 0.338198 0.0184074 0.233133 0.639931 0.0184074 0.111095 0.841086 0.0184074 0 0.99983 0.0184074 -0.0967886 0.9865 0.0184074 -0.16496 0.923487 0.0184074 -0.144762 0.690826 0.0184074 -0.0875299 0.309116 0.0184074 -0.131295 0.0691839 0.0184074 -0.305513 0.0631256 0.0184074 -0.600927 0.214597 0.0184074 -0.806286 0.294575 0.0184074 -0.877825 0.224292 0.0184074 -0.8854 0.12129 -0.11218 0.338337 0.310618 -0.22093 0.233133 0.589383 -0.29343 0.111095 0.775226 -0.350644 0 0.921885 -0.34584 -0.0967886 0.909571 -0.323129 -0.16496 0.851354 -0.239273 -0.144762 0.636403 -0.101699 -0.0875299 0.28375 -0.0152218 -0.131295 0.0620819 -0.0130384 -0.305513 0.0564835 -0.0676323 -0.600927 0.196425 -0.0964574 -0.806286 0.270315 -0.0711259 -0.877825 0.205383 -0.0340018 -0.8854 0.110222 -0.196264 0.338337 0.216986 -0.375037 0.233133 0.417774 -0.494219 0.111095 0.551634 -0.588273 0 0.657271 -0.580376 -0.0967886 0.648401 -0.543042 -0.16496 0.606469 -0.405193 -0.144762 0.451643 -0.179033 -0.0875299 0.197633 -0.0368757 -0.131295 0.0379687 -0.033286 -0.305513 0.0339365 -0.123031 -0.600927 0.134735 -0.170418 -0.806286 0.187956 -0.128775 -0.877825 0.141186 -0.0677482 -0.8854 0.072643 -0.249622 0.338337 0.12377 -0.472831 0.233133 0.246932 -0.621637 0.111095 0.32904 -0.739067 0 0.393836 -0.729206 -0.0967886 0.388395 -0.682593 -0.16496 0.362674 -0.51048 -0.144762 0.267706 -0.228108 -0.0875299 0.111898 -0.0506171 -0.131295 0.0139635 -0.0461344 -0.305513 0.0114895 -0.158187 -0.600927 0.0733188 -0.217351 -0.806286 0.105964 -0.165359 -0.877825 0.077275 -0.0891635 -0.8854 0.0352323 -0.269476 0.338337 0.00354499 -0.509218 0.233133 0.0265865 -0.669046 0.111095 0.0419476 -0.795175 0 0.0540695 -0.784585 -0.0967886 0.0530524 -0.734518 -0.16496 0.0482405 -0.549657 -0.144762 0.0304735 -0.246368 -0.0875299 0.00132441 -0.0557303 -0.131295 -0.0169984 -0.0509157 -0.305513 -0.0174609 -0.171268 -0.600927 -0.00589341 -0.234814 -0.806286 0.000214196 -0.178971 -0.877825 -0.00515362 -0.0971306 -0.8854 -0.0130181 -0.262652 0.338337 -0.148301 -0.496709 0.233133 -0.251713 -0.652749 0.111095 -0.320654 -0.775889 0 -0.37506 -0.765549 -0.0967886 -0.370492 -0.716668 -0.16496 -0.348895 -0.53619 -0.144762 -0.269155 -0.240091 -0.0875299 -0.138333 -0.0539721 -0.131295 -0.056102 -0.0492721 -0.305513 -0.0540252 -0.166772 -0.600927 -0.105939 -0.228812 -0.806286 -0.133349 -0.174291 -0.877825 -0.109261 -0.0943927 -0.8854 -0.0739595 -0.222887 0.338337 -0.280322 -0.42383 0.233133 -0.493681 -0.557793 0.111095 -0.635918 -0.66351 0 -0.748166 -0.654633 -0.0967886 -0.738741 -0.612669 -0.16496 -0.694184 -0.457724 -0.144762 -0.529668 -0.203519 -0.0875299 -0.259759 -0.0437324 -0.131295 -0.0901003 -0.0396975 -0.305513 -0.0858162 -0.140572 -0.600927 -0.192923 -0.193834 -0.806286 -0.249477 -0.147028 -0.877825 -0.199779 -0.0784332 -0.8854 -0.126946 -0.114676 0.338337 -0.332426 -0.225506 0.233133 -0.589172 -0.299392 0.111095 -0.760337 -0.357699 0 -0.895414 -0.352803 -0.0967886 -0.884071 -0.329658 -0.16496 -0.830453 -0.2442 -0.144762 -0.63248 -0.103994 -0.0875299 -0.307679 -0.0158656 -0.131295 -0.103519 -0.0136396 -0.305513 -0.0983633 -0.0692771 -0.600927 -0.227252 -0.0986528 -0.806286 -0.295306 -0.0728375 -0.877825 -0.235502 -0.0350042 -0.8854 -0.147856 0.0184074 0.338337 -0.339672 0.0184074 0.233133 -0.602454 0.0184074 0.111095 -0.777642 0.0184074 0 -0.915893 0.0184074 -0.0967886 -0.904283 0.0184074 -0.16496 -0.849405 0.0184074 -0.144762 -0.646779 0.0184074 -0.0875299 -0.314343 0.0184074 -0.131295 -0.105385 0.0184074 -0.305513 -0.100108 0.0184074 -0.600927 -0.232027 0.0184074 -0.806286 -0.301679 0.0184074 -0.877825 -0.24047 0.0184074 -0.8854 -0.150764 0.128226 0.338337 -0.295865 0.219678 0.233133 -0.522163 0.280648 0.111095 -0.67303 0.328761 0 -0.792087 0.324722 -0.0967886 -0.78209 0.305622 -0.16496 -0.734831 0.235105 -0.144762 -0.560335 0.119411 -0.0875299 -0.274052 0.0466887 -0.131295 -0.0941032 0.0448519 -0.305513 -0.0895592 0.0907615 -0.600927 -0.203163 0.115003 -0.806286 -0.263146 0.0937007 -0.877825 -0.210434 0.0624815 -0.8854 -0.133183 0.247039 0.338337 -0.245139 0.437438 0.233133 -0.429196 0.56437 0.111095 -0.5519 0.66454 0 -0.648734 0.656129 -0.0967886 -0.640603 0.616367 -0.16496 -0.602166 0.469553 -0.144762 -0.460242 0.228688 -0.0875299 -0.227399 0.0772853 -0.131295 -0.0810402 0.0734624 -0.305513 -0.077344 0.169045 -0.600927 -0.169742 0.219512 -0.806286 -0.218528 0.175162 -0.877825 -0.175656 0.110165 -0.8854 -0.112824 0.333673 0.338337 -0.162777 0.596218 0.233133 -0.278246 0.771249 0.111095 -0.355224 0.909376 0 -0.415972 0.897777 -0.0967886 -0.410871 0.842948 -0.16496 -0.386758 0.640503 -0.144762 -0.297722 0.308368 -0.0875299 -0.151648 0.0995963 -0.131295 -0.0598303 0.0943245 -0.305513 -0.0575109 0.226125 -0.600927 -0.115477 0.295714 -0.806286 -0.146083 0.234559 -0.877825 -0.119187 0.144936 -0.8854 -0.0797698 3 16 1 0 3 2 1 16 3 3 2 17 3 4 3 18 3 5 4 19 3 6 5 20 3 7 6 21 3 8 7 22 3 9 8 23 3 10 9 24 3 11 10 25 3 12 11 26 3 13 12 27 3 14 13 28 3 29 15 14 3 30 16 0 3 17 16 30 3 18 17 31 3 19 18 32 3 20 19 33 3 21 20 34 3 22 21 35 3 23 22 36 3 24 23 37 3 25 24 38 3 26 25 39 3 27 26 40 3 28 27 41 3 29 28 42 3 43 15 29 3 44 30 0 3 31 30 44 3 32 31 45 3 33 32 46 3 34 33 47 3 35 34 48 3 36 35 49 3 37 36 50 3 38 37 51 3 39 38 52 3 40 39 53 3 41 40 54 3 42 41 55 3 43 42 56 3 57 15 43 3 58 44 0 3 45 44 58 3 46 45 59 3 47 46 60 3 48 47 61 3 49 48 62 3 50 49 63 3 51 50 64 3 52 51 65 3 53 52 66 3 54 53 67 3 55 54 68 3 56 55 69 3 57 56 70 3 71 15 57 3 72 58 0 3 59 58 72 3 60 59 73 3 61 60 74 3 62 61 75 3 63 62 76 3 64 63 77 3 65 64 78 3 66 65 79 3 67 66 80 3 68 67 81 3 69 68 82 3 70 69 83 3 71 70 84 3 85 15 71 3 86 72 0 3 73 72 86 3 74 73 87 3 75 74 88 3 76 75 89 3 77 76 90 3 78 77 91 3 79 78 92 3 80 79 93 3 81 80 94 3 82 81 95 3 83 82 96 3 84 83 97 3 85 84 98 3 99 15 85 3 100 86 0 3 87 86 100 3 88 87 101 3 89 88 102 3 90 89 103 3 91 90 104 3 92 91 105 3 93 92 106 3 94 93 107 3 95 94 108 3 96 95 109 3 97 96 110 3 98 97 111 3 99 98 112 3 113 15 99 3 114 100 0 3 101 100 114 3 102 101 115 3 103 102 116 3 104 103 117 3 105 104 118 3 106 105 119 3 107 106 120 3 108 107 121 3 109 108 122 3 110 109 123 3 111 110 124 3 112 111 125 3 113 112 126 3 127 15 113 3 128 114 0 3 115 114 128 3 116 115 129 3 117 116 130 3 118 117 131 3 119 118 132 3 120 119 133 3 121 120 134 3 122 121 135 3 123 122 136 3 124 123 137 3 125 124 138 3 126 125 139 3 127 126 140 3 141 15 127 3 142 128 0 3 129 128 142 3 130 129 143 3 131 130 144 3 132 131 145 3 133 132 146 3 134 133 147 3 135 134 148 3 136 135 149 3 137 136 150 3 138 137 151 3 139 138 152 3 140 139 153 3 141 140 154 3 155 15 141 3 156 142 0 3 143 142 156 3 144 143 157 3 145 144 158 3 146 145 159 3 147 146 160 3 148 147 161 3 149 148 162 3 150 149 163 3 151 150 164 3 152 151 165 3 153 152 166 3 154 153 167 3 155 154 168 3 169 15 155 3 170 156 0 3 157 156 170 3 158 157 171 3 159 158 172 3 160 159 173 3 161 160 174 3 162 161 175 3 163 162 176 3 164 163 177 3 165 164 178 3 166 165 179 3 167 166 180 3 168 167 181 3 169 168 182 3 183 15 169 3 184 170 0 3 171 170 184 3 172 171 185 3 173 172 186 3 174 173 187 3 175 174 188 3 176 175 189 3 177 176 190 3 178 177 191 3 179 178 192 3 180 179 193 3 181 180 194 3 182 181 195 3 183 182 196 3 197 15 183 3 198 184 0 3 185 184 198 3 186 185 199 3 187 186 200 3 188 187 201 3 189 188 202 3 190 189 203 3 191 190 204 3 192 191 205 3 193 192 206 3 194 193 207 3 195 194 208 3 196 195 209 3 197 196 210 3 211 15 197 3 212 198 0 3 199 198 212 3 200 199 213 3 201 200 214 3 202 201 215 3 203 202 216 3 204 203 217 3 205 204 218 3 206 205 219 3 207 206 220 3 208 207 221 3 209 208 222 3 210 209 223 3 211 210 224 3 225 15 211 3 1 212 0 3 213 212 1 3 214 213 2 3 215 214 3 3 216 215 4 3 217 216 5 3 218 217 6 3 219 218 7 3 220 219 8 3 221 220 9 3 222 221 10 3 223 222 11 3 224 223 12 3 225 224 13 3 14 15 225 3 16 17 2 3 17 18 3 3 18 19 4 3 19 20 5 3 20 21 6 3 21 22 7 3 22 23 8 3 23 24 9 3 24 25 10 3 25 26 11 3 26 27 12 3 27 28 13 3 28 29 14 3 30 31 17 3 31 32 18 3 32 33 19 3 33 34 20 3 34 35 21 3 35 36 22 3 36 37 23 3 37 38 24 3 38 39 25 3 39 40 26 3 40 41 27 3 41 42 28 3 42 43 29 3 44 45 31 3 45 46 32 3 46 47 33 3 47 48 34 3 48 49 35 3 49 50 36 3 50 51 37 3 51 52 38 3 52 53 39 3 53 54 40 3 54 55 41 3 55 56 42 3 56 57 43 3 58 59 45 3 59 60 46 3 60 61 47 3 61 62 48 3 62 63 49 3 63 64 50 3 64 65 51 3 65 66 52 3 66 67 53 3 67 68 54 3 68 69 55 3 69 70 56 3 70 71 57 3 72 73 59 3 73 74 60 3 74 75 61 3 75 76 62 3 76 77 63 3 77 78 64 3 78 79 65 3 79 80 66 3 80 81 67 3 81 82 68 3 82 83 69 3 83 84 70 3 84 85 71 3 86 87 73 3 87 88 74 3 88 89 75 3 89 90 76 3 90 91 77 3 91 92 78 3 92 93 79 3 93 94 80 3 94 95 81 3 95 96 82 3 96 97 83 3 97 98 84 3 98 99 85 3 100 101 87 3 101 102 88 3 102 103 89 3 103 104 90 3 104 105 91 3 105 106 92 3 106 107 93 3 107 108 94 3 108 109 95 3 109 110 96 3 110 111 97 3 111 112 98 3 112 113 99 3 114 115 101 3 115 116 102 3 116 117 103 3 117 118 104 3 118 119 105 3 119 120 106 3 120 121 107 3 121 122 108 3 122 123 109 3 123 124 110 3 124 125 111 3 125 126 112 3 126 127 113 3 128 129 115 3 129 130 116 3 130 131 117 3 131 132 118 3 132 133 119 3 133 134 120 3 134 135 121 3 135 136 122 3 136 137 123 3 137 138 124 3 138 139 125 3 139 140 126 3 140 141 127 3 142 143 129 3 143 144 130 3 144 145 131 3 145 146 132 3 146 147 133 3 147 148 134 3 148 149 135 3 149 150 136 3 150 151 137 3 151 152 138 3 152 153 139 3 153 154 140 3 154 155 141 3 156 157 143 3 157 158 144 3 158 159 145 3 159 160 146 3 160 161 147 3 161 162 148 3 162 163 149 3 163 164 150 3 164 165 151 3 165 166 152 3 166 167 153 3 167 168 154 3 168 169 155 3 170 171 157 3 171 172 158 3 172 173 159 3 173 174 160 3 174 175 161 3 175 176 162 3 176 177 163 3 177 178 164 3 178 179 165 3 179 180 166 3 180 181 167 3 181 182 168 3 182 183 169 3 184 185 171 3 185 186 172 3 186 187 173 3 187 188 174 3 188 189 175 3 189 190 176 3 190 191 177 3 191 192 178 3 192 193 179 3 193 194 180 3 194 195 181 3 195 196 182 3 196 197 183 3 198 199 185 3 199 200 186 3 200 201 187 3 201 202 188 3 202 203 189 3 203 204 190 3 204 205 191 3 205 206 192 3 206 207 193 3 207 208 194 3 208 209 195 3 209 210 196 3 210 211 197 3 212 213 199 3 213 214 200 3 214 215 201 3 215 216 202 3 216 217 203 3 217 218 204 3 218 219 205 3 219 220 206 3 220 221 207 3 221 222 208 3 222 223 209 3 223 224 210 3 224 225 211 3 1 2 213 3 2 3 214 3 3 4 215 3 4 5 216 3 5 6 217 3 6 7 218 3 7 8 219 3 8 9 220 3 9 10 221 3 10 11 222 3 11 12 223 3 12 13 224 3 13 14 225 # End of OFF # matgeom-1.2.4/inst/meshes3d/PaxHeaders/bunny_F5k.ply0000644000000000000000000000013214576357160017321 xustar0030 mtime=1710874224.682193781 30 atime=1710874224.670193794 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/bunny_F5k.ply0000644000175000017500000027215214576357160021112 0ustar00juanpijuanpi00000000000000ply format binary_little_endian 1.0 comment VCGLIB generated element vertex 2505 property float x property float y property float z element face 5006 property list uchar int vertex_indices end_header Rš}ÀŠ?×@,<AWûdÀÙÐÊ@üOö@¸ ‰ÀâÔº@3ÄÌ@qåfÀžÂÓ@±áê@á§À=›@ûË»@ ’ÀëÔ@bö@oç¤ÀÓ?‹@wí@ð?cÆ“@ÛàÍ¿ÙÈ®>9]‡@1X6À“ @Å]Š@oÄÀÀ&@a_‚@œð¹=¬K8@B…|@¢DuÀ4¨¾£ÜR@nCÀ“H¢@@$R@Ÿ®‡¿ŽW?ZIN@ó+A³ìÖ?ÏgO@:P¹Àë‘>¥6f@÷’ÀÔǵ¾ A@é†À²’@‹FV@Õˆ€ÀÖZc@[æY@—ÀÊA§@á­?@†¾ýˆÁ?}ëi@jÞAµªL?»¹?@¯A‘Wx@•©%@Rà·ÀK›Àfÿ@@¶èí:ð>Ú¿¦XB@yR>ÕcQ@´`=@¦L˜?Àj¡@Ÿö!@*™”ÀWù´@»v8@cç꿳ÏÚ¿"1.@ÚÊ?öBÃ?A@@¡Ûð@5,?O¯*@z¥AG uÀ²#+@¸wN¿úÆ€@Q&@\á?2µ‹Àè~@~bÞ@’±>¸Žõ?n" AßÅ~Àã“H?òµÅ@¿ÒÀœ3 @+¸ÀTÄ2¿<¤@I€Àr?@”¾ò?ª?@òÒ{ÀÞÇÓ?R¸š@JŸ?5²@™â@õ ÀÎèÀ?®Ù@Û‘oÀRô¯?hX§Àó_O?…ÎÙ?æyÜ@€G¿<$§?öœAoTݽ–Ëæ?j A® ¿õL7?"2²Àñ77Àç ¥?gÀÂS@¿É?´bO@ âPÀXY‹?çÆ®@HÜ™À%XÆ? ¢@>\‰ÀÁ‚?<·ÀÄyPÀšÏV?À¤‘À¾tø@íê‡?¥âRÀ0à@žˆ?8¿æ¿¬Àv Œ?Ц–@—ªTÀÞ?ñcÇ@¿î@P• ?ÿÿ—À˜ ÉÀ9Eã¾ÀJª@í—Àv?âíÀUýÀyca>6Å‹@?Àž@Hc¤ÍÀ¬JÌÀI3‡>þ:@Z·À‹Á?Æm¡@¡sÀÈY> {°Àw#ø¾Å´÷¾x¸À³ÍŠ@K¯z>Ìp^@%æÍ@D¾—sÊ@\ô)À‰|±¿m#nÀ)%&À(óÀÑé…ÀF¡[¾²¥÷¿Ùý/@Ï^ÒÀ¿ÀL‡Àé· Àj"À ý@²fbÀšbSÀ­óµÀŽÎ–@¹DÀh¬ÀëCÀÀ¦ëŠ@4±«Àæ4PÀü§@Oò•ÀõFÀ?ú= ?ÆÀ¨“EÀ¢+ @TòŒ@f¦ À2–(@Ά@yêYÀé·À6O‡¾Ë…=À„ÓpÀ0ò€Àô³=À ïÚ?0bÀâä&ÀkÊ…ÀÊS‡À§TÀ-:¿Ùw£¿KXTÀ¼‘·Àu3w@ê*AÀê•@:ã¬À°ãTÀ•ç?á´¿'[À•!‰¿wÓ¸À˜ÜxÀ@Y@¾Àî tÀÜs@)´G¾b‰ÀÊ_´À”“?ý‹À.À~ûn@‚&…ÀxÀoŒX?j‡Àò³Àu¨À°Ü‰À±ÀI@pD@„éÀ7õ6>»®%@‡;˜À@Üʾ¦_ÀÜ•²@,>ê@qœÀ žº@XôAT—”ÀjöÀ@e ASjÀì ¨@7î@‹ë£Àòêž@¦aù@_Ó¤Àx3˜@˜/ø@,w'?y"“@E×ÀÓ‰E?W&•@MH“¿¦Ý?¶=“@d•q¿Åì?Tº.?ºt@¤Êe>ÖÕ£ÀP²}@Ö´æ@Ú¯“ÀôŠy@ð¦õ@-ZqÀXé0@ °@µ‰žÀHÅo@˜ð@º[ì>r«a@t%¹ÀÆ=ƒ@ÇW^@‹…ÀwÀŠ?]¹[@2¨ A•«@šI@§²´ÀQíN@óœT@‹®ŸÀ¾ã@UN@4ÚŽÀ€ë†¾Z%O@cÀ9ZÎ>Ÿò6@*¶ A”4…?ÅQ@ÞÙAu¤v?õ*H@»¸Ad‚@<@J€¬À<}u¿²O@rCO¿àM¨¿m‰C@_k ?'w@ù·=@Àòm?òÑÍ?#+K@ÇÑ…?@ä\I@?ˆ?™iÀœ.@Ô¹À|h•¿H6@3û”ÀMÓ•@+X8@,±—ÀŽT¿ƒB'@Á–ƒÀý¿UÀà­4@•5Ç U¿¸¬9@‹ˆ©?ŠZÀ=vœ6@æ˜Ì?õÂ@é.4@Fòï?Á£m?&÷!@_kAG_@?xï,@A8-@¸h#@r4Â?Ÿƒ@¦ú@Õ_¹Àùú<À@8mÿ¿v©è¿:U@Eã@Þ%ÿ-!@×”ÿ?N@ª%@s­#@Ò–¹>75 @¥3AqÉÀì+@x»ÀÐ'ÀÇ @ÝźÀrÅÓ¿zE @>-¼À›DÁ@“,@3á>ÀÃÀÚ@Fu&Àæj‡À¾¥@¸ >P¾š¾nÏ@ÛÇAPÕ@Á@Á?û¶=Àê6€ÀË*Í?ŽVÀ „@<ò@Æö?™ñ¦@Ÿé?ÙH@XAÀruÊ?š«L@×™ƒ@CëÑ?²ó=@vp¢Àé@±íÎ@ˆ!Ë¿éÎ?‡€»ÀèÄñ¿9Cø?‘À»¸¿Qkö?킃ÀV‘Àž°ò?ÍÙXÀ”)ÀœP¹?Gõ…ÀçR­À†›Ï? c>,!ŠÀn*Ö? $;@uEÀ+"Í?Üe„@Dý§Àø°²?ãÿn@iÀ¿?F¤@ì ¾lÑ?ž ARJÀ–_à?ÍÚ·ÀNíÚ@Õʺ?[£F¿§ À]Þ¦?I¾@”¢–@ø«º?·v³Àéú=ÀQ§¼?O„DÀ5¥@p?Yb-@™X@©S‘?!=_@=˜À‡?Úí¼À$‚«ÀË?P½¿ÒfºÀ–†3?û*U¿ÉºÀ*]?BrÔ½ á¿@º‹4?«%@‹ÅŸÀÒ‰?àSÃ@„H—Àî=©?ûtÏ@@n¿«‘i?â›ã@4gŠÀ†t?)â©ÀAýfÀ©À?øÆ–ÀŸÙ*¿0Ž\?ߤN@ËWµÀÃêë>£Ü¯@¤ ƒ¿Tu†?ºÿ»@= ‹¿Ø&?á÷Ä@›_á@† ?zYŸÀÝ—DÀ!Ÿ??•MfÀ%»ÀÁ ’>ÂI–¿ÔžÀ1 )?¬¾°«¿’ ?»éæ@Þ„AÀ% ?˜ƒÀòä?Œy9?@T@Ýg!@+>ˆq@N×±?9£¿Ö§®ÀñÅ@ 3À>¸®ÀàÐÅÀ(?O@@»”±¿¢Lô¾øÝ¸À#¾Ø@3½óà¨Àb‹Að’¾ßÀ–6ÀP 9¾< €À7 A+7"¾sìHÀ”£F@cЯ¾‘t@ÕgÀá=2½Þæš@´@ÕKÁ<÷h¶À2gUÀRîE¾'˜ÀK¸Àhó¾ÀÖ½¿<\¿Àvó,¾|¿æk@ ¿Ý·ÀßUÀ—a"¿§&ŸÀ°³lÀu4¿®Á¬ÀI!Ê@±Fy¿³]á?òãÎÀ_?À¾R~@"ì³ÀÝ^K¿WWÂ@õÑ£@¹¼U¿×)·Àƒ, AM4¿¿T+Ààë@$íÞ¾UÜú¿c.ÕÀ©¯¿ŽVJ@Ø1@H8¿;?s@ÁòÉÀâ» ¿1[›@â ½@ö´H¿(þ²À} ç@o÷ ¿é¿ê#Àœý³¿©þš@‰ëA ôN¿ÓŠ‚ÀKAƒ‡¿Î& ÀUéÂÀöêi¿°»@F{Àg4¿V{È@_À}j€¿,È@¾KAÛž·¿°bÀ!‘ÐÀß´¥¿r@ŸLª?j·¿hâ]@`•ÊÀu?­¿)´²@ï_ÀDí½¿¿©ÀœúiÀéú³¿ï·ÀŠo²@¿`Á¿„2°Àñ‡_À†!ø¿vŸÀßéAžÈ¼¿Š¥4Àê3ÃÀàá°¿,O>*ºÀaì¿À S?P˜Þ?j翘•\@A€žá¿…àMÀžt¤ÀÂNß¿_TÂ@Øk¯ÀþUÀªË¼@ü,ä@VÑÀ†êŽÀ¨åë@jÒÀ¥‚Àåuû@·þ忆0ÀáŠ#Àâ Àl׺ÀÈæ¾UÑý¿h<°À?ø¿@w¯ À¯~šÀ©ÝÛ@ÔEÀõLÀ"´Àœ^ À½°í>2ø¥À.$À°§Á?z£,ÀÇPÀ5=‚@.a)ÀÓkÀE^i@jŸªÀ ä!À¡Æ¸@,C×@?á À°e5À´½¯ÀRÀŽ»¾Æ6ÀŠÌ Àq%@-QW@¢Ïý¿¸X@Ñ$rÀ²¤&ÀOL¶À$š›@€$À3³ÀÓ§§À$ù+À­Ke¾÷9¼@Ðu7Àâ€? €¿djÀï@ÐAï¿kd6Àä%Þ?’¦@¯cÀ|(¸ÀÛê¥@b5ÀBo¡À¨¨AÀø#%À÷s*ÀËÀoòOÀ!ù¿è³ÀÜ-5ÀXë¿¿%žÀbæ.À˜Fn?•›À˜*:À;Â?£”›À`ç2À\¬°?=aKÀßà2À8¾@aS¿xŸÀ^B²Àº pÀ{|=ÀdªÀOT¿IoBÀl•QÀª+¾)¯?ÀÔXÀ/UÀœ>ÀCD“¾Êê”@áú5ÀP«ø? ³ÆÀfcEÀÊí‡@ìÚ‘¿u…OÀ0*Àç°>›îiÀ§•>À "–ÀÔxCÀþÝ9¿Wäà¿i£EÀCÓ§?¾R¦>‘l7À‚—@ÀÑ™? ²LÀœêè?û_ÎÀ,ÑQÀÒ›L@ó‹@—.ZÀÖè¡À}ì?ÀÛ)YÀEÁšÀýŒ!À ½VÀ1 —ÀWÚ¾#°XÀSZ¢¿M¶@Î!WÀ‡´¾à]º@‰iFÀfw>ظ‘À rTÀ`¢ä?–3ÂÀíÀaÀ@T¨¼¿ç&XÀû(£À –ê¿à/^ÀAF´Às¨D¿­ênÀ3¦žÀ™ÿ²@¨êbÀúL¿-š¿ìZÀu>u9,¿~ãaÀ·1Ÿ¾S”ZÀ1`À³Z>)ÍuÀ«]ÀZ,s=åÅÀv%\À4Åz@'ѲÀC2nÀ$…‘@1ʲÀ‡bjÀ^Ì@kŸ³ÀyF~Àqƒ@*È}@­ uÀ{ãŠÀË“@ÁÀ‚×·¾ÒÝ›@º€ÀQÉ¿w#¿Ñ{À&·ÀÖ®£?ƒÀò˜À Ë?‰dƒÀuxˆÀŸ} ?^0qÀƤpÀÅv@¥Ž…À vÀºL•@RóƒÀðÚοæH@¬ØÀ™¾©¿Ôp?žëŠÀJ“>¢ç¨À!€À. @ ÀÀˆÀCòf@ó±¬>øÛŒÀ* À¨±v@ñ‹ÀsTKÀ.â˜À¹¦ƒÀÖ@0½´Ài¾„À ùI@Œ)ß?ãÉ’À”NÀšÒt?¡’ÀÄ Àð¡?š½”ÀoL¾ÒrC@÷”ÀÙR‰¾ìw @”@šÀàþÀò©÷?s£ÀˆPпʶ@*'Ày"Ç¿*n«?[%›ÀÇp]¿S>lÀ<Ü×@wøì@TÁÀ´‹Î@™êï@~ŠÀi¬È@>jþ@/‰mÀøRÎ@ÏAÓ“ÀH3Ç@mó ASµgÀ]ú¸@[Fó@ZAsÀlÊ»@§A(º‚À×À«@¯[A皊Àõ¬œ@yæAyaû?­@íAñ¿x+“Àèîƒ@¬1·@ê$Q@1)…@ w À²==pî@–éË¿W9&?†Ã‡@äæÒ½LPŠ?¾Ž‚@ú’Ð=³°Ù?LŽk@3W”ÀpŒí>±ßw@f{|Àutv@¿×q@Ÿy]ÀƒÒ?½£c@%>?a‘rÀ3 ˆ@¾pÀ@˜Y@gÌl@Ë?-ÀnF¿>ª#a@ìõ«>þEx½=?X@¨Ñ˜>2™À.t@clÑ@'¥¦?cña@äA*I¹?]?d@*“ŸÀŒf³¾˜ˆU@®Ú‘Àô}@Z_V@ØA“ÀàÞ¨@ÄA@¶¡[ÀX‡—@†¼_@IÂCÀÿå—@?—Y@œª*¿Tê$@bôX@.2"?¼°ÀF%:@ýÊ@§@JqU@S°Àq¶6@ØP@êä©À»îÍ?á&S@½û@ãQ@;.J@4+«Àµ_ÀqB@«ÄV½7w¥¿™iG@XlQº,ÀX¦?@ç°¼>¿ß9@AH@aZd?qij¼a·C@|ö“?é‚À­ƒ@ε@S«mÀÛ3P@»¹@Ë×ê¿.2@¥æ®À¤+ÀÄ@@Hë¾åôeÀâc0@å0žCþVÀû,6@,ÍT¿ææÀ`Ç4@\‡?òkŒ@DD0@²€Œ?]%z?½§,@l Av8I@u@$œºÀ±¸@’2@ÁF°¿%Î-ÀjÒ+@ݱ?éZX?6@“@›ægÀõ“@àK·@†b?ŸÖ)@v´´À«R9>åc@í)°ÀëPÀe&@:Ô¿Õ@eÀJì@P´?Øæ†¿ut@ѯ@ØÄ¿HC@C@x<@I%@æ @?k@\4AsÀ×@\»À ÊÄ¿ÃQ@@àì»ÀbµÈ¿òÏ@#?1ÀÄ[·@ÉÄ@ºâ>õ¬¼@ÁZ @nÆ@?vp?9â@M€â@×À°å?‹gÖ@ªç'=ÅA+@Ø+A 2«@Dì@fW‘À)&©Àg+ä?['[¾K†Ó@pIê?4 ¿QúNÀYd@¯m@K§j@ •ç?F ?@žÐ§¿üÈÿ?_~ŠÀ«ÊÀÖM÷?îlÀU Î@†@pz¨¿m Ï@ %@äÀš–À%Tö?ÏΕ¿=8¤@}@ßYã?½@dÀ¨— @&Ðø?2¦Ý=Qoç?>ã1@Ϫñ¿š•ÿ?^W0@_<8?§[ü?Èië@?C·@º>ï?Ä ‡ÀV>Î@-šß?—I×>Sû±@4Ì?µ%ý?§!†À ¯Û?ÿÄ@¿<¾ .Ò?etA+]+À‚pô?~»ºÀ~k@@6Š?  ³ÀXµ4À`Þ²?Vüb@õ¦–À'Ä?‹þ’@ð}œ@¨½ç?m©ÀÖ×£@Z®?ù3ªÀ_Û†@>o›?kL@¿ˆq@_³?2²O@Iæþ¿«WW?i¡¼ÀÖ)q@±@? ä¹Àܽ@/9‡?04¥À8÷@pL? e@‘¢³ÀK}? "‰@yŽpÀµn´?¿Â¿@aAFG?«~fÀ[Ý@²Ñz?ìÕD=g†¬À— Ž?ƒú@ú¸‰@Ÿì??“nW@) À´èy?³®@ÍQâ¿e?\7°@›g.¿wÀ™?Kï@‘dô@…_?‹Àê¤\ÀÐîP?Z±NÀÙö»Àê?g=‹?Aó•@qëý>a¹ÀM2ò@mF?ý*ÀÑÂÀGY)?ý ‹@…ÙÁÀí2®>1i@Êt?ËŒ¿ÁB¯ÀöXå@ÖM>êé¡À‚ƒÂ@ª–†>W @Ì È@õºœ½òFò?~½ÀÔhÐ>-æñ?J4—@8ÿø>¤N@ö†=@<ÕÊ>}p@À?ÄÏã@‡Å©@5?Õ¶Àí®æ@vna>¬„¿nj@5]=•µÀ£LPÀÀ—>R`‘ÀlaA' Š½Ž)À)Ö@2—(>Ík’?+JÛ@µw\=-"F?^D²@'W5=>ˆ(@ïÑê>V¿€éY@åóÀÄE>Š©@=xÆÀï]ܾFq?/ÀÌÀQw‚¾] @#àÀ ê½Á]´@œ£L@ùrN=Û6¹Àd^°¾* Œ>«<²ÀbQ•@¸aþ¾ÒµÀš±ü@œt¾=~ÀyÒÆÀ€  ¿Þ;ì?o;ƒ@Ò–þ¾´Üf@°‚º¿ý¬w¿´~¹Àžç³@…>¿ÓF¶À5òAVW¿Ôý‹À/ãDÀ&A¿aÀÿ/ÀÏÉ¿é[sÀgryÀR­-¿•¯KÀœ4£ÀØæ¿ŽÂÀ(`A‡5„¾OéÀ+A“-¿{Ï À`è@Â# >ÿ‚Å¿ê:ËÀ‰÷¾?Œ@ aÀ¼˜D¿Ä1‰@kÀ²€¿ªIž@wÿÀR$¿°•@JT@}º®¿á>¸ÀdÉý@7Þp¿žÀ×§Am%¿ GgÀL^^Ào+v¿o;SÀ;„ A<,+¿DTIÀJŽ¿€uC¿ÉrZ@JÌÀunt¿è.¥@M”¿J#£¿Šy¹À…lo@¤¦ˆ¿3Ù¸ÀeoÊ@euR¿iƒ®ÀÙ_¸ÀýÌ¢¿«qŸ¿–F®ÀÚ¦¿7&Ú¿2õá@lÕZ¿{O>¾{3å@Ì}¿CÌ¿îZ]@Ê›¿2jk@1[Àpˆ<•)É@‚T#À¿×ĿчÀè¢uÀضÀÛ*ö¿ Ð?ŸüÀÀ⮘¿’·“?Š‹Í@ÌY¥¿Oл?䑵@Øvµ¿—®@HªÀ;zÈ¿ª­„@gÎ@r4¨¿©À¨åÕ@–ûÕ¿ø~ŸÀ³z'À {ÀC=YÀÝ%À˜#é¿7ðqÀgœA1z­¿;ÏSÀ÷¤®Àž$Þ¿wÀ¿ eâ@ 5´¿¹…S¿Õ‘ŸÀ¸V À2Í¿@”RAÀ`VÏ¿§ÊÀ@µÏ@¯‡ÀZ÷˜Àc&Û@ðxõ¿—À@ˆñ@6Í¿Z‹ÀpˆµÀ¨áé¿%f„¿¨yÀüÊþ¿?"s@­8'Àœ°°¿u‹§@ ”?±t濾®ÀÑpEÀ‘À»“ÀÁ1Ù@Ôu ÀeÌö¿Íc´¿ïfÀèÜ,@¸ã@ª“ ÀÀ[MÀ,è@Œ ö¿ª/ÀgÁ@¦~ú¿ÂøÐ?ÞÂÐÀpo Àá-+@JQ¢@^ ü¿AÙ)@o2v@õ²û¿c—R@ï.gÀÅÑÀZÀ@!ó‘¿Øk!ÀØ @P:û¿w|#À™á@ „@rºÀüÌ?@ȤTÀª<"À’µ@%Û¯@ ñ.Àû”À¸ !ÀÕD1À]#&À\7Ï@o¼&ÀÌØ€¿=ì¥ÀGšÀZ’?ãHÀ«¦;Àfå@Æ>ï?©ù$À€ç;@0oÀW°@À€¶ÀMöÆ@4ä$Àj1`Àönº@qß8À»µlÀÀÔÐ@¬! À¡ùÀ‚­¢À}³3Àøœ>ÔP”@k*ÀZj@‚~y@iŠ'À¸.@Ïk0@.ÀÇ 7@¤TÀBNÀ‹b4@ð"ÄÀ˜À9ÀÊ9–@Ò¿À§”%À¹©@ܱP@G|OÀüG¸ÀLþ0@ú/"ÀÉ×®ÀªS>^À^ú}Àè›@ýXÀ ˆÀ+xo¿KlCÀETnÀ¨dŒÀÕSFÀ@¿ sP>t;IÀîòÊ?€‘ÒÀÃq1Àô&:@ïì³À¼2À´‹®@YS·?Cn:ÀxC®ÀÚ»bÀP 3À‘Õ›ÀÑZ7ÀcAÀšõ‘Àn¯iÀ¢ÍEÀà"Þ¿¢ZJÀËÁQÀ[ֿШÀgdOÀãÔ¢¾ìš¿ASÀúÅ0?ÐÀ¤¾â=ZÀ^ñR?;æ®À#3À:×ß?Ó³%@‰0CÀ½Ë@+ ¿wÙ:ÀïµÀ´ru¿¯‚*À™œ·ÀIì?Ë™QÀ÷Õ²ÀïÀLÀÍÀdÀz¶§À)¬@%4]ÀE AÀšRXÀ?AbÀòu¿À‘AÀR£eÀXð½@îO¿ÕaÀßA >­OÀ²“^À-ò> 7¥@à1VÀ±—=?,H>ð)cÀ#m#?Z¥—@wjSÀŽl‹?#3X@)ˆYÀ¾gµ?x@¾ÀBÄeÀïQ‡@ÆY²À>[Àþ\@µº‘ÀÀåCÀàO±@a@BßkÀÓh¢ÀöÒ®@†•dÀ­YÚ¿4&Àê&]ÀÒ{Ÿ¾ò*±?[.lÀJÀB?úbÆÀG~cÀMJb@E°|À/§XÀ¦·‘@Ó½ÀËmTÀÁO”@¶wÀ‹¢KÀv( @Es›>‚âcÀ¯P¸ÀfI@`ãrÀC´¶Àùi@8÷zÀQµdÀ=‚”@>É{ÀôAÀŒm¿/iÀ‡¸Àêu@A®„ÀÏÖ‹À.?ƒxÀ™ýNÀu|ˆ@ _„À OÀP!ˆ@M߆ÀºW¼¾Ïˆ5?2Ù{ÀÏà>ñ\>^oÀÒ_>ÔM@MÀÜî>†® Àá*kÀÊ2õ?é[xÀu-tÀI£T@®y>?l …À£•À$H<@íƒÀ~ ŒÀÄQ€@ºM†À¢ fÀªµW?rÞˆÀ>¹=À R˜?‘€Àªè>¶L¯ÀÝK„ÀÄ1@œúxÀMøwÀÂ_2@0¾Àá6{ÀоW@†D–À0{Àê©@ó“S@#3“ÀhFÀïÞ=˜ƒÀX`ý¾ž"@Y‚À8·¦>y¿˜ÀßfŒÀuAI@‚‚@:’À $gÀ—N@Õµ•ÀÂ!À}fk@J“ÀG8|¿Žå-@M¤“À–~ã¼0Ä@€ö˜Àá^1À]Éû?P~—À¯z4ÀÀ ”?ÁÝ—Àw¤¿§ÓZ? ˜À¾ H¿VI@(h™À¥ß¾´“rÀXÕ@‡íæ@aThÀæÉÚ@ký@D¨kÀ[aÛ@¬‹AGçÀAÓÕ@V·A‚Æ…À&ªÑ@C Að‹}ÀlDÎ@^Ü@ɉÀßÁ@[î@Ž¢ŽÀwÉ@™X AUdÀÐÄ@ŽÔÏ@fjÀ;õ›@sÔ@¡ögÀ„X©@íßÜ@¡Àh¾ª@‡PA±Þ›Àh·@ŒsA{ƒzÀÊ6‚@÷«ë@AzÀ¹f¡@ê:ú@sF? h@šË%À¡™¬?NK•@󤿽ã?ÈŽ@7Lˆ¾ q¿?™z“@wç⿉v5@‰@»ÚÀ£Ð)@åÁ‹@XÏT¿=é,@ªH‹@#+Ü¿î’À<]@Òã°@-"Ž?!+m@v”Àë}#@Ö‡@’Ú>Àw©l@Ë€@QÀĺG¾ïd@”e¾ìJ@Wð€@å—uÀ©9¾ Êj@C4ÀŸm@GŸ€@wS­¿æ¢…À?†I@×€¬@ì=‡@cf@ÝønÀ0†@–¼s@±hÀ¿Yæ@c;k@Д À=B> 5v@Ê¢+¼Ÿ•?‘KT@m*>?×[,YOÀúº.@8J?Êö¿66@*’?Ä™¿-@$ÉÓ?÷/d¿D@(>Q?ˆzo?¬6@ȆAØ @æ|B@bcºÀ^Ý@R.@úʹÀ”ݱ?~ 4@8ºÀ±l@4d:@;ÖºÀ‡xò¿â:*@tÛ¿ì«Ò¿N¸4@½×¥¿ -”¿¢I=@;‘ ¿zÞª¿ì.-@â!ä¿vMÅ@4¡@#Iª¿´I¯@0ò/@Ã~>{gÀO•$@ª¥s?&cGÀô¿ @d¿Ô?Ð Ü?Ç©@˜‹@žX4?$€"@}l@‹Ã>Â@]wÞ@ŒW=¾ÿë@ßÃã@ƒ²?wƒ-@w~ê@7»?r—3@Óüí@äg@Dà@JRºÀm`›¾ô@@Љ±ÀCF4¿iû9@ø»Àrº@‹„@êAxÀÈ©@P€!@™ó‰ÀŽÎpÀ=²@Ú|Ú¿̽@«Õ@6p†½ß3Â@m @ð¿Z[À—,@ Œ&@¥^X?éa@,Ÿú@~ ?é @ÂA‹Á@W:@c ]ÀõZÂ@Äâ?9&yÀü]À„K@l …¾_ç—ÀØ@\<¿¬ÉÅ@‚“@¨š> ѹ@¨fü?°?ÿZ`>¨%@`nü?Ž }À}Š@^[×@×*4@ú @pDzÀò—R@óø?uµÀêPÒ@Õáã?&)$ÀLÀ÷«Õ?Ü/ÀÊìÉ@Ê @¹Û¾)RÀLQæ?dð2@Aó¡ÀŸÈ?$†Ä@²¢Àê\:@–ÏÕ@s9²¿zÌß?—UË@y,6?·ª"@«‡AìÝ;>P}@@ÎAö’¿6Ý®?ÝǶÀ›ÿ¥¿ãü?2ÎpÀ Àèå?ö˜ƒÀÃù¿‰Y@wŸLÀš1„ÀNà’?-Àã—ÀäC¹?ÿMÀ)Ü›@Ηå?)@ ‘À³Õ?ñá@ì@9vâ?v+@ÁˆŠÀU”×?£œ@½5•¿".½?¡¿@@Š?ož@âÌß@v‹Àp ì?TÛ¼À£ Á@ŠóÅ?¿‹ÀL´³ÀDz?oK"¾Ð‚·À@‹˜?@„>I*ª@Âú´?%Œ@놗À¹ËË?ÕD@ñv¿ƒµ@Øß@9]¿vUÇ?æD@£ƒº?ø¤æ?6µ;@ÆüˆÀcúÏ?š8‘@ÒèÀœA½?jÿƒ@bÅ‚À©È‚?UƧÀ³í>ÀK|ž?ÀìÀ{ Î@Ïâ½?ê×Às7Ü@™µ?Ì¿tÀg{é@»³Ÿ?'S„ÀÄ5ë@Õ§?lEeÀ^é¤Ààµä?¡s?೤Àf¿»?DO@ˆs9À7¸¡?¶ø|@x9=À¸x?8m£@…Y?Åq¹?NÙ@u!Ô=íÿ¶?Àøá@J Ê=@¡?2,Õ@ƒO¿Þú¯?3Aᤧ@USØ?´džÀ¸Ý@&°§?ÛxTÀEŒIÀ;^?¬FRÀ’`–@ƒ?1ŽB@a"v@çŽr?®6]@…¡ÀŸ­?!„@S±eÀq¼?QÚ±@ž×#¾¨‡?ÎpÌ@¢¢ñ>žµ?6šÖ@Ñïo@ÿsá?S¹ÀØYÿ@°-6?¿\ÀüSö@#s`?j3À‡zê@€z?× EÀká·À]ÒŠ?u8¿Ù…¿À Ð'?ÐÍX>¶ä×@­ž?lÈg?bȬ@Ìz ?ûç,@Öp»ÀÇ?öý>@ÊͼÀCí:?§Mƒ@›Þï¿ ž¦?ï¸@F+jÀ±yv?–]¼@N@ Àdä?2tÃ@ º“ÀR(é>«^Ç@Fº…ÀÉìÂ>ʧÇ@ä@?À?ÛE?T{Ï@„,tÀ¥¿X’¹À,ÛÀâO?@‚À¯ýAÒvÃ>GÄXÀ$ùá@œ?“æW¾`S±Àî?‘¦–?4ºÐ@Ü· ?ؽ­?ú(ÀãnR?À¥@™“7¿ËP´?e Â@ÂFÀå0l?tï¾@,`O¿ê]Œ?ú~ý@ƒS‰¿À£^?(Uó@úä@Hž}?™ð”À`zü@Q‘Õ>‚ÙŒÀ~ÛCÀBæL>”.lÀhV¿§Ü?•Î@ÏAɾ¾VW?€šÑ@ulì¿×Ë?Kùè@{¡¿ÉÓ?]ý@,p‰À~ó>6Ã>À@bAƒˆ?Ù#ÀU©²ÀΑ>kTÔ¿?cÀÀuSF?›y)@_¹¿gòy=^ë^@‘¨@}ä+¾wIp@*wŽÀfƒÑ>F†³ÀNÀ®¡¢=ëm¼ÀÐdÀ¸-¢¿[½Àüø¿?š\½•·ÀÊÇÔ?‹¢Ì¿µ®Àƒ¾‹å/¾>²À”¬õ@°}U=o ˜À’4Ð@çG=90¿?û ;@åš<­r@çÌ@bQ¼wa®À~/ÃÀïa½íYê? q…>ÂM¾>cTU@,4y@sé>çf@ÁbÀ›+4¾i©@PoÀÁ¤>–Ç@ïL@i?®¸ÀÀ­„@®UØ>p¸À¦ê‚@º—®¾W›³À–ÍP@Í»b¿+ø¹À?cÇÀ‚Z.¿ Õ›=…ÄÀøŽÍ=¾îÊ>"á@†¨Ï¾”=>žêÂ@¥¿Ð@BWÑÀ¿f½¤eB@€Q À®­=ÑAÅ@àL@™ ×¾Žs¹À*dÀùJˆ¿÷K¶À {þ—}¿ž;·ÀƒyÀùÏ#¾<ÏMÀùéø@AA¿4>À‹ ÈÀtò…¿½Ùô?äÂÀ:T¿€Þ³?ä®ÕÀøÌj¿¨¡1@{ag@¾Öξ,’p@©Úo¿ S¿».¹À'á5@cŒ•¿l”´ÀÊ@Å@J0×¾£b²Àq ú@Ž„è¾4ò”ÀßBÖÀtø‡¿¬uO@cë¿ú˃¿Kk@i/@/*¿ö¶À|œ;À7ؤ¿išÀ4PÀzu¿f¦ÀmOí@ȳ¾ÄžÀöçî@õ$œ¿ã`˜À6lA¿€v¿É™VÀV5¿¿ Ù¿Åq\@ÃaI¿§M‰¿0P@$¤“@þÛ’¿ÊÇ·Àniä@%ª°¿÷¥¿¶ÉÁÀ*±¿–µ6?qïÄÀ‰àc¿„ïa?%3ÌÀ<Ìé¿o@â…«ÀÚ|§¿´SÃ@G3pÀu¼¿£4Ç@²Aº]¦¿Ü:ƒÀ'âAÀVÊ¿lKlÀ*ëÒÀ3Õ¿_0@4‚1¼U¿Ë¿(³>@~¾@??£ò¿«qD@¨`¥¿ÇçÔ¿{B@­å@=µŒ¿§lo@„‘¾о¿ ²³À¹¿.Œñ¿RµÀå€é@Ö5®¿5*ÀƱÞ@iPè¿h1Œ¿–÷ã@áEà¿Ç÷À³Ì·Àöù¿È¿Z©@ñØÂ¿²”-@¯¼@SšÚ¿Ó¿@[WÛ¿–=´¿Š{T@üRæ¿ì¿JA>@RÀÀ5vì¿Ú€W@ÓrÊÀµç¿Ðtª@lîÞ@Á¡¿°0¡ÀðÀ*åÀqTÀô¥ÀEÖ¿²hò¿bŸÆ@ðK½¿»0à?OËÀê¥É¿‰º@Õ*ÅÀ6 ÀÙ`ª@dˆÀz¼¿™6Ç@OÍ@ÀU…0¿ÊÆ@PFÀÃíÀ)}¼@ìj˜@’JÜ¿QÒ¶À³“ï@¥¤Û¿.|ŽÀQÙù@4Îã¿Ês€À7²ü@<ö¿ aÀ ËÀ™GÀŠo@ ËÀóÀ?î†@Ý;Àœ8Àít¹Àfm=@À$‡®À53>jhÊ¿ý¯À™F×@GŽ À!"Y¿4ìÖ@Ê\ÀXݰ¿œVÝ@ªç¿óß¿ÿ¢Ë@LgÛ¿QŸ§?‰®ÀöÏÀ#¼¾?.­À¿8|ÀÀ-@ç,@mÀçN@-`?>'9Àîy®À(2ß@TÛÀAÿƒÀañà@(ÛÀQjlÀ÷ãšÀñÀ 9Àkî ÀÖ¾ ÀAÞ¿]¯“À˜!ÀŸmì¿YþÌ@gJ&À4X¾C_›@ôPÀ¢æ@=¦rÀ—Š,Àù¹@RZZÀûO2À‚¸À¸óxÀÆjÀ°N²ÀÉ…ú?å×<Àßæ¯ÀÐ:¥Ày¿-À³.¿¤¯À6æÀ'W¿¤a°@:u1ÀÎÛ±?<&Æ?ë#À<I@ý“™ÀÝT+À`·º@׿ˆÀ /ÀÀlº@‡@õ <À¢ô¶À?]ÀRXÀéd™À³NÀpCÀ+—ÀÒ¿„ `sÀ¼<‰À½yÀ}žVÀ“=ˆ¿1Õ‘À ‹;Àx‹?½?âæBÀš— @uw8@óTÀRÚß?ø©»À0@ÀqÄ¡@šÔŠ@¯vTÀé§°ÀTq{@ädÀ`æ¨À.OÀ2r>À5ÀÛ)ÀÑ YÀEŒÎ¿îjœ¿-ÒSÀÁCÀÔ$á¿l¦UÀÛ=ö¿hŸƒ¿hS\ÀºŸ1¿÷‡À‰¢TÀÕ×= –Æ@£8*À^¹ª>bÆŒÀÇ]IÀ ?$MD¿´ø[ÀOØ ?V"?NÌUÀÛÙª?e“ÀeúqÀ%@ÿ?q·Ù?,ñ6ÀÎÓ%@×°@PYÀ&½Ç?q«@OÀ®É@±éL¾S:À$±À Œ¢¿;àYÀ¶x¦À}•È¿d¬WÀÜÚµÀ$€¥¿_ZÀô±À‹)¿ À²«ÀgDaÀ–“\ÀS>±À…°-ÀœdgÀÂS¤À›ß¡@'ÌlÀcÃ/Àò©=<—SYÀ ¢À«>$£‰ÀÚËt¿Ì:LÀ ÐgÀ^m ¿ZVÄ¿«\ÀÉY¿¶‹8¾1kÀ¥)–¿ËbÀŒfÀ·t¾/I4ÀŸ`À!õf>ˆ·À˜y_Àiú=‡å @¦WsÀ°;I?©œ²?¨”WÀDº?«èv@KµNÀe Ñ? *@.óoÀúY?‰‚„ÀˆZÀã¼ø?&x~À®ºmÀ-¡@T>_À“ˆJÀ/@T[ÇÀdÒjÀG 0@ÂÀoiÀý_œ@P/ÀÑUÀÄõ¶Àd@UÀ/jfÀE²ÀÒAÀVjÀVr°À·¥À›¥hÀÌè°ÀH¶e@ŒsÀ±v•À À<eÀ70¿ùŸ¾5=eÀýž¡>É,e?4ulÀ³â(?gKK@:kÀìÔz?ÙkiÀû6_À˜¶%@ÇÅÀmólÀÝQJ@¬ oÀ–šPÀo.ƒ@ÖtÛ?Fü|À’À¯@LsÀ¶&?3rc@êHyÀƒ>?x>\ˆÀh¥³ÀI?Öx‡ÀÜÁ¤À„À,?‘>‹Àfp¦À0·@aõ‹ÀÿL€Àv G@]HuÀ·“˜Àha?D9{ÀÏhƒÀ7Ýt?…è„ÀÝ,cÀŒ3@‡ùˆÀ‡™¿ðdŽ@,€ÀÒ±=tŒt@DSŽÀ£#ë¾í‰È‡ª>‡f“À­F‹Àn¼-@Œ0‡À5”„À"@ê­†À`+‡Àx[F@üȼÀýb}À°è;@dD¡À¤‚‹À¸Sf@h”šÀ…ü…À7X@H@A@–‘ÀáúeÀïÜÈ?±Ž“Àš6Àˆ‹¤?à^ŽÀÐÁHÀ˜z?Ž–À0`ê¿¿$@(ÀVo›>·.0@¥–ÀkoKÀ’ @æË•ÀNLMÀï#@ ƒœÀ©Šø¿ÇÖX@~””À7¿ŠÉ?¡™ÀæKð¾žßÕ?Ó]–ÀÁ#Àø‚?GšÀË÷¨¿OñÎ?À”¡¿Aóí?Ìñ›À"ÜX¿‚3•À•·@ø(ü@XÔqÀª@ÌèÍ@q¶“>„b@£[¿7ÒÀ¶[—@ni¹@œFœ¾žWn@›ÀeˆÀÈ;ƒ@ò¢õ@Œý‘Ài“@z]Í@Øfá¾þzU@²Ë%À0À¯@Ûý=@MŠx¿ß»¿‹¶`@U¿Ÿe¿Ì%K@)Ë>whâ?.:<@KäºÀ®'f@G±'@¶Lÿ?Œ–@á°@7m¨Às1@Bâ@¯Ë@r´ÀéB@.˜¾ùã°@ÙÌ@DWk?¨ds¼‰ @Ã"@™Tš@2Ò@âè@sš@JÑ@ù·Ô?<ÞŠÀ[_â?œÑÀ\`@ôöÃ?xÊ­À{–@¬o ?žµ­Àgñ£À¨ê¶?¼ó¾?JüwÀ³oÑ?òÉ@O…@ 2¼?]ER@Fƒ9@*•¦?¡ÑZ@·:)À†?&MÓ@4l?¿¦ZT?b=Ø@+ç@ùZ_?¨Ã&À[óªÀ̬+?Ð~æ¿]¸Æ@dU?V^Ð?‡É¿L¯w?W•Z@–µÀx^Q?” @î'¿&P®>iU@h–ÀOâ>{`•@ï)¸@}z¥>ʇ³À‚0¿´6(¾"W@ Åç@¨)¾õ䜿|À÷’¾“4È@ÁØ@éT¿6†§À³Ýä@Ì›'¿‹ÿ)¿2¬]ÀÉ@ç¾9É@èx‘À­2ë¿a·Àæ>›?sí¿Ù‰P@€·À²?¿¿~Þn@by¸?[gÀõŒ­À—½Õ@D ÀjxÀ¾+¶Ñ@ÚÑç¿mPM?Ç9@2~À¹ö¯ÀþÀ}ÀÜ ÀðùpÀ iý¿P·Àð¯À@ß™!Àç±€Àô’­@@å!Àþ£í?³º‚@ž€À®¸À=ºÀ'xLÀ:`ø?½JÀ‹.EÀgÀwUÀ4)AÀ:Tq@ÉQ°@p'\À¥~ÀžàÌ¿c\ÀAyǽBµÀcYÀÑ?•ô™À¨ÄWÀ/ §@øIhÀ‹RZÀ0d@c¤ŠÀãŠ|À€ö@¯Ðª?Å>–ÀÆÊÀP1æ?"HšÀMÚÀ>Ø@Â9Àðœ¿&â‡À²@b¾Ã@PoˆÀé´µ@cTAc“À|¤@®]ã@U]‰Àdë¼@{Ý@}£¤ÀõŸ@­ü@v™~?„¤•@¾tÖ¿œ?Y ”@ö¤E¿'ÍœÀ35°@ÀÛA°æŒ?$ÌŽ@ub;À3@V@¥¿*ŠÀvôŒ@ȵ@­×?£Ÿ‰@ÃWÀù» @ƒð†@FYÀwƉ¾0+„@Ë¿Ì8l>sN‰@ECÕ¾•¤%@Ä¡t@‡À¯§?Ñ„@ëÄqÀ¯Á?͈@ʯj¼ÃGÔ¾| q@ßשÀn?žSo@Â:ÀŒ.Z@V#|@)^_¾WiÀ^ @¯fÎ@!æ’Àj“Y@ýìî@S[£¿räb@/„­Àà¨I@Ìo@ï†Àƒ@"‡s@9¿TJƒ@'p@88¿˜%À'¡@ãÖÒ@Ȭ@]ƒ0@QyÀ @QK@¹qÀp\0@Œq@›—>Ï“À¯à…@}èÆ@ß®›Àø¨+@™¾@Ë"fÀãId@µÓ@;²qÀtqJ@×IÚ@žÔ#¾ S@máÀ´pڿײB@zô·¾ª¿ÂT@vþ£<-qû¾³L@´T?ºk@U7R@h1í>°À?ÃÝI@¿éA—,ÀÐç@\²Àôø¿æJ@ôOÀÜAÀ +=@ˆ`m¿ Õ5À¡t3@}g?N “?õF@¹?Òùa?Õ…>@`´?!ÀÏ?x-@F!÷?rg?'ñ4@vùAÚõ…À‹˜l@¹Iï@ÔŽÀlg7@C^ç@Ð>¼)@´Ôì@O%£?ÝK@&6ø@>«Æ@)Ž@ªý!ÀÁº@$Ë(@O-À*²DÀÚ25@&c¡¿1¯3À¡*@?¹Í¿{PÀ(x*@’€Ð¿×vJ@k%@qž'@n0@Èö@…3@yé?úe@–Ù AÍÅ&À»¸ @| À/Ø¡Àʨý?‡ï1><–í>S˜@h,)@Aþ¾¾a @@poD¾û2ö?3¹¯À%Ÿ?cE—?è!®À›#aÀƒƒì?¸¨ÀÍ“kÀí ¶?3ç.ÀƒŸÀÄÆ?é2O@ÏÄ4@CÈÜ?þ‘I@•‰À ö)@™©¨@Êue½#ô@©ŽÕ@x*¿›Ï@é±ë@'½Còä?Üù@™t×¾nÿ¸?Wû@œI7¿ñ£ @¹ø¶ÀðYÀ >@_«ÀxµŠ¿À@S±‰Àâ#’?°â@Ñ‘î@á`h>—à?7í@#{÷?£NÚ?KØ­ÀÙbUÀ/çÑ?Vì¬Ào2À¦±Ê?*½˜ÀÍÀ”¡ÿ?W<À4Vº¿Ëáã? j;@tÿ¿R¤?ëX@'×ÀÈÊ?±g@. }ÀŽÏ?ìˆ@+/¶¿sæë?þí@RBoÀsØÁ?áç·ÀÄ[@ÀÙ&Û?ÀmºÀ",@¸ö+?­²ÀÀ—¥À#‰Ê?°D‚?æ¡nÀâ1Ï?Ln@-ß@­l–?á=:À™ØÚ@X4º?½»£¿²Àê$¬?è¼À‰´À‹Y ?pļÀ3®@_~?vð¬À·§±@ëk©?Žy¡À BÚ@¹$©?m½ŠÀ7Ê×@oÄ}?‚¢?´7Ö@P´? ü>4¹@N˜›?Y@·4³@þde?qÔ@Š#¡@œ›)?WÓ<@p™²ÀmH›?·X@S¢Àn¥?F¸@U*4ÀÀü‘?›´@á—€À¹+?†Õ¹Àâ´EÀ'@²¾yP¼À|_W@àë¸?rL¶ÀÜ U?Æ‘?ss®ÀQâï?^{/¿Æ¦®À¼ß@6á‚? 3À:ò×@Ê—Ç?™¶ÀökÐ@Û,ƒ?+‹?·¶±ÀŒ´E?ó¨¥@á 3ÀÔ>±¼ÀŸ¶÷¿è£©>‡¾o@•š¶¿ö>û‘»À“°t¿–’‚¾ìÀºÀUöÃÀŠgJ>¹B¾ÙÀ­?Ë“? ÝT@f= @®?4ök@_(ÿ?/k´>¦k@úV½Àï+>ßGŸ@²f²¿\58?Q·@"…À£áö=.¶·ÀÃUç?â]“¿Û®À¤ß ÀË6?EÀ ÞZ@D(?lYj@Ý–<@ê›[?w{h@|$å@kt6>¿ã¬¾þ¬Å=‹T@L]?Õdž¾’è`@:a#À.Öî½ÓÎ@à—†À(u.¾Ön²ÀÑ'¤@_/®¿cDµÀ}6æ@}”Q¾ƒnO¿¦ÀÀSÈ ¿#­£@M$r@˜ÐZ¿Þqk@Ÿ,ŒÀ~«¿RÈ@Ÿ>¿Œ¯¿[¹À~ß¿p ä¿þ ºÀ¡è@/£^¿8"¿²ä@Î2š¾bÁ¦¾d·à@ów°¿3½»¾„Àº4 ½¿Ç@(/}À`¿zMÈ@·®BÀÄG¥¿•YÀ* _ÀS$ö¿;ÀÖÎÓÀú|ô¿D@9‹@vV²¿÷XV@zUÏÀWÖ™¿ñ@,x¿@w§È¿~z«À‹¥’À²¦¿8Ü'ÀœOºÀõ*ç¿„~Ô?oÓ“@ƒÀ|„7@¢%¤@k¿¿å=@J}ݾ`]Ñ¿v<@ÁÅ?46Š¿V@¾ãÀ@Ûaš¿y;@šä@nòÒ¿N‘˜À¯"Àðp¿I ­@Ÿ•?m À€C­À(?7µÍ¿ÿ¯À5P×@zë俺/¦>_ŒÙ@Ù®¿ëò?Ût6@ ú¿B\@¦‘@<¤ó¿û]@E³j@=À︷À9½:@5JÏ¿qæ±À”¼@ge'ÀÀ„?*øÅ@‘q À,µ?—l1ÀŠGÀ()@ÎÛ?a¢À…ä¬ÀÛ @#è¿ ®À˜Ø@›š ÀbC­Àð¬¿,Ž/ÀSÓê?˜%Àú¥ÀßWºÀ‚oCÀfïAÀH_¸À«8KÀ®ä)ÀpÌ“ÀL À{¬)À épÀºî¥ÀŠa Àµ,‹¿ïý/Ào¤9ÀËÜ? °6¿^œ!ÀˆÞ@øÖϾöºÀžµ@y¯@‰[(À\®Àµ†ý¿‚°5ÀÅHTÀî@ò½˜þFÀZï6Ào_Ì@ I%À±j>À~*Ô@XPÀW‰UÀö™Å@ͬ>À‡]Õ¿KÆÅ@T!@Àœ¢–¿ù~Àî™ÀöYU@K i@Ï‘6À B¸ÀÉ#e@ZXÀâ.·Àø>1@¹±YÀˆ³¸À]k@`ƒ=À—³Àûu½DqJÀñqÀ²ÒšÀ"3ÀÖyŽ¿ Þ.>6]À5÷@åv/?ÄÜIÀ?à? 1¨¾ŠâHÀ߯?œè?Àü)ÀЃ{@{Û‘?³¨UÀ >´À U§@}BÀ\¸Àe'¹¿¿ñKÀ%W‘Àˆb½7kÀE#‹ÀÛóQÀ&¬AÀÀ;i¿#[XÀE-˜¿‹V=¿—ãOÀ\ÀfÃ@d"?À^¹½­ñ À|@JÀ(âØ?O…˜?wþ2Àãµ@9¹=vvSÀû³ÀìÔÀ@U ;À ™JÀC»@ÜuOÀ”À í=æ€ÀÄ=§¿`w„ÀÄi7ÀÙæ¿hÀuãdÀ›l¾¡ „?ª—^À"ñŒ?} ¤@aïBÀš»š?™3@‹_À-£?(h0?ÔÈfÀ°à¸ÀÂ|>oÁlÀÅô#À À£ZÀt5À¿=]}ÀÖUkÀ?(t@´ý'@íìtÀΡÀ'¯¾¥pvÀ P•ÀÙ]„@®1ŒÀŽRU¿¥o€>Hp…À¬á¿N¾¨À÷]†À§}@•‹9?ŠØ‹ÀСÀ¶˜?Ïk‘À4È&À-·“ÀY Â@ªˆA¤ûnÀÛ·@žDÕ@‹WfÀùa¶@¹4ä@ØSrÀ¶—®@_û@îtÀ_\¯@ã$Ø@ožÀXJŒ@éä@lû–>v+Œ@ð¶ÀÐb@¥Ž@QrÉ¿÷ð@$%@«”"¿ æ½?’£z@é#‡À‘2ë?2ƒ@–ÖtÀÞ5+@Îfƒ@}B\Àêv¸?¥z@=:>¶Ñ—½v-i@ºdQÀ^u–=MS{@u?À;»H@”E\@+Rè>|ód@ƒ­g@ Cð=BV?Jk@'¡Å>Á?Ì¿ˆ¥L@ò‚­À~±?å*j@¢¶ÀDr±@?ê.@¿k^À`ð‹@[·`@®h‘¾ºÀî~@¾KÝ@JõtÀ+ìg@”â@Ëô1@’V\@èâ›À°Yž@&â>@±£¨>À!e@áa=@ð²ÀCM¿U¸R@úrÀw[qÀkéq@ ­»@®6"ÀH‰;@ç#?˯¿}W:@úR?“Éë?þ}>@5>Á?Ò*:?uL@;GA·ë>á9@µõ@L¨?à‘D@|n»Àÿ ¿Tq<@­f5Àîü¸¾RÎ7@ªd»?$Ð@)y.@Úç­?¨¡›?Mk@Ëf @ ¬??t @iQ%@ä|?ãž:@‹ï@©±‹@ÐÂ@ÿú±À™ÞYÀDu@"À8Ï>‡É@°mù@¬hË@ÃF@OðW¿ÿ”|ÀšŠ @{Ú?b¾Q@á @?p.4@´xÜ?·—Æ?˜]·?€ê­À±?ƒñÄ?ž—®À~I¿^(@&À©XÀ½h¤?Rm?ÀÐwz¿Úû?ónÓ@UŒ›¾ 1#@$ô@o¿§@ùÀÓH€ÀZ0 @'Æ?uo›À#Cõ??á®@Zîo¿¥gÜ?ÝŽÇ@åý4¿«Ô?ß^±ÀD @GK’?{›®À¨¹À—Ü?tÀXý†ÀŠÔ?ƒ,n@ ÿÀFŠ×?÷1S@éÝŒÀjJÔ?û!T@‡5@p*Í?;g¯À*þ¢ÀZ‘¯?Ø7@µ:Û@ô§?FŽ"ÀÅkŽ?5Ã?GÁE@ʹªÀõ•¡?;L†@ŒS=ñ³Í?-3Í@€ Œ?Ñ7¥>œŒ®ÀŸÛÊ@nH?¦lÀ,Eš>„‹?:RI@ý$ŸÀ…õ»? „¬@¦Àž“©?DœÎ@è€Ñ¾pÆ‘?¯Âß@qSÀñ˜›?¶–ºÀ@à@˜‘„? @À¿ŸÀµÀÜ„?ò@!¨À>Ž?ê(©@ÕÀ2=L?úªg@¦’©À«*S?;™·@8×b¿^X–> ¹À†Q¿¾$?"Y@vŸ?~;?7%[@Ú–å> Û—¾’ůÀ× º@0X0?'œ®ÀÒ÷T?½Z€>?^@Âoª@ê §¾:7@}ô/@Sz¾Mq¶À©G¸@óhq¿.b@ß\m¿Èƾ®î[@w(±@o…¿‹/´Àq~ý¿cu¿í{@s& ÀÔh¿X•@ÝÄAÀpõ¾jä–ÀvÚß@0྾mV¥ÀÊ*ò@VW=¿áŒ™À9R@i©H¿4˜q@$0…@¿,S¿G˜µÀÅI@p>Ë¿#pg@Óå)ÀÖtY¿¡b¼@Êè˜ÀÊ@ľß8Ç@±^ÀPüº¿3³HÀpô>‡¡¿Ž„J@¾“>ÿqö¿¸ÿ7@ÇëÀºíÌ¿÷T¼À!¹½ÀBº»¿¾L.¿=Я@~î¿ÿ@æ«™@ÁpÊ¿¥A@32c?TW¾¿ÀŸS@Áê¶ÀlÏÀ9•鼯“ÀÐí¿ÙgÄ@AC@À˜Ö”¿EyÃ@µK À‡÷ÀïH»À‡-@üÀÉ#­ÀÓ¢f?Þ#À÷ ®ÀÝçÚ@œ:å¿:×¾>=Ò@Ú ÀÛøß=[}@äFý¿ÇÛ¸ÀËP@2AÀÌÚ³À}7†Àˆ À)pÀV²@½œÀ.žÀ§nÍ@× À;}?–4ÊÀSÀ§š@Š#ÀΪ:ÀÒ¹Àב@]u%À>&µÀ: ºÀw(Àjwò?Çê¿=À vÀ ¥ÀÔD;À‹2À%:B@¡í8À1 ¶À¬VÔ?É«OÀŽ´Àm©w¿êÑFÀâS‰ÀKO¢¿çKFÀJ‹?qT¾$j(ÀJ`@ïâR¿ò³TÀÞÇÛ¿¡¡@µDÀ¼à@ÂHbÀ–VUÀ1×­¿ÆæÀ@BÀšŠ¾?¿Ú@.¥mÀÐà£>:;Á?zp`À’»?5y£Àr>@ÀE±@3@IÀ`åXÀa ¶ÀF7¢@ËŽvÀLOÖ¿b ÀuŒ`À••¿êïkÀÉê@À¦’@šx@ö‰pÀ Öb?ˆÝ?e/vÀi’·À›Ó?îìxÀ·[·Àsó@Z€Àò翚 ½ÄwxÀU\¿A8²À¾È…Àc9g@ÌœÀþùš@‘oë@s|’ÀPF¬@¯AÊ›ŒÀƒP­@Ž»Ä@2qÀãcš@Ãï@œŽ•À‹h–@ÔÜ@èÃÀþª@‹Ã@„šX(€@Â&YÀ*û >>Æf@ †Àö`E@£Œ@ h^ÀÜè5iÀê›@xŽã@ 6y@afp@°o¾8šŒ@WÅg@R>¿A< À†@¾Ùõ@Œ`ˆ?òW@-+¹Àü0@•P@°~`>ÿÃܾ}-@NwºÀ´îY¿À(1@÷µÀI´@‘h3@<¬á¾t/H@ßF3@ºß?cd£?YG@)u AŸÈ¿5@¼F¡Àÿö¿8r<@[ga¿Ó ©@×?*@~ ?ÒŸ™@V"@í-¡?fPš?³¨Y@G?A¸±¥?ä‘,@Ö5ý@Ú$r?g9@mºÀ/á@XâC@þºÀá'@bž1@˜ºÀÍÛ¿o @ö1À ÀÎÖ,@Ý/Â?âà6¿r1+@Ãdà?‰D¨@£S@@S±? ¹4@]ô*@$=@ßWx?Jœ @x>²ÀRD?ÁJ@ѯÀ’õ™@q—"@.ºžÀ3ˆ¼¿ý=@ ò”Àß°@9¿7@{EÀ\Ê@Kf÷?9ë?À†ÓÍ@dýÍ?«_ÀÓ”À¡ið?³CÓ¿¢sÆ@„rí?1‡M?Šv?Ÿó?Üæ1@î²>÷@:ö@ Àfj”?Y£Ê@ºD‰Àlˆ±?ƒàÏ@³+‚À€iö?yˆÔ@Ûm@ãkö?ÐÛ®À²ØÀ'â@‹‹?ÕµšÀ·õ?s“e?`™ÀëùÏ?™Ü?®*ÀXšë?¶O;@ì mÀdUò?ø½@¢Ö—À™Š@Zu¯@¼"}Àûò?´<Ÿ@q-¢Àjü?ÐÉ@ ­¿ø´ @ÚåÚ@j™‡¿x+@W8ä@OÿÇ¿¾ƒŠ?/i»ÀpÞ’¿,ñ?:·ÀCÀ«nÖ?óGnÀÖ»À% ™?[f@ø¿o3Ô?sdF@2¶K?r´@Ù@$Ê>”è?¾ÒÒ@ë-r¾ÖÁ?}í@‡ú9Àvð?Y†µÀ´g&ÀT˜@Ý5¸À}¶]ÀÛ̸?rúƒ@9·kÀ#w?gÏœÀãŸÌ@­`­?e‘À|ûÚ@ŽÖ²?ZÝ¿¯³Ù¿`ª²?äGó@Àn4Ì?CŒ¼À{fý¿>&(ÀÔÂM?‰‡˜@ȬÀ„m¦>/Q½@¹¾Üɪ?DÆÇ@ùLŽ¿4+”?@[P@®“¿'c?¼dÖ@+E²¿‚]!=æo»À5al?}†“¿"H¯ÀGÕç>TÇ ¿z °ÀÕžÀø‹€¾‚ÀÀÀ„¼¾¹@—R`ÀEà?=Ç@Î5oÀ{啾㉠À¿ZÀÄ‘š=sDÐ@…€ÀÊ&¾n¶Á@¶¤Ø@Öèe¿}ÀV?Íð¶@Âs徺}!@D÷¤¿¾Ü·¾Ö0a@•’Ô¿ÃRĽtBk@)ì@Ð-Ù½Dmù¿ÍÄÀ áO¾Zˆü¾±D{@Ê©£¿´‡c@&äÆ¿BZ¹¿ëîºÀVZÔ¿z›ø¿÷n»Àîè¾@A·–¿ÖܯÀQ¤À6tÿ È@½|3À PÑ¿Aô‘À°+Þ@ÅΫ¿˜*Æ=ê¢ÂÀýIù¿ÝU@¼É™À`}ª¿_KÆ@Å—Y@©žò¿¯óµÀ>ÜGÀ–ä¿lbIÀQA]À„ZÀbt,À½„tÀÊŽÀ#³ÀÁÐÀ·_?¿\@-ã>ÌÅ¿KH@ïsÏÀ¸& À-÷m@€½À,Hà¿VPª> Ê(@æ€Å¿(Yi@ø¡UÀÁµ¿{Å@WÜËÀHt'À8Ë~@N;À6†ü¿páºÀ¦(=K¶¿dȱÀ[ç @ñò¿¿1-®À……Ñ@ ‰À&{ÀÚgÐ@fk À¡–¿Dû§@9 ÀŽ“ªÀ·³@}ß"ÀéY­À&º@0öÀH ÀDfܿܛSÀú¬·À±à ÀìzQÀ<ηÀy¦É¿qžIÀk›@ÀâûÆÀ[DÀš¬ @EÍÀ‹Õ-À'N@Êè2À¬Ô*ÀLq@ž; ¿³ø4ÀB‰ä?Y–@°BÀH²¿?haRÀ§ÁJÀ»éR@oÞ³@õMÀ…ÕVÀAÔÕ¿ÝæPÀ¡\?ºä¯¿»‘9À«ÙÇ?2%â½æ;Àúå? _G@™†=ÀÁå@‘R9@a’JÀé/ @Þfˆ¿¦ÏVÀΘÀ4Ú¿=¨ZÀÂ^³¿®Úî¾9øWÀ»Æ¶Àpù¿ÜJ_ÀŒD{¿ñ& Ài2PÀbY„?|E:ÀGUÀE9ŒÀÓ⮿õn–@y}Àžø!À%U-@•ì™ÀûÀ”}ã?[³•ÀÒ7K½ÏÀ@m›ÀÝëS¿éý£ÀÐÅ“@³ñ@ï’?cד@P ÀÁŸ@™R@ËÒVÀâÌÀ꿜@×µÅ@78MÀÍy)@&˜?‹k¹> ö?]ý®ÀHÎ?s¹z?ì®Àá6Àv:b¿à½À¤<´?ØÙ¬>nüd@}Ý@D¯g>R¾as@/ÿõ@é¡™¿ ) Àù¯@Ë“¿Hg,@¨Ô¨@XLÀ·í@RÚE@QwÀfLJ@_Ïv?‡ATÀ;À?âãf@!¥iÀÙ)Š? cd@=D•ÀûšÈ¿f§„>[r@Þ,ø¿ShÎ?fP@³Õå¾$Žš@ÎR1@úBZ?ªOì?¡#@!¸µÀz¿¯@aQò?6ÛØ?6~žÀ¸e @GU½@&¤¿*Ô?oêAl8´ÀŸí‰?†w@‘p”?µïJ?pR®À™œÁÀ~M’¾‘þ³?^Ò?m+š½ k@\•Ü@DÌÞ¾rö?<@Z¢#¿)Êp@lÏÌÀš¿Á€’@U„?­&¿›]@…78À'}»¿ è»À5×@+Õ ÀðŽÀwÖŽÀâÀäÜÀ@AÓmÀZÁKÀž#?Jª™@UùMÀœ™À ²[À•KQÀæ¡À΂ç>K…ÀtØÙ½š‹Õ>îÀCR¿® }ÀÝÔ@ãºû@>¶!@îèˆ@3g·¾f÷K@v†@Óˆ¿€ŽK@êŒr@¬ÏÚ=|¼¤@ æM@Ñ”<ÀkñnÀÌ£-@ÍSÒ@sàÃ?9C^@<á¬ÀRÙP?kÄI@ˆAZÑA@³Ñ:@24·ÀÁš¥@à#H@x ¿ì!¬@èLF@숹¿*¾e¿æCO@RU€¾¯êÛ> B@>{¤?Œlë¿+Ô@È{¥À¥@Àaþ@@À…ì¾Û¹@u0!@Š OÀb¸¿£@@@:&W¿eŸi@ë 2@ƒ'¿? &À¥o @æàð?ièÀUt"@˜úø?îR ÀïD@‘ÿÀFÀÛº@>81?Áë@k74?ód®À•ȱ@e5@è3ƒÀƒqë?€¨@p„1@±ç'¿@—Õü@ÒŒ>Ù¹@/óA6:Õ¿´eô?X€ÀÀlÖ¿¨Ø@AÔeÀc&©ÀÙdÆ? Œ¿>­À‹?ÄÊÜ?EeÀÍØ¸?Ì,”@šû­ÀÿƤ?â±8@ýêÆ@D׿?•›?J±á=½OÂ? ¯À'§ÀĨ?_@½… À?õ¯?NK@ºÀ×k? ¢/?ËѨÀ2„>ù,Àå’¿½m?¶Å@ isÀLÎ>æ·KÀ(ã\À•}¥<ÜIYÀBNÆÀ€F>ý# @:L¹@¾xË>ìÄ@¼ù¿°k¾?M»Àž6Õ@´mÎ>eæ§À÷õ¨?üÚ¾%jg@M¹i@:ñˆ>ž¾·À_á³À@œo¿Ã×Ê¿2dÀ–Oã¾@´@Ýqä¿42¿>jÿ²@ð¿¿é½>Vþ½@(ùê¿cí=Þ+À@„•Á¿S#™>SYË@)_¦@QÀ¾ª7¸À–öÄÀQí¿õÉY¾·tÀ8hD¿T½À"ÁÀW¿@ÈG¿=9=0Å\¿'«Q@UèJÀïÀË¿ À^.¼ÀîÈ¿¨ã˜?øƒµ@¸êÀQ™ý?B×ÕÀß?¶¿¶àC@Üùµ@­pü¿€Ñ§ÀPC3ÀjYã¿×v±@¨rÀè+À9n¥À"›g@^rÀö F@5ÉÀˆÔ"À»`@¸¢@÷e5ÀbÚÖ?óÛ‡¿ÓJÀB KÀk¾¿¿Û¤GÀž¼aÀr½¿Æ¾*ÀW–ú?7èj?o>Àõä@W@X@ £HÀý?Þ@Àð…_ÀÑË£¿:½eÀ %aÀT*C@ꡦ? r„À¬;À§qO@!û‰ÀùÀ¿?½Ê‹ÀûfÀ%¿«j!@`JÀ…QÀ°Z@k°@Ü„¿fÑ@xîô@âo?ª!?âÉ®À€ç¶Àw†4?îYÆ?2]2ÀµsÀü¢JÀJ¦@hµî¿OÓ°À)Œ•¾£yJÀ<›ÀvJ@7¹—À„û¿ú.X@Ò”@(.Àë˜ÀùK@Ü¿@ønÀ¬ @è@ò‘¤@ìy"@[“‚?Þr‰¿¾‰@@Ã;À¸ë1@OÉ"@Ô¹À‰ Àûç@{¼Àêb¶@.¸@R±kÀþ—>Hc @Îè ALÛ³¿eþ@YRÀIó®À-Õ¿?¡º¿P*¤Àªœñ?¨à,¿‚‹ô¾]¾æ?ðÍË@âV—À‚ Æ?#@z•aÀÖwÑ?“ØO@(l?¢-Ë?Ò>@ dÀ?²½¾†%»ÀtË? Ÿü>–K®Àn$¾À’¦l> ¹?ÈØÆÀïpÃ>“ðz@Ì©r?¼ :¿˜¯`@îAÖ@ñ}¹¾¹Ä?ftæ@E¨I¿f= ÀgÓÀ×=­¿Ù>f@¿}å?£ ¿Ùíl@uµõ¿µƒ¿–¼À[¯¾Àt˜Ð¿ö%¾µ=?Ÿ±ÀË­ÀîàWÀóp)ÀF•@3(¿ VIÀP1À#Ñh@X8Àsn@»ÐÕ½Î[ÀuÀ[ ?BÃ`ÀlÅe?ÈäÈ?ïä€ÀØé´À¤¹ƒÀÌ=Ó@çéAª‹¨?¨t‘@Ôè$À´tõ½ùAy@ÍÍྒྷ:uÀÕCš@>ËÄ@Õz’@¨Šh@UbÝ¿dð.½+¡H@“q»ÀQð±@’ò;@éíÀ #©@*ÎK@³&÷¿z7ƒÀ‰g@©Ø°@žØ­?Q^<@„‘¼?”ë½@kv*@E0j¿J¶ ¾ë;@>¦ AÄ1¿µ3@"¨AÆ~M@˜Ò÷?´v<@‰â¡Àü»?^ 5@NøKÀÙV ?”Ž@),? Ï>1¯ÀC¢²ÀóÌ?40{¿ÁܳÀÅ7?4rª¿AsWÀ-Ú>@XÀPë¿À'I?û…a@u<•ÀQ9Ö½Â.ÀG8û?d ‚¿{l@¦6M¿;Y»¿ðé‚ÀÿsÀ;ç=Û pÀ<´À%1ÀÕÍgÀd®ê¾Â.ü?2azÀމ¶À¸?R’šÀÏÚ¿GD@-ª…@NA ¿Â(@‚ó‰@©ô+¾é{ˆ@ïs@žö¿:ŽgÀ8ýa@bòÄ@—hÀ¼C{@àºÉ@ü¨š@÷G_@¼.$À\Àª¶^@Nœì@´šÀ³B@.WAŽ –Àk#n@¥À@ºð?­v_@T#¢Àl–›ÀTzU@“†Í@ÃÞ¾xŠ6@ø«XÀÂÙ¾wØK@Ñ\@?» í¿okE@[[»ÀË{Ô@ì?3"‡¿Bëº>x*=@(NAàšb¿1ðó?šAQ7¿Ña@¯Ï±À®3î<3W0@Tzý@Jq+À!Ö?ÝÁPÀŒäM<@ò,?¤¬¯À0¡O>¿yS>¿Í¯ÀÏS¦¾ m½?¢à¯À›æ‚?¨¹¾~Ö®À´UÀâkE¿­Q»Àø,ÂÀ’_ì<<8t?ò¸¾@xÀ´¼ÀسÀþ…Û?2Ý«¿qe@žGÀ¦Ä¿X^Àr渿ÊÎ7ÀǺÀ¤W„À¤´GÀ÷_?ÔÓƒÀ¸·?Àßü¡?ÒNNÀKÀD“?vc@>„cÀCà?N™u@p³aÀ£B²Àro`@·´gÀ¼³²À%N@š›lÀzý²À6ö(@8nuÀ/4³ÀáÓ@¿m~À t³À S½?\nƒÀÖo³Àun@ÖgÀl,À½*@FDH@ì ˜?f£è@%(?ë À—uÀ—Àœ,À^õÎÀâ$QÀ’&@d¦@:tÀä'¿nO?Ò­ƒ@¬]hÀ F;@ã5†@5ª&À«¿økc@áR›À«’L?–I@ëªý@f$Æ@R1@,/À{¡ÀU.¨?‰lÀ /Àmý⿞XÀD @ˆ8'ÀŠ{@ 1ê=/’VÀ‹È;À‘þH¿øîNÀNN~?W@%€@@è½?%ïé¾¥D@zT‚?€/šÀƒž%@XÍÞ@˜’¯¾i|è?‰K0@è0Ú@ ¶?§}„¾9—‡@vÄË?ïb¹Àgi¡ÀÝÃ?€Ë¿ËQI¾ú „?(H@œîÿ¨qµ?ÜWN@CÝ>ÖkA?jºN@¦Xx½Š¶Ã¾¾¿T@¼ÆÀk޾¶Àn3*¿†AÀÀ¶ê>Hû-? £@uJ>­?@úyÀýüÀ÷7@~+û¾4¹>À¡ pÀ\`¿l'?À†¸?? €Àµ®/ÀÝØÿ?#]„ÀüpŠÀ2 Àõ¤:@ÅÌE?$‘>À“O4?ö_¼À*„^Àž·ì¾u×WÀL²À^XÓ¿ ¿@\{@0¥_ÀÊs ?ya1¿ý p@ƒ<¹Àµžy@»Fx@,37Àƒš@–¥M@5ð9¾ÃŠ•Às·<@!d±@¯˜>èN@5)A?h4À@3½#@‘²á¿14À:20@¨ß@RªÏ@Ç,¸?JJÔÚ@¹ß}ÀñŸö¾½û²À9°ÌÀÝ,¼¿ëzŸ@µ@@Áõ»¿°·h@üpeÀ˜6ÀÚ`ž@Ž{E@ŠoÀ¨\©ÀùŽg@·~“Àl Àô ?8ö+@®©é@žŒ[ÀM0À¦u¹À†»Àv?i?`}@Žƒ±Àô©¿°eß¿5‹?é¨Ä?–;®ÀèlEÀÏF“¾¾fÀàªÀÕhr¿ÌÃö¿þ¦À‰¦¿/QÀût„@—ýœ¿§–¸À= @0ê'@‡å @(Až@$ |?·v´À~Ï­ÀHEÀR^Ä=n„CÀئÀzš@%%ï?$ß@ÒÞb>ê‰õ?§dÔ?½£G@¿îÇ¿‚ú¾?³ª¿@TÀp $À.¤@üo”¿®]À#la¾å3À§]Ê@QEA€RƒÀ<1¹@(È@óæ ÀÙ³±@^A~ÏrÀ°–(@J=Bc.Àóé??}8@ô±¿ÝŸ@eÀ%@Àµb:9í—?tµÍ@ùqÀ]zø> o@Žê0ÀNE†?+‹@·4W@«±+À—3@SzÄÀç'Àlûž@X¸Œ@¬`Àü^‘À'ä©@üjÀè$¾@‚ÀùCÀZç¯@†Ý{@ÙÓ‡ÀaÌ<£¦ÀóÛ€À‘¦‹@ñ#~? H!ÀUœ-@Ñ@€Ü@ÕwÀÃ$@J”]@°„>Vï‚ÀþzN@Uç@*°ÀØä²?´“)?¤„tÀ¸¡„?\‹¹ÀZ5É@^Ó>âˆâ?6~5@Ò>N¶ÀÏÌý?Ã'ÀˆgÀGÚÌÀ åg<]@t@å¡À³¬@µlÿ@;¢kÀ¿ñ?'?­@þN"¿©ö´?Ä]B@FhŠÀ}$о~”?ÀÉvÓ@‘Q­¿¥—†?“$‰À×[p¿îâ<Àh-®@•ôiÀ͸—¿û©n¿¸êþ?ˆ„ÀØ’SÀT>Cý»Àz)œ?º ý¼ÔRe@lXÀb 0ÀÌ÷?òº\@”-À—‹ÀT9ÀƒË À±â¹ÀR"@Rg@Á}•À¬|ß@ûB½¡{Ë>5øh?5ÿ?Z¸®ÀwùPÀ]›¿FɺÀ\%¢À¸o‡?Wñ÷¿À&Ÿ>n=Þ@r-@("@Q9)@0~ò>—çÒ?oSã@šCÊ¿RLi?3þô@˜â@€!£=È%«»H€€@À@Ñ¿p%Z@2ò?m™jÀ3ÿ?y“?þ”’ÀãÊ¿¢ãd@œT@â¼@¬¾>¡¸½Ó†Y@K>ÀŒ±4ÀÄ#_@MSá?[‰À½õ~À£ÐÒ? ZE?ÃYa@ùE¼@_çÆ?)MÔ?×Íw>Œ\Àžv[À~TÀÝÑÛ¿ø^ºÀ;J†@õã3Àk©@D5wÀÜ×ɾ¯¹ÀÇ?ÓÀȕҾq)*@$Lã@8‡¿ÎF¿Ld À{[Àâ B@Ú±¿À¸.À=‚@}¾Y¿=‡?@¡˜Î¿igœ¿ÿ®@´8À?~ò? ÿ@v‰¯ÀÈÀB•¿É@y~¨@ì[ÀÅ!^Àc—ÀÖŽˆ@VƒÖ@=•À±×@ã¸ü@¤fÀìŒ@ž¹œ¿½€¿c6@¨—»ÀKP·À¢¤6?s3•@%ÓÆ?|ð¼?`*L@͆ß@½êƒ?#èü¾9š,À/‘À×_;À¥.¾cRRÀã*ƒÀJɽ£g@¿¹—ÀÌŠZ@ü‘Ø=×p@•îé¿TÀ„Z—À9/Ë¿láè>Õec@D Ì?‹ÐgÀ5?¸À´|@ÝÀ@`ƳÀŒN@ŠøÀe&è¿#±@<Í”À£K½)|@ÐÚ‹@ʼn7ÀÌð@~\À„ŠfÀdÑwÀäŸTÀó~?·¶eÀd8À¡Çª@Ú<Àär€?|-ƒÀK©¹?jMÞ¾n®À¹Þ@Ÿc¿­ ´>åš?_(Àq;0@±S‰¿HìT@º¾»ÀßêÀºsð?×9Ô?×2ˆ@Qìo¿1Â_@þ!ÀV4GÀ+ˆ¸¿d¡Š@1û‰Àæ2á¿$VA2K²>,h6ÀçÀÀËÛr¿pGE¿ì€ÀÚ*û¿ÑÄ@,8¾sŽ?‡´¯À”øÁ?zo< t®Àva@Aœ@V—/@ Ìþ¿+6bÀ{˜Õ¾‰™À†’â?øo©?Ë.ÆÀ¸Ä¿„)þ?l™À<Ž(Àã™>À(u€@òÐ@Õ½ @¼@^WTÀ`+m¿æè¿Ý¥À¸¼ºÀ¿¬²? -$ÀQ5@þãl@öZ«À­¼?óáŒÀÛߌ>{º$Àd³¾½Ù¼À®§§¿ôåWÀ¿IË¿0áL¿ˆ:õ¿ÅN2@Ätÿ>­”ÀÀÃŽ¿Žy‰@lZοQþ¸ÀO”Ï@g-¼>»ÌÀÜ­®ÀœÖ@ÄÚ]?C½ŸÀH^>Àî¾SŽÀ’£-?Έg@¤­ÀË’@Çù ¿¦†W@aÀAc?—ø©@Ò“ƒÀ:ó=*­¢À&AÂR„¿º<=ÀD$@d†À?&N@µæ Àž]ˆÀ"Ã-@ªPP?ª’ÀÆw ¾“§uÀ€ Þ?©¢7@ý?@ßn·?Ò;@À›@ò†¶?ž3-@ÓÌŸÀ¢-Þ?†Ÿº@ø@Ûüˆ?9=wÀ"jA"lB?ÀaCÀÄåŠ@ƹ~?´¹À}ŽÀ6md?s(À%"x¼&'¿a2²À´]h@¨ô;¾¶À0rÑÀ¾rw¾Ra@ÆCÅÀÑp¾ð"¡@|nA]"¿@ömÀÜ£°À O À ev?u¨ÏÀäK-À©¹]@ãb3ÀÑJÀŒÿ¿h@r¿UmÀjœ­ÀbM£À…7lÀ¢7›@]…ÀQ,€Àòƒe@ˆC„@øô~À–M{À&!t=âjtÀ|„õ½þ5ä?ü»€Àb?ã[=@N”¿Zço@Ø¿«Àýü ÀíM§¿k²°¾úžQÀZM뿇À¡ @&6Ø¿àj @”³ @´,žÀДÀN¥ì>°÷(Àb±XÀÚ†4Àrû†@ÿ pÀ€¥Ì@ý†Ü@äyxÀå¸@úÀ—À°Œ„¾ÊóªÀTL1Àc°$À2vŒÀLhƒÀ!xÉ@€‡â@2˜@í€w@˜Ð‡À_ÝK=…‹h@¶ÞoÀµ\@¶(@ž6¹Àò†?B&0@_è?i nÀôš @ñÚÉ@ml¿¯.@"~‹À? •ÀÎ@§„&>BI¹¿˜—?Ns·@ ¥Ñ@¡_æ?‹ž£¼Ñj,À7z(?¤Ú@à1\¾ ?ŒUO@J;–@‘ô½¶ÿR@U¬ËÀ”‰>ë{Y@F<À«º^¿@•šÀX†À ÜÛ¿Û•+À_Ū¾Å!œ¿„:H@Zæ]À³‚è¿mÓÃ@_ t@dh¿ÒQ¹ÀžGÀß½ Àæì:À:3Š?º\À?@¨ßÀöÉÀåõpÀ_Ìæ¾¦µ^Àè—P¿þúþ?Z•>Žå®À¶^²@šKÀ+_ ?v+ÀÌ&ÀãÏK@½„@ù›v@Â^Àï#3@i@7rÀ„Ï?ë0‘@–ß À¿Vï?iœŠ¾[¼®À³Òæ¿Q)¿º¶ºÀ…;wÀ%•¿˜EÀqWé?íwPÀeÐè?G*A¾½AmÀ{ÍÒ¾ ö?’®™?hªX@]ðz@~}@ð¿È„Ê¿¼X¿$-e@i¿‰&ð?LÜ/@ÕA6O½¦iÀ‹@¿7¾<`@m@¨–L@W•¢À·4mÀ”D>ÙÀÑ_}@›4½=wi@ãI´@Y4À ‡À^2}@lngÀàVšÀðŽ@›"mÀ)‚À8S\@p|@ZÐNÀH²¯@ÏWd;7·ÀúØkÀwÐÀ@¿Ü@%5i¿ütp@¸L¯ÀvÉ’@õe@ƒ–¿0CfÀä¹.@%4Á@c-À¯FŽ?%Æ@u¿@Ñ«?'™À•3D½’l¼?`+>@¢×·À…IÀ=T·@WçÀÐ,‚?)ªì@4±À×X>UÙ@ð'…À⬿Ó88Àê‘Í@,¥,ÀÝܲ¿ìŸ|@ehNÀäø¶ÀtKÀ.–fÀ~$‡@Ü>.@Ä.›ÀHÛÞ¿}ÀŸAÀ;Á¿@ñÙN@Ô¡†@zÉ¿>ÞÛ?4,@}¿%Àõ­@Ã'[ÀQU†>š+@Ä¿›À58 ¿F;£¿Y"Ó?Uý@=…€ÀŒh¢?µÀ·À¶»Àˆ'¿s ¿~ä)À‚•¿ç‰À%Æ,À¡¿²³ŒÀ’?@ßñÀš?"5‡Àôt'?UÏ8À¥hð>qËX¿?K°À˜!A&슿–5ÀXM@û…S@ PM?kÝ,À_ºJÀ(›?{Ž@ÄV@+n@Oj¿5…@¡laÀŸAÇÀþoÝ>ö$@ý°V@»vH@n@?ö„¿”@)jÀgäÀת @Y” ¿–‰Àb@n^F¿ƒÔ™Àj@òÌ?¬)ÀYZ“?z¡Þ@Úå@ÄŽ?ÎÇÚ¿}lÉÀ ö¼Y†@SpÀ1ê4ÀiÀê}IÀ¯Ž>À½È?"”«@‚ÇLÀHzÀ#e0Àî@Â@«>F³?GЮÀ¦hÀ©aAÀeè¹?E9QÀþ"XÀ Ð$?†ÅÀiÛ!¿ë¾¾4#¼¾K…À™Ç À~AFj”>Àž|ÀøãA+ ½†ŒÀhLž@‹ã<@ŽI‰ÀÁaп¨XÀÇÚÇ>Ÿ@;(¡¾VüG@êKð?Œ"\À÷dª?È\Ô@(Ùç?‡)Ó¿¼Ö@\“?'}–ÀÈß@ë~濪Ë¿5' ¿„[ÀΑŽÀ?g±@F@À…Æm?ö½¿È&@¢ì»Àk ÎÀ†=©$@iÕ³?Ùåa¿"Ì®ÀÙ`Ÿ@>akÀ²PÀ²rÀ¦çPÀ›7 @ÜwÀ<"@“§@É”¹@^ÅÀ9OÁ?`à¿ÀÎî=ãЬ@ÊßÃÀô4ø¾7…?|ób@‹[ƒ@¦Dì¿÷2ô¿Ý{Å?bGÈ@°lh@kºÏ¿¡Ÿa@N+ ÀÝtƒ¿x‹~À!øµ¿ÃZõ?¨Ü@9\6Àx| ?«E¼À”¶Æ@ˆò9Àšù À‹¨>åê8Àm¢®ÀξܿeØÜ?4¦Õ@¡yŽÀîÝ@Ø/¤@d™ÅÀ¯¾]ZQÀŠf»??uh@ŸY¾@嘽U¼@µ§°À¶J¾ö]À@1:é@Y+»¾ÉÈ¿*ÈÏ@>@&À 迯Â!Àž€AÀE¦ÀX›½@˜üPÀ;øö¾Pè6À§eÀK[¿耼…ÆsÀ­ ¸À¦g@nËc@s§ŠÀæGÏÀ~F¿²‰„@¹Þ˜ÀùˆO¿@Ç@YþÆ@œ¸æ¿!˜£ÀàÀú³?ñ-æ@yÏã@k#?·O@¿¡Ÿ¤ÀØ‚x¿Ë²Å@è*’@Æ€…ÀTM=¿Q3@¹¾˜³¯À:Ò©½¤ŽkÀܙп°5?³Ü‘@L„¿!ÀÆÕõ¿3]†@2ð@mýdÀ> qÀNÔ¤¾éy@ +W¿¼OEÀ—Í@îsÀ@¥Àµ@¿ç»Å@wßO¿ÍL@‡Xž¿q.‹ÀËJ€¿cÈ@`‰"Àտí@EH#@®Ï´¿ð†¯À·jº?ÝÚï?nP®Àã‹0ÀÀ=~¿jÀ]”>å‘@pÄ ¿Œû%ÀD9@¶&õ¿ôÚ>‡ù?òAÎo8À¨*@×-&@¿QÀTš?˜;@ ý¼àŸ†@td5¿Iɳ?î@(°Àf=ÀÕŠ?º—@±ÃÀá÷?æ@~9@b—À||1À‰EÀ˜œ@àä@Q¬¿-÷@-@] RÀ5š«?ƒÞœÀþsbÀ¶Í?Á»ÀS¿sÀÖwu?Â?À—À!<2¿ÙX)ÀRÁ @R…{ÀEr¤ÀÛÌÓ?ø:‚Àb¤À(X÷@™Îˆ>Zy ÀAÝ>ÀGÄ&>a…À›7—?–£Š@"àTÀ Í @øf2¿*ºE@ˆÀ’KlÀ¤O‘@O„ÀqÎ^À<=›@o‹ ? E@BýºÀà©mÀÑÒbÀïÙ)¿’×+À1]í?O!©Àpî&À¯k6@ˆ-¥¿ÚeAÀ2~×?¶¦À€ ¹@QLÀ¯G6À{^¿¾©N@WÓ»Àx'ë@ªN—>×hù¿õ@¾7ÀG¾GÀ”ƒÀ‡ï?¯Å›À1šÀ¨@~qô@Àå@½Ó?ö¢¿G0?L¢*À£¨@@GÊÀ/êL¿9²@¬A7À:Ô=@Þ¥*=þò·=â: ÀN(@?N@‹ã—Ào¿žiŽÀ”–@8Eš?_œ4À½ì?ÚE0Àq¶l@ìÆk@Yä|Ào ¤ÀÔ*½sÀ¤9¿ 4‘?I²ÀN‘Àí =>á{ÀòÃ@?ü À#š>?,2E@ЙÀF ¿SžÀ,¬À†Ä¿‚¿#À“ÚWÀ”=.?;w½¾qdfÀ"½bmß¿Éo]ÀÂ[§À—ï¿…¥>>9¼À0 Àª˜bÀwN¥À§ÀމÅ@kA€ŒÀé™s?GË@¸L쿱TEÀæ ‹À Ày PÀr“À%´‹¿gÛa?×Ë·ÀÜë¡j¬q²n·¾=‚XËÔ«*퉂í™úîüœý¡Æ ¥ü)ì^ ù; £`—˜}XZ ¡°Xm(|ÀÀX]cXÐzÛa|ÛÛ|:D×”K |J äJ   æÀóAóö•Ù„ë1CªöŸ{¢ ¿$8Èd#õìÔîïEIOeWI+,èÓNQ ôd 0 Q0U6nXZjj38_;CE)*r ,u tmJv<Ñ)FA2B¦ a‘yF>J<<ƒß|PNToU•T—\j›n”;gœœJcQOkkfžb]¡fk¢¢lU¦§l§pg«°·np·p¾ÄGvztÁ†Ôúìë”MÞ›œü˜ø¶1#¨>·…=,ÅÁ-ˆqIÑÔJ avœRÚzÐ8zAÞ阋CªGí#' ºÀ1 HÇ­ @–"÷d1À( 3U"aj8 r>_Y ;FvÀ Ú‘FC“ŽŽ“d|N…-rBioTO“\Ž—‰#a`\Äš;œaQ^O`¡Äghbi¨©j­®­m«j®¯²¯==¯ç«°ot±·qnpn¤>³¥¹r¹qr»¶Wsøtu q·¸EwÍwÅvÅ ßJÕÔÎÔ¶Î~ÙÏ‚‚ÍXßßÜX‚ÊááÔPѹMåS‰‚… …Œè***í‰í‚í,V3’.’ôô3ÛΕ||•4 XTøÍ‘%àŒ™è™iøèø‘L ÔL ù¤ûZ ˜™™˜j  ™ùù™î™j ú³ ›üa¸‚Ó 3œ ýýüãÌëì‹`£Í‘¦¥˜ ¦ÿ¦Ï0¡¡0¡ª%à2¬Ð+o#®€''(ä´Ã̪ý1Í1ÈÉ}É#-.#11¨º P :jµ¯…=)À=·€ài4¸à%‰Á ¼@AoÂ#ãCáâÆ½À|XX|Z …¯=Úy»J™? K´ðú,ƉÉ;GG;(Î-#STUmXLBÈÇh"CÌÍ[ÍÈ[\3É2À]_,SC_Uy-V6ÊNÊaÛMÊÛXcNh±"ó#í\í3Ò‹q‹Iq6ÔÊÊÔa”×[[×Ì×ZÌ”[;[È;È1Ž;È<vAœ2$RÙUÀ2kxk$¦k¦9k9xÐïÚÚyzMÛ{{Û:ÙËJ^lŽzy¡1âÏ̘¢ƒ?b߃ƒŸ ?Dç×—àœBÁÑL°}?Ÿ úäK J J |a}å0ær¢Ýûø D” ”ŽÞ>éé>ùéù™ŽK ­Ž:|Ž|K ­K ÿ½  í J r rææ¢îôîî¢?‡5ÀUóAóèèó•©W¨åBA.ë„IÂõûõM’Uöóö©Tùó¸æôú¥Âû¦õ’ûû’¦û§û§ D Eü©ü ©;Ñøâ1ªªC£ª£GŽ­³õ¥ú®q õCúšúq ÐñöÐ÷ç‚G£Æ£CÎÆ£Ê¡š°ÿäüôÂô¨Â¨{ç÷÷ÅÜ;øþ¥² ¹¦–H± Òüü ÿJ¦§FÜ L  ml ü¿üÒ¿8ý¥I¥ý¥ýý3 ¦Pk k þ¢Q´$ÜÜ$ÝÝ¿ÀÝÀÞÒµ1µÂ1  Z•)»º)º_Ãû 0òKÀÒ1 3  82992Ý2ÔïÝ2ï¹3ÉnOQÜÝÜA8Ê8ÈÈIÝø99:,‚ }Ð{]–»^üÓ/ ÞÀÞ ­ ­ AA8Ê Ó#Ô¼?Ïê úÆaP/ÇHÇHGd#Ý––ííì@AÞ­ ––@íî¦ðð¦TAÊÔÚîËø}{eEeInEOóJFJÚFô ,§#"6÷øù©gOIVIW\VI\¯$PúPêd1ûµÚJ ÿfL(‹,+-++NN--Sèm#C¼ÔêÕ[PP$,QVôVQdõ 0Q,¦TA Á 3ZUUZ,"U6U, S- -YO¸M5ßPÑ××[&~^€`2^€.9%*r×XnÞFÞ™NcÔ1dYYd'‡‡_H==d0ff0 0, )ÕjZ383÷ _CC;#[«DmŽdn,cÕꆙq†ëe(E**)b(*ÖG(ÖAr,ÿ >)›t1¦ IHAu41J<ý J4KLK4ue2ã<vIz—Ø%ߘ#;<;Y <êD>g|M|…5|5M…}}YN×}A,VAV2B2@ D =aj¦ 44LjF!vG™‚™±Û7:ßS Ž CŽC#“DOfDf>=IY Y I<<JƒßƒMƒJœMƒgƒœgKâ5}…N|gPìíC-B->rQD ’M6N6  HN7‘œI G+.ëôY9V“0:fO\Od“\“``“#b”ØTÖ‹YZI ZžI Z•^•Z•iTTWŽ_—‰—Ù—_\™[^_mf\š#<a`a`cša``ÄašlšÄl<›a›baab`b›”›<I›In>fccfš¡]dd]el;aaœccJ>;ldP¡L¡;deLO^YOYhj\pæž__ž\žf\]X¡_0 mj¥m`b¡Ä¡l¡dlR¢U[f¢¢klf¦õZ “Xn¤Å¨dÅd[d¨odoöneneX^ne^mk¦l¦f§b§gbl§§fpgp£½rqriq* µ ©"µsoiqi©io¨©¨Åhgmh% * Nr?øs<ŸÅÍ„zÖò¿óVb€¬€ÖD — µŠ‰ß6ËÔŒrÓ°LK˜ìRóBH Tœ-•ÅPN6.7bÃa,õ§Ü)*Ý:=W‚0–GI ž~ Ÿ½gr­#uA>Ä ²q±çº¯ s» v¡ FÂÂÃ®ÛøˆŒk†'ÓL ÔO´O©„º(Ù!öÏôÛ’9 áj0囦•äþcÌŠa_g‘ÍÍø m¬­b­7brsÅ mlkí2\‡e}-—·j¸ ­5‚¸4žw‡Á ?ƈ‰‡TÁ-`£ûë¼ ”3ç xoРb‘ß.‰¥ \ ÒÓø<4è=èµ¢ üN ô'»p™ï¹ ³‘´ $–›LnmGHH²íšºLJ»KE°žJOéM Â9øË¯¡ÎZ+ͽÙÙž677.[ÆÇh]¢<^¢¢^£L=æ_`¤¤[ç`BÍT eùùe[ òV\D5Èßn=þÔ~Õ–e â«L‹¬ö'ewW7w…Xâ­âKŒSŽm«dO %&oâ‡qàá}ˆ]~h- u»•ä.5 ç/x–8 çz虆7B@CE㨕»E5(†âá)áSìSR~ ï7Ûk7åðæ_ŸX³eiqp´c£ªöok#jj«k¦ o?ptpq§q=r=q¸»st¼uvv ½¼ ¿Bº«yÀx«sB¡ ìïưxµ”¥z{ÊzIìzé±IÎ|µèy„·°ƒÓÄÄ͆îà„ʈ»ÙØ¿{ñ.~[~¦åëÃæŸêÐÅÆb € ž§V§|“ £îì¬í¹ Ð V©Ï© —©®­„…qÒ qUÖ€l¬ì²¬6 ‡¢²Ø~‡ Ź·>º 5Àk,àÊ à® º‚Ñáâããâ½,†…Å-ˆÆÇä'¨.1AQ¼8åèΠùÕâÐ ŒëeAÌÇg 씊Ðïï—Ç *+Õ›f›,D“ÍS“D-àÖÕJ Ô~ –Ó÷4Ñ5~ÖJâ¢2 ùâ2 Óù;<è4Þè`?Q?`ûûr?¥p  –$n–¦$üñœ2†™–ÿ™†p †  ‹øCÎóþþùšq ¯¡,è µêî\ì- E\ ¸ÿ›F›nL¸33ú|Ù žÿd« ´·#³SÚTŸ_(UÌDС:¡ÐÎÑ& 44¢Œ¢<6R¥¾c¾ õ,jÏji"ª&p¾ #m~$rs"&!¨RSwT]&`hih6ÓkÜ—ùg‚s*g>?³md««OD/'oo'ââ~\Á à ª sÚ¿ ä5 ‚æ0zØézéèO % ßO æ~1±1~û±?êÒC@S)¹ ºï:7’6Nv hT™78S GžŒì–R~ ³£ +ÖT;¡P×Lòcicò¢¥nej#¬¯®n=¤t¤l±tl¹¯ o¯ ¹<¥µu¥u> ã ¦ ¦µ¥´µNµ´u ¦rµNµrt¯ WÄ q¸=År>·>D§roq¹§¹?§¹r?r¹mpr…¹@<¨¹oºo±ç±kº³ø©vG v¼»v½v»¼w»½½v ¾¶==¶ÅrÅ…ž¿º¾CÀ¼»½»x½ ½s½xsxÀ««ÀyÀ¿ys«C«ÀC¾À' twÁDÁwDwÖEtwtEºBIBìF¿žGÄi Ÿ}ÅÅŸÍ€¾$Æ ÆÆÆèÆè®­Â{®­Ç­{ÇÂÇ¡ Æ®ÃÃïí}Ãx~ÇÇ{x{Ç xò|x¼wȰ8°Èxw‚xwÍ‚|8°|°µ|4 ÁDÐzÁ”¥ÁzÁÉÉÝîÉÖÞƒèÆdƒyÇdÇyÊJ}{ {ÙÊʸ {Ù{JézzéIDZ ±Ç²~²ÇI²²~Å}ÜÍÅ€Å܀ˀ& Õ€O´ÞεÏϵ‚µx‚}ÂÀÒ´Nè¸y…yÕÎ Õ ·ÂÞ·Þ¾„ßÉî·Ê·Ê¼d ÊÙá~‡ÙÐÑPÑÐOш PÒ@¹z@ÒÒ¹¨¨º>¨†ƒÛQ¶»Å…Q„ÚÍÄw …w ØÏˆ¸ Êw ¸ ˆ…ˆŒk¸†¸Ó†  ˆ,ˆˆP¹ÑO¹½S¹OSSOMSå½4 ‰³‰’{ÜÁÆzEûÁ|ÓººÓƒ©@„ÈÓØÁÂÁØæP»èÆRÞR¾RÞ)缌‹Œ¼‹¼ØØ‹Ž‹ ßÚJéÚÚéÚ߈, ÆÈ¡êX¡… • …+ê+ŒŽŒ+ŠäâÃÖñÇ{Çñ¿òx{¿xñÖU¿UU¿ñH’} ,|,V| V.}’ô’3Ûô.“~“Ü.~Á‘þõ‘õ”Þ9 MOÞÊ÷““/žÓ/ä•Εç4  W‰–’ç–4  ÐD”Ð}…É•ßëÜî¥ ¢×¶Y–Y¶Ë–¶¶ÔË—à––à0É ± ZÛ3³ —j j —ú—âúãšÁýãüÁüãšþÁ³ ü½ õ““õõþÂþÂÿ“ÂÂÎöä/åöäå¦äöå/Ó忦ëÊæë÷öŸŸæ¨ÃŸö¦æÃ¨æçœ ç ^œX_ÆÆ_Ra€ÖrrÖÇÇ ÉÇÉr&7 : &: šb §VãüŸŸü dÿdÈÉ›”›É¢4!É¢É!²¢!›¢\‡\¢W ÷4€!ëÊÓëå Ê!€¬W÷f]êÓ æ(&!"øéÚ„y…êÙêÙï]ë‰]Ü]ìëëì¯Ì`ŠŠ+a€a++€`(g¢_¢ghiøšà˜7ôŽ ¨ ïîðï¨  ž Ð §< ; ; ùc65— D Èd¹dÿ¦ÿ¦§¦D¦¦˜ q€·÷Ÿ40œó=©œó ó© ‡= ©ÏÀ ^ÏÀªà—ªª>ª&í^‚2 ¸k2 mK„5¬­ô77ð†; ß; ß¹ÐÌЧ+@®Ñ!ƒ"m < ƒ®î8!îƒv ÑÑœ@œÑ ®#­­ „$®„[~$„e~e„öp …öqq%Ò§Ò¹÷…ÒÒ§÷D÷§qö %ž¹¯)°stÏs°t"°"t&*©¯<ø£ýþŠ9¬€€ U )lìl)°l°míkðúû±úäÎÎäÛ¶ ž:86 j:6 ¬²!e‡¼‡²†µz,ü´ÈË;ýªòò'ýÉþ}¶ÈŠ.—-϶}˜ø˜".¶øÓ.Ú~Ø~ÿ~ÿÝØ‡0¨ó€·22·Ï0á0àá® ¸4>>·¸¹3^4¸>5­¬?5„„7  ô­º¸‚¸º5› 6û±û66ñ±ˆ±ññ7ˆnˆ7     ¹P ¹Ì½— Û½¥x9žÃ³— ½µ• 9Ľzµ¾ö…8:Èüƒ „yüy„¿y¿|(;g |;;3g Ü3íÜg 3f b /~:/<~ÿ‡…†éž‡†ÿ)^^ÀkkT,kS€2È 2ÞÏÞWà²Ê‘ià9ŠßŠÔЉ‰uu’߉ä‰uä ™ © à»4® § ‰§ J ™ ‚4»B¿ ” ô„þ þ„ „ ¿ü „PC¾ááãCã½áâHɾG¾¿P¿HH¾_醯)=_ î*f *#‡ÚÅ-yÁÅ Æ%ª%ƉI+,  ˆ99ßÇßÇ—ßäÇ'ä(`'(?KŒŒKLNM‹x©Ow= ‰´,´‰n n ȴȃüƒÈQ(BB(ÀŠBŠâ‰ÆŠn èåH;É3G( Ä$sŒtƒ1Å‘ÊËÊW ?ŒÆÑ0Æ×*°æ)æ°*æ+æ)+P ¼QOOwO= õB8È!ÇZ!ZçpçF•<Ž\å8\ÉåèH¿_SUé_C^žCyVª>>€ÎÉΠ‰`ûÌÅ5ÐúËË5WËW“M{Q Œ“ Nc6HQAÌA@#Âð NÍ Í!gÇ3‰ç犔ýì u5Ñ4<•Žýý'Ò8è8ó\õ#óõÎ#óí\$2xÎÏ-ΖÏ–Îl–lm–mÅ mnÅ n$Å rÅ $—ϰ—°˜"˜°x $o 9ox‡ïTÐÛ TïUUï9ºo‹™p%4Rƪ—TÇ' `'Ï T+P ? ñ° Õ›fðoD"v“DSu“òFÖòÖ•ÖGAÖA•à=D8-óÔõ7ÙïJÕwÙ7UÖ7ÕVU7ž^JwžJï‡Ú._²&.Ö&ÿÿ&²É².‰.×/ô=´D/´­­/Dô-ƒ-ôõlÎ^U¡ 0O¡â¡ö1’:Il ò•†–÷÷””÷Ÿ÷ÓŸŸYEÿò“uøÝø”3”øøu34•ÑÑ\ 6V7ÖB8A8Bˆˆ%8%ˆ4ÿ[Šö/ø‹öø/ÒøøÓùÎúê°Ø}ïul 8 …æ’M8 @á…8 á…áhŽ;èñoº@ºJ‹C1˜Ø جþê > þY Y>P‘àããã³à‘ض‘ã° ë° 7| ë| =| Šss=| øûûÝ“”;ŽçŽèÞ=—èè•DD•Tp  p  Ñ;\ ì˜éìé™íÒ ê §q Òï¿ó rò?ò?©öW¨WXX $ XÖJH@H©@é i¨ @€éií™Ïí¡š¡í§ïî Á§§Áå¯2»›`[`ª`›ªªåo žðžZþZžño NäNo o ñ«þG+þž«þZþ+·™ÿ>™–™>ÿ†¬¬†­­†V@ Žòp ¥T—÷A%åïå%ï%p¢™Q™¢ï£ÎÊ®úŸ Å÷Þ‡ ¬­ý±¸óBBù³¤‚Këš®q ëCšC=JCJšCúq úI¯ ¡¯ ­­´´µµµ  ‚=µ´èD  D D\   ‚²‰O”±õ/ ê§î¬Ø‘¬‘¶œ‘‘³Òœ‘N N0\¯ì··ÿ·¬ÿ÷ÜÜT©Hÿž›¹–¹9¦›–n FL™ùù¸¬¶œ¶¬ù=Lº. º2II&&I¹Iú¹IJm|K»›ð*[*ç¸ †  ½Øˆ  LmMÿºJ¹º9¹º°«’ù¾ 0L!  T\! NKò N¿öéCPÁÁ¼¦ªœÃ ÜûÄÎÄ´¶¶ÎŸ°QŸQQOÄ!òYx ñÄà!gÿÆÇG³²^=þI&ȹR &È%Ê%È&¹ÉR •Ë( Ó¦FªÌD+ÌWÌ ]÷´Ä´XMÂú û ú ÃÃà   ÙÙ 'ÃY YÃ] Y¶¯Î:¡,ÐÏÎ&ÑbSz -.z ³-S´[Ò3¹ ºÅº ŕŠ•ËÕZÍPaÁ` ÆÜÅÆÅ'à Ö4Pؽ½½} ½JÙHÇ5¸5c5Ú5c¸Ú5øÇÙJžÇ¾øÇ¾M¾¸BÛ¸Û¶6z .[Ü[7[.ÒÜ[´ÏÐ},‰ ‚ Ð:{:Èàĸc;®Û/ÇÆãÊãÆËŒh¢he]¢]ß<¢<^–»z 6R67Ê%%>R ÉåÉæäÉäå>år æKK»_»¤`[mèÔ¼¼#¼U#UèaÆbabÆ' b'bêÃêb PêP×4ûcª|£ãÊã£^ã»ë–]|c¥d¾c¾ù¾id¥RÌxŸ¦Ÿ¦î" åM`[ BÕBçòDVO—âXgXõ#§öehÏhöhÏ«dŠ ]ÏjRÐÐK't'W'ÎtÎ'bÎbìÌìíR¨Ð¨RÌÌR¨K ‡T #eT ù—``©jGéM¯ûfG ÈfàfÈ5X7—¶7gÛb!áÒm!@Vm2ªcý|ª¶&Û&¶ª"ýÐKÿgnÓ%%«uoü`ð*¾ ¾ *÷pøp÷øÝpAHt " Mzñ  ÍñÍ MÔ#~Õ~[~«[CÔÕê[DÖO.B .×rk$GrMX´b‹&Û!x!ÛýWtW""!t`o$oÆ $¸$Æ i$¸o$u¨S ‘SR21T·‘w‹Ó«¬L%)¬ ÁÀ zM¸ sY=O¸OOÖÖU…Z5× GÑPZ…[d[d}|# ~&\|&^(`ˆ¸Æ ^‰(¸ˆ8÷F ÝÝ_ kjÜ4ر œ‚œ ´ ‚´ s*srÝ*׃ ;;kƒk;k± Ýb:ׄÝFXÞß&ßlÞ™ÞlX……­s…Ù­²K²­­…âûü]‘''WW=àg?`àˆE‰S žžZ‰iÕŠÕe‹³‹eá³e#B„õl&, &n,,$pp/poâ‹‹âT™‡qâ'~]ý# ?-à -?>à -C®ë.á›-im-t”h *”  t Hë]áã›I¯<2¯¨IkM 6°wÛ9ä.ä9aq.çM/– "7ßæG‚––08çxzxT —騿O 080O O  8;8 8; {˜:˜ß±ê~üû~1Y±~êJÒFCFÒÑÑb)†‘7 š/ôš7“ó0ó“ 4›ãE4ãEu 4»u1»1u ‚™Ûl9c 66MèMçèéèé9n²”œ”²³ØœK$ œ$ „£ —5ↄ5£ ³$ ‡™8~㈼䜈ä¼kåPãâ)áà)áã))S íMW/RîWv Ohv Tâ‡v 8v ‡å7œO8kk87kPQQ•^S àGà(GLViŽð_ëñôë3ñYñ339Y93]]ë9S9ëV9~ :3“VŸZŸV~ RWKWM’WK_^³e]h+T‹Ö*jpbbSD˜¢¹˜UUh˜hUqò¹¢¹ò æð]:0Ÿ0µ"g;PPLNNL×L¡e£ ??×µq©qµppµó0óµ¡Z“XôñV¡Y0 jmï jõ¦– g£h´ic£¢˜¢£cmõ% fõmm¥eµfmµ½´i´½fµppµ´´£psªoª”ö#.Á"PC¦êŒÏRìs¶÷¬mã° ù½¨>ÒúÔái™‚:õ¼O´úÃèÒ+I‹EœàˆBÑû“r5öUWë„>Yù¨®öø²¢_º Ì+ ÷Âlõ!Fà C"Ÿ0!Å[[¢RUlb¤ Z€ÍÆÖõ‘—1ât<$eˆ½ÄÉÜŠúÕ™Ø0Úe̪1 Yų3ùAìÌZf5ƒ:bÞnßv ⮪ ôXð!‘f[p"!ŸŸ!Úµ ¤ºç³}Ÿ„ ¬$¿ÐÈטà„Q)ƒÇá‡úú‡''âð'ðk×{º„ì(&ÄŽ*£â¤-|žÊ“¥”À¥À•³ —2‚¸ m ˜4W€ÐêÙÓ:ºìð5cŸs5D %ªªÔ«b7*Ž*ú… †²6 F;Ë?>¸¾Šö<ï:¼³@‰n •AvÌûÅ,"Di±Ž1ý9þÑI4GFˆGÖFƒQ-×Ü› ’æŸþ”I„’‡Þ5XVÖ4ˆÑèÞ—ÏRðfïðïu5T•öWUVùYó'Z ÷¤KL®ö&Öâªý±H²[*CÁ¼NÄ]Yò^º±_ (GW`Í  bz ;c¶]eë]¥dþÌíxí@xË%jHHéf à4ûÿnf4góy\W]&ŒS ^WÓihŒ€C ‡ 8aaÜ%9b"ƒgÿ>Æ ˆqe ëqë†áeãKG —¨ã26w•Uoq[!’N_nÙ²ìS–\fp ö”Â}ÌÏL¸ êÅ+§¨ŽƒŽ/(Õ5?¸w݇$ØvK1 › /öÈ ˜RÏ-³yv/¬%w^Wùºu¿¾%BIÁ•ÀР}'ÃâEÖz×|ØÙæƒ)Þ¤âäã -Ÿšã½å(‚´ÌÐ'§;+ tÎt+ ¹·„7 3@†»ù¾…9ˆÄâ‰ÅË5ŠçpgN ±"_&‹Œþ¦eHvÝÞ45ê5°ÜØ’‡Ú2£R’!³“ µcÚÓ%uwx6Œ`1w2€Û)9)Ûk$›yoqbh³ã žù ¿%yŸÅ’ &Õ³} ÌÂÁÀ©ºƒÎ¶×{ÄÚÄÓÍ„†ÖtÆEzû(æÙ}¸Ñ»Ñ¸Ê€‘¾ “~– ’•É¥[½[ ½~\•¦Ã§ž|Åï̘í65sc56d¦§&ší¬lÄÍŽ¯©¨Á²:ñª§t½ˆCĽÆx‹GAG‹«FCn QÈEQ¬Š¬Qì&t.©ÅÊË0Ñ‚êuÓu­Õ­êʯ®¯Ë®®Ëd…®d’¯ÊúÕÝHtHÝ”ô˜ êåS`Q``û›ªð»] ô\œ Z›Z'þ¬ù.²õîTÚª[!’®’’®aŠ”º^=^=%&R 9Ë&Ö Ñ ×½½Î!xHUÉcyŒ˜T·wôw7*a)Ü9AB/opy››4j0 ïíŒp–bb–S´ u AuN?}}¸}?Àw¬¬w ù¼½^ u' ¿À¬}„ H¾€Ë¾¿$í{}Ä^ ˾%¾È ¼¼xÈ¿È8ËÀ &€ÕÑÂÌÎ×Ö {Ç~áÙ‡z„@ƒÄ††QQ…Û¢¥ îÕÔw ˆ…'†ú¡äÌÌÀ¡ä¡ãÌäȹÆtzÒ}ÑØÑ»è»¸)R‹çŠÇ‹)çÇdŒ‹ŽûÒ>Ú‡£¤íð££ðâ¤ã--ž÷ÊÝ÷È““ž/ÏöÎçö–’ Z þ…”}ÀZ …¡Z31—â1ZÂÿ Ç{@›˜è„ÍëÌïÍïÅ]ë“ g“  ïï£6¦Ÿ 54Ÿ¨4¨§—Ë©©Ë««>^ííjé"!ø"éŽÍ±ƒ±¨±Ð¯<ΩÕýfýhfEýÕùþŠþÔŒþ9?“Á²Á““W²¬„)캅@³†…³¶ ©ž†8³;§þg {t¯ÐÙ<ÙÁ=#‡¹>3ð  »nü@…d…†@Y ùŠpöù…÷†éÿ‹ ºÑ *· Ƴ¼ÄÆzMLCˆ««ˆFR‘ 2ŠB¬YׯYÜ××› û Ñ•Ž+ + Žû‘Å¥/º ÞÔº Ò/¥uÓÒù­Õ­ùÓ¥EE  ¼P@Ê®…@®˯Ù Yý¿"‹&ÖÖ™‹øýEEÔø¥ÔEu((ùþŒŒêŒ9þ¯’„¯„Ù? ¬ ŠÕsˆ9GxG9Ô-6Ø™ÜK‚1 K› ÜdÌ@œ××Ý×ÝvæHtQ´/D0€È 1ö‹2Ú†÷ÿ²[’«Š ˜êúP×ã㎳°KÜL}0±áô±ôŽ÷RÏüG«?Q QWVXTý2¯«Gþõú®‡“Q“Z\±²[”Š \12Z£ \TýªœÒ-.-ÒÔ2S ¾dNò¿ÁéÀNÔÄ’RÙ'³“³Q “Šÿ"ŠUF_WÌ÷´X´´X&PapÛÛpO¿ú»`_aâe 'òDV!ÎtiË¥]ji¥jéG$UaHJ;µx,§ÛbÑlá!áÑÒ!Ò@m@2ômVmSÓui$iu SC %L«h”A yW™ÙY¸¸ ˜h1€Œ^/vôw€^aa—G Ý %Üj­ÙsŠhA  ŠÞF õ„,$&%šº€ Ûä°9c9l{~Jüšô77:H˜9{ˆ¼]áâ}âã~ãäˆä圼œ‘SîRRtVoiK’_p[–DS¢˜½qisir,>«·#­¬Öàî('vAtÁ.Ÿ ߬ `æ›)rABëîSG™·>Ap?¾w½ ДÁ8|”›åÍÄïìïð ºð"¿P2wôõ)k, >·È¿ Û”åMÈž“•ÃçöçÃû!ÙP!PéÑ®8+´Ðj· ù÷Ü{g ÃúŠYÆ0Ã7üÊ@uÑ š %Rí5Òc‘vØAÚËßè¬ Û€$ìë- ò]éOÀ2ÚÔ°` n\¸;®²á®ÛøFÚa%HþfnÀOúTÁA ÷3"c™l"bx—z QHàE(WTUWUŸÚ ÷¶*  o½+޾úà˜‰^Œ 8 ö÷î藍ø9• ž³8BCP«‹tA@©¨[O ©çØMˆ ²Å)õ–"››"LVÙ»PÝ~šÁÐÍÅ¢h£—ªõ= îú±ä ¹P ìÿÝåSä þ ¤öŸT˜óJ8a…sš¹op¯²Ä Ä pmºªª~|É { ÌÃ~Õ¹Sy¸)‹Ï DAXœç ž e~\ê¡ìPèÍ+ê]ïÄê£ ðïò§'ñ§qo®$£hýfhg²¼‡†¼†³þ{‡ÿéFËpPC«tŒìY0Øt‹ PàeHA,f*î> ØÙÀœeŸÓY“Ýÿؘàã:ŽåžEg! º@½êÛ$ 'ô››ôôœ2œe%AzZ¤¤L¶ãE©DT\1SÙ HéÁR!ÖÈÔß(Óè(èUVD!àÖúw‹ÚŸî ÅÌRµ;7gxl®á,côôv2d ’ yc™cyfZG×k:k±  Ü ,Zƒ" Š.ô/šºå¿ 5 6è$ ³œ[Œ–íLW’Kó pŸ :Ú!‘ ÷D_‹šôcm uª›\Qtc ð—Ü ª| çd¼/ö7ñ<‘bc-QE—R÷E&"û;¶óòTÁ+ÅÌÎVΩmc!€íš/‹ Ôv$^2 ´ÌR‡¾[„­òCFåÉH.¨©ìÝ”iÒ“‡±”ýa’ Y Ù"¿8 Ë&´1Xçßê쌤Î[­ ±ÍÐfg“ †!"…hò£‘ûº Ô¥uE (sÕ›2eÚeðL0 ¶3¸®²‰ û¶QgxÉ,xÉÑáÛ·d 4óV{ ZGbÝ„÷ªsW¯ »ð¨ û÷4fF§)+͵7¶GjkÄ*‰/:_ 6bË©ógâ'/×G[ºš¹Pž UUbql=²=ntp¤?W¶¨oº{ÂÊ{׫ Ý¢H‡ ’A,´e¼^CU9)’è¿E” œËÚdlzÜYØ»§] )§» »â©óUFø¤dfþFWea.%†'‘_ƒ  QÙjKXe¡d[d±ûú*ÿìýrkÓ$¨Xl„zÊJOO¹^¹OQè*? © Ž.1S1.°` (ˆà%˜OË´~ ’€6cbrò Â÷<¯2=l¤uºªN s ÏÆÆÏ ËOÑÌÒéPÍû>ĉ]]Xê‡ ó¿@œ›]Ü̯++¯_¢¥ ðû:²A ,já¸E þ¾áG¾Ékr$‰ 9Cžé›msØjÙŸEþdÚÌuSðEžZ‚¤x Eð Ãþؤ6L(Vò\Uk5—(åž PXK^¶rg"Âof/ÕvÃ9';Ç B_.&ÔrJ Ⴒ"Šlñ£F™WUqt"Å!ÔÈÄaUÖF _ÝNsC(/ùÔù/»ü@_š Ù³ tÅ»ŠÈ|ïí£ä±ˆ6 8†¯Ù<F9;“vòl …åE12÷·´lc!clØg4 ,ׄh¶g?¶¾`×{:×:ãèNC NRUt¿¬ ~ªI±²@©<ç‹Ç1ÛZ‹ /fðe›øš/ºvÃÚéÍpz‹E Ò¥Éc,¶.Š^±²2ÔVóò›G–RŒ[( @‹+å0h’ʈá6‘Pã$i¨ÿ ­}e'†°·¾|׊«‡Á‘ÓêŒ.øÚz• ÄkTSàú E“ò>zp%I» ¹ =mJÏ}Gkr-N+o‘<s¯ †ßnPãã9Œßr>sÙ¸<©øC¾ •àíÃq¬€‚»0­uêQ~m«® ’hi- -ipò¯Ã}©ƒÌ´Ò×¶€ÝÊÝ€ÜYj˜”4É”4(!&"†» U"»†A úÐ Do$lŽ >ò–me··÷WwRx ­z£˜h*“ ‚:ÓŒsr$¿ ¶sr0jYóYþÖR {Hotq×¶ŠuÒE “>r—;(§x³!†« qj¬vD$^_F)toVün7LXN3 ‰yAü« ÝhÊüR4, p ò-8ˆ |v• z½Û1yV\ {—LK7;—— hü7£4Vyy4‹©ÞÌ5…ÅtÝÜ~ЉX ß„zš‹…tÛxgê†J†˜J”n¥(˜†~x|âW ¢|m% h·u°Xu,“ŸV {ô3 ]­H Z*z£ÃÕ­#€i$‚û‰ Ž ¾ôD/|37XgÕ‰ ÕþZ g ’h: ¨i]·™·‚ ûK3|wò/_ñ‘]¼*£æ‘ R” Á|Æ BtVÝ÷‹(úGo— Ïw/Ó6Mؾ3€ “¿$¬z% õ‡« °ÉÙìTîbƒËÈË ç^ß½/ åæ3KíìŒØ¤Ë¡Às éÉö{¨õÂ{ÂÑØ„àÜ}.‘æ` L*‘æ+³¯M˜6h–ö ‰9F´ Ših ¾íe£H \3æÉt¦ ¡Ë #+iŽáw¿òP ÐAy*æ]6+‹³³´&`©w‹wÓRŒ¯ìÉ"玩Žç,_†ìÙël €£ÍäÆ|È„ìß^ßìës¿¥uïf¦ a• öª1³9 Þ£æJó˜€'’q%QÖgë° | Ÿ¿üæ£äuÄ{¸ L{éÚÓ%W ߢäu'’'u¯H E°Ÿwú¿£ñÍÆ Ç ²Kœ”[ ³Þ´wÀx›ä ž L—æ•Áº 2Þ€Ûl,uftÎ<„Ö5åG »wxÃB›"ÉN•( •N (àS lÛzšé ”jµ¶Íޖݶ1ÍA@­ –0Y»™0W âšT÷ýé$?é?¤& FZY^¥ÉÁ÷óB‰ OÒ‘´Á¨˜vyzì{Ç{ìY˜×¶§ªÉ-}?„3“Í÷¡ýž› Z•5Ku¤ŸX¤ZŸZ¡VEà-± Mœ,"S (¦šÕ„b¨¯6é±¢r˨6•¿sÁa¨Ê Ë]öB F _F ÄÏ?6¥¦8 MV ­] ùžº‰ˆ§ à—=¡÷Ïu«ÓÓouí¾u‘n߈ pËà »Ä?´¨ ÐylYXñ¡XY½òk ¨a®jéH¼ùu'‡Ã¤-6s¥9'w¶ 8@€ 3ü& ²‚Z—–Ëj¶µ¨•EÖÿgªn”§jq¶j§—œA/ò0—AèULiÎÏÄî?¯$Ç Ã ¨1ƒW·€ÀÌ Wf·¼¼ªk ½|}\Œ+4S- .ë.- ™ÖQ®lY E DBûâZ‚·foG›@xÊË÷È÷nª‹Š`¾‘¯Pú=YIɰݱdö¹d§/ØÝlõ²O[‘oy±™[±ö  lO.ŽŠð¯K ûzÒ«‡U $´?Ï]ßn&]“*ÙnY\&|- |¯¨±Šôð ”þº+)P¼×3:ýEŸüj”¥ ÚÀ æÊ¹žÈ`¸(÷* Á:š8%LÏ ô ƒÞê> ùSb°nQp§o¯}KàÖ×ÒN}q·ñޱƒºP +æl •¯¶ BÕÍi¸`â\}lß À äã¤Òiˆem›÷nåäž ¼{פùî‘´ž%Ó¶ ¡“]‚f4%¹ÒªU¼¾‡°ª¼ÒÀ¿w<Ýšz8¯ ÆÕ<wy­è</Ýñ·‚À,={¼Q m=s°š« šbÎxŠçŒFUª£- ñº ç‰FÝvt¿Ÿö]'l{Í‘bx0õ³¼9 g½µW?tœ¶r¦oL K·«Ú«Ý$¿üJóL { LK< m 0óœÀ{:væ•k:ƒ a@V ŸN ¿¢ Í£»ã^³õ!gµmöϬ­m>·D‹*b·ADøÛt³>0¨XFÁBå1 XÃXýJè™øðúµÇ:ÈZÇ:ÇÈÌZÇÈÇZ#ÉíNÊM•ŽÔËrÈŽ<ÌÞ˜6› 1 Íá<ÑÁqÏ™íæîôŸÐô?úúÑh ø³­öÐŸÒ µ Â3 Âô3 ¥õINPCµÂ1NÓc<ÔßÔ<'K‡GÖ+<2}×Y‚ÛæŽ‰ŠbØ]]سٗjÄ\` Û±n^e©Å"ÜÆÝ¾ pšÞy¬2íàWÊá:<Læ`ïÛ ñ‚òäßÄjØ*ñåï§›LFŒ¢<Œ<ßÝï¾ gæn" zygØ—2eçk«®è­ÚéJ¼ Øw ؾêê+¾ëÓ¡ ìô… ¤‚4§ªñò‚§òõî!+𴥿BÕï<KLÆ,zûÌÂðoññ> Ž#{ #ŽÍNä–òÓjïÙ7ïÕé > 9’Ëá²» çDóNgñá@ô±Ži\ ;¥Ïì™ÍäSõ±. ±õ²›H ZBxöé÷]·Çø5ù3¶¶ù/âÃêBxÛúû¯næ=ÓüoL`ü¬)s Ls ý"Wr T>w‘Rz yÜݳáý@3@ý‹ƒX ƒ ’ €y’d 5w¿ Y×±æÛ79騔œã³°ô@Ÿç°³È%ïj:Ó¶cµ W4 Ì~ dÆ (ìFe˜;Jª Ú‘ž ( Ä ~õî' u¾í˜jùÔþ ¾ù ¦þ~J âý³'ÅaÃ1h`ÿ) B z­5 ÞåŸöægIëH ;ÈÐËÿýòÓòý¤ø¾Àú(£ „¤ î= 8cþšêäˆßØÀA³ù9ËŒ±×? ý:” ýyÞŒhCò  Þš€ ÉÜíF¡ ¿cšŸ_HQ Ù ‰ÙÐVôÌÏ ÏØ O≃ X †n»u 3ñVÐ$ €#ð+B) AÈ ^ ¤H ¯\ ËИ(;Þ5êu{íH ›‹ý •âÕšÞ@+ ¬¦ÕêœMû¢Ëƒù YÞ+ŒîÄ   Ä¿ ü …èmLKÁ qü   æµ Ð KQ H-VÊ2 £þ Ø12vì¡ Çv8¶ 37 ^"2 ¢£ù2 ÎÍMä&ª€3ëlk±¥ ¦  ã' ÀyÖÉ } K ÎÖã ‘ è, +? “ Њ ìØ$Ä 'ñ° ñ7€ éW 9ßñ é=Cë óD Ö~ñü«! \ T! ö! öMåäçf¤yr " # |ýà# # à}q5 .5„Küó& ¡ ã6˜Œ³ ¥%' yñ@ { 0 :ïN(  È^ ' ¾ Š‹ “ ¶g‰ C _‡—ܯM 6Î+ VÜݱhá"‘+ V_ H’* ¶hR, ’ˆ8Ò˜1v4I, )9W ( •F& óF •æÿx) & ¤- £\- SXà =HhYI šy/> ñéõ. / º. ±ÚS‘ž( FT‡VŽô/ ½* zî L ™Œä 0 NHL ŒµÍÌ2]kÎ2 Êä ü3 ýÕç*N0 _% ½ * 4 –‰j6 ¬7 &^æMl ”9 r7 < "ƒ8= wÌÃë Ð> îñg@ ᎠçBfÓ6‰ZA ”T6B q.M Û°m @˜ÚƒC C SÚsD E Õ(ž©x3>?ýYÓŠA F ÞB G ÞG åÞ"< †¯IM > { *@ h áE EÕ? *ñN ó¿#kl Ã.X sŠX .) ’iáˆZH £{V õ‡Ý°V Mõ†< ; ǵÌ61 Í ëÐ>T#lf¤°ä¿ w°¿ ñ@ VM °6hI +ÿK ä»'ºM kÛóN O ß%[ ef{Q Q ëŒWG¢ %R >S ‰ŒT ÿ#«U ©R å>[ fBÏøÏøÞÔÞø÷XÂxÿT H{˜8 V @L ÓQ ¼ë«U ÚÿB#a / . yèd®.s)W šk]Ór: 7 :0 HZ |g Y _[ ©ùÈ.ÓKNŒ ©[ `s´$´sM a*] ×ô×] u^ ÄþÉ…<:h²à7<h] §»–â ’yÔ6\ ®’€Ä_ j_ :jî_ Äa . yƒÂy­ÚÏ®€ëÚÏ` EnÄv|L ™‚,` EeEmt-Ä|òÓÔ†Øb b Ø/Éc Æžo «Td ·ÕiŠî/We qøh e –ëb #b e 'U ‡ÚTr d A) Isª ®@ h ) x/r yd rÉ: ÌP a / f /_ h Ñ6f _ *0Kh 6á„ i Hj ›³ 0Lü³’9 l M8 i „ GHi ói Äò@m ®v¶ Ûäo å} † òp ò† x ñk P¬s LAt mi t ­u m4u 1tE»u v 8O]ðXm4w ϸ m ƒ®Qn ŠIîëj ˜›x RRx /0ü½} ò )š E­t Hs )Õs Õ7ñI) /îI/r å"  š¦#b f y ˆ Fy F  ¿O { > | 7Š} ½y ˆ y ½ O-z S~ 9S#=¨Š7Ãþ ý ðRðš R‹ f“ Âðð°ý¡“€  ° ýÕ‰³«š Ž{  { #*a Œ ,‚‰ Ka ói ò©U «©«½ ¼w Å w¼R$v:‚ ƒ ‰ Î… ú5™ ‹† y  vvó‡ HçZ׈ ÿF† } y ‰ g‚ ‚ giŠ dŠ iËÔ‹ *… · œ T’Š Ë5‹ÒÍ<ñbDQ‡ ’‡ óA´üvG’ å/ ˆ Mÿ¤… ÎjbQê¤ †)   °’Íñ6Œ N¯Ä =󨃃 C Œ a KŒ ÉÎÂF•v  v7Ž ð =Á Gv‹  Ï©Ï D µ À‘ Bç!çóœ B‘ ¬Ÿ’ „ œ ²Z¤Î¤‘ À2ðŽ ï” Rœž• Û µ, D £zõ¬” E” ¬‘ ™ 5J¢²ï B ¤¤ïÍ1 áÞ€ @ƒÚsX ƒsÛ• ½’ G„ v’ ÅÄ mɘ ¥B– ¦k®ÇÂŽ ô¤D˜ B¦˜ D+™ ;û õ– £– ž£ž– k¥½ %š š™ +‹š _šœ ¤²; \棞ðš ß‘èí ê½íêÜ™5¥ ü — 5„$ KN üÔ\  € º œ \TUi•QP•ƒ _C J5™íÜ5ï²î1 ‚áR_¥ ž LU‡R¥ Ÿ ƒßå}    Üíå  ½¿¡ BW¢   }ÜØÜ} J»¢ ¿?¤ ê¤ ?£   +B Þ5 ¢ Güc ÉqB 5 ðc ¤ „†ïŽ ¤þ² è‘*PU•Ö.qaÖq üý4¦ 1Õ*ðÕðZìíï± ‚:⨠úîú¨ û¨ â© ˆ © ™ ¸á®  ª ·ª ‘·? ¬ è¬ ®Ÿ ‡« T=Y ®¬  § © ôל=Oc þk òþò¥² ¥;­ ¯ to ® § ? ° ­ § ˆ© ± MIYnvÛ¥ äã v¥² ;² ‚*: ãIIõ*×ûf¼ ¼ #œ´ ‚´ Ms-ÔõÑ8vó-õ M´ µ ½ ³ Á¸® ൠ¤n__¤µ nIõq Fyl¹ ¤¶ w© · ôðT”ñ*ð”B!õk¹ I· ÑÆÑ· » I:²¤» ¹ » ¤ˆ6-•w5Iv!!kIá» :½ µ * · … ô!Fl¼ fe¼ ¼ e#z½ % ½ z À vJcê<G K5Á E À JÀ ÚF5¿ å¢îT0 ÎÄ ¸p0΀¢T« Ï–Å cCÕEÁ )O ¡Á F)Á à FCcNÈ ö0ê><Eˆ¸qpÏÅ s·=¸ïîðßG[?Ç Æ Ç Ç éš: È º /Ç ?à È' %é: É€ ]€]3œ ¤º È 2•5u¾ ïð‡¥ ¢‡¢Ý0ö¡Lž L ímatgeom-1.2.4/inst/meshes3d/PaxHeaders/meshComplement.m0000644000000000000000000000013214576357161020072 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshComplement.m0000644000175000017500000000503514576357161021655 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = meshComplement(varargin) %MESHCOMPLEMENT Reverse the normal of each face in the mesh. % % [V2, F2] = meshComplement(V, F) % % Example % [v, f] = createOctahedron; % meshVolume(v, f) % ans = % 1.3333 % [v2, f2] = meshComplement(v, f); % meshVolume(v2, f2) % ans = % -1.3333 % % See also % meshes3d, meshVolume % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-01-22, using Matlab 9.7.0.1247435 (R2019b) Update 2 % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % extract mesh data mesh = parseMeshData(varargin{:}); faces = mesh.faces; % iterate over faces to invert order of vertex indices if isnumeric(faces) for i = 1:size(faces, 1) faces(i,:) = faces(i, end:-1:1); end else for i = 1:size(faces, 1) faces{i} = faces{i}(end:-1:1); end end % create new mesh data varargout = formatMeshOutput(nargout, mesh.vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/boxToMesh.m0000644000000000000000000000013214576357161017022 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/boxToMesh.m0000644000175000017500000000664214576357161020612 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = boxToMesh(varargin) %BOXTOMESH Convert a box into a quad mesh with the same size. % % [V E F] = boxToMesh(BOX) % Create a box as a polyhedra representation. The box is defined by its % coordinate extents: BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX] % The result has the form [V E F], where V is a 8-by-3 array with vertex % coordinates, E is a 12-by-2 array containing indices of neighbour % vertices, and F is a 6-by-4 array containing vertices array of each % face. % % [V F] = boxToMesh(BOX) % Returns only the vertices and the face vertex indices. % % MESH = boxToMesh(BOX) % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % ... = boxToMesh() % Creates a unit cube % % Example % [v, f] = boxToMesh([-2 -1 0 pi 2 3]) % drawMesh(v, f); % % See also % meshes3d, drawMesh, triangulateFaces % ------ % Authors: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2016-09-22 % Copyright 2016-2023 p = inputParser; boxDefault = [0 1 0 1 0 1]; boxDatatype = {'numeric'}; boxAttribs = {'nonempty','vector','numel',6,'real','finite'}; addOptional(p,'box',boxDefault,@(x)validateattributes(x,boxDatatype,boxAttribs)) parse(p,varargin{:}) xmin = p.Results.box(1); xmax = p.Results.box(2); ymin = p.Results.box(3); ymax = p.Results.box(4); zmin = p.Results.box(5); zmax = p.Results.box(6); vertices = [... xmin, ymin, zmin; ... xmax, ymin, zmin; ... xmin, ymax, zmin; ... xmax, ymax, zmin; ... xmin, ymin, zmax; ... xmax, ymin, zmax; ... xmin, ymax, zmax; ... xmax, ymax, zmax; ... ]; edges = [1 2;1 3;1 5;2 4;2 6;3 4;3 7;4 8;5 6;5 7;6 8;7 8]; % faces are oriented such that normals point outwards faces = [2 4 3 1;7 8 6 5;6 8 4 2;3 7 5 1;5 6 2 1;4 8 7 3]; % format output varargout = formatMeshOutput(nargout, vertices, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/ensureManifoldMesh.m0000644000000000000000000000013214576357161020702 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/ensureManifoldMesh.m0000644000175000017500000000560614576357161022471 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = ensureManifoldMesh(varargin) %ENSUREMANIFOLDMESH Apply several simplification to obtain a manifold mesh. % % Try to transform an input mesh into a manifold mesh. % % Not all cases of "non-manifoldity" are checked, so please use with % care. % % [V2, F2] = ensureManifoldMesh(V, F); % [V2, F2] = ensureManifoldMesh(MESH); % MESH2 = ensureManifoldMesh(...); % % Example % ensureManifoldMesh % % See also % meshes3d, isManifoldMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-02-01, using Matlab 9.5.0.944444 (R2018b) % Copyright 2019-2023 INRA - Cepia Software Platform %% Parse input arguments [vertices, faces] = parseMeshData(varargin{:}); verbose = true; %% Pre-processing % remove duplicate faces if any if verbose disp('remove duplicate faces'); end faces = removeDuplicateFaces(faces); %% Iterative processing of multiple edges % Reduces all edges connected to more than two faces, by collapsing second % vertex onto the first one. % iter = 0; % while ~isManifoldMesh(vertices, faces) && iter < 10 % iter = iter + 1; if verbose disp('collapse edges with many faces'); end [vertices, faces] = collapseEdgesWithManyFaces(vertices, faces); % end %% Format output varargout = formatMeshOutput(nargout, vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/triangulateFaces.m0000644000000000000000000000013214576357161020373 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/triangulateFaces.m0000644000175000017500000001110414576357161022150 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [tri, inds] = triangulateFaces(faces) %TRIANGULATEFACES Convert face array to an array of triangular faces. % % TRI = triangulateFaces(FACES) % Returns a 3-columns array of indices, based on the data stored in the % argument FACES: % - if FACES is a N-by-3 array, returns the same array % - if FACES is a N-by-4 array, returns an array with 2*N rows and 3 % columns, splitting each square into 2 triangles (uses first and % third vertex of each square as diagonal). % - if FACES is a cell array, split each face into a set of triangles, % and returns the union of all triangles. Faces are assumed to be % convex. % % [TRI, INDS] = triangulateFaces(FACES) % Also returns original face index of each new triangular face. INDS has % the same number of rows as TRI, and has values between 1 and the % number of rows of the original FACES array. % % % Example % % create a basic shape % [n, e, f] = createCubeOctahedron; % % draw with plain faces % figure; hold on; axis equal; view(3); % drawMesh(n, f); % % draw as a triangulation % tri = triangulateFaces(f); % figure; hold on; axis equal; view(3); % drawMesh(n, tri, 'facecolor', 'r'); % % See also % meshes3d, triangulateMesh, drawMesh, mergeCoplanarFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-09-08, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas %% Tri mesh case: return original set of faces if isnumeric(faces) && size(faces, 2) == 3 tri = faces; if nargout > 1 inds = (1:size(faces, 1))'; end return; end %% Square faces: split each square into 2 triangles if isnumeric(faces) && size(faces, 2) == 4 nf = size(faces, 1); tri = zeros(nf * 2, 3); tri(1:2:end, :) = faces(:, [1 2 3]); tri(2:2:end, :) = faces(:, [1 3 4]); if nargout > 1 inds = kron(1:size(faces, 1), ones(1,2))'; end return; end %% Pentagonal faces (for dodecahedron...): split into 3 triangles if isnumeric(faces) && size(faces, 2) == 5 nf = size(faces, 1); tri = zeros(nf * 3, 3); tri(1:3:end, :) = faces(:, [1 2 3]); tri(2:3:end, :) = faces(:, [1 3 4]); tri(3:3:end, :) = faces(:, [1 4 5]); if nargout > 1 inds = kron(1:size(faces, 1), ones(1,2))'; end return; end %% Faces as cell array % number of faces nf = length(faces); % compute total number of triangles ni = zeros(nf, 1); for i = 1:nf % as many triangles as the number of vertices minus 1 ni(i) = length(faces{i}) - 2; end nt = sum(ni); % allocate memory for triangle array tri = zeros(nt, 3); inds = zeros(nt, 1); % convert faces to triangles t = 1; for i = 1:nf face = faces{i}; nv = length(face); v0 = face(1); for j = 3:nv tri(t, :) = [v0 face(j-1) face(j)]; inds(t) = i; t = t + 1; end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createMengerSponge.m0000644000000000000000000000013214576357161020667 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createMengerSponge.m0000644000175000017500000001146514576357161022456 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createMengerSponge() %CREATEMENGERSPONGE Create a cube with an inside cross removed. % % [n, e, f] = createMengerSponge; % Main use is to test possibility of drawing polyhedra with complex faces % (polygonal faces with holes) % % Example % [n, e, f] = createMengerSponge; % drawMesh(n, f); % % See also % meshes3d, drawMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-18 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas nodes =[... ... % main cube corners (1->8) 0 0 0; ... 3 0 0; ... 0 3 0; ... 3 3 0; ... 0 0 3; ... 3 0 3; ... 0 3 3; ... 3 3 3; ... ... % outer cube inner face corners 1 1 0; ... % face z=0 (9->12) 2 1 0; ... 1 2 0; ... 2 2 0; ... 1 1 3; ... % face z=3 (13->16) 2 1 3; ... 1 2 3; ... 2 2 3; ... 1 0 1; ... % face y=0 (17->20) 2 0 1; ... 1 0 2; ... 2 0 2; ... 1 3 1; ... % face y=3 (21->24) 2 3 1; ... 1 3 2; ... 2 3 2; ... 0 1 1; ... % face x=0 (25->28) 0 2 1; ... 0 1 2; ... 0 2 2; ... 3 1 1; ... % face x=3 (29->32) 3 2 1; ... 3 1 2; ... 3 2 2; ... ... % inner cube corners (33->40) 1 1 1; ... 2 1 1; ... 1 2 1; ... 2 2 1; ... 1 1 2; ... 2 1 2; ... 1 2 2; ... 2 2 2; ... ]; edges = [... 1 2;1 3;2 4;3 4;5 6;5 7;6 8;7 8;1 5;2 6;3 7;4 8;... % outer cube 9 10;9 11;10 12;11 12;13 14;13 15;14 16;15 16; ... 17 18;17 19;18 20;19 20; 21 22;21 23;22 24;23 24; ... 25 26;25 27;26 28;27 28; 29 30;29 31;30 32;31 32; ... 33 34;33 35;34 36;35 36; 37 38;37 39;38 40;39 40; ... % inner cube 33 37;34 38;35 39;36 40; ... 9 33;10 34;11 35;12 36; ... % parallel to xy 13 37;14 38;15 39;16 40; ... 17 33;18 34;19 37;20 38; ... % parallel to yz 21 35;22 36;23 39;24 40; ... 25 33;26 35;27 37;28 39; ... % parallel to xz 29 34;30 36;31 38;32 40; ... ]; % Alternative definition for faces: % [1 2 4 3 NaN 9 11 12 10], ... % [5 6 8 7 NaN 13 15 16 14], ... % [1 5 7 3 NaN 25 26 28 27], .... % [2 6 8 4 NaN 29 30 32 31], ... % [1 2 6 5 NaN 17 18 20 19], ... % [3 4 8 7 NaN 21 22 24 23], ... faces = {... ... % 6 square faces with a square hole [1 2 4 3 1 9 11 12 10 9], ... [5 6 8 7 5 13 15 16 14 13], ... [1 5 7 3 1 25 26 28 27 25], .... [2 6 8 4 2 29 30 32 31 29], ... [1 2 6 5 1 17 18 20 19 17], ... [3 4 8 7 3 21 22 24 23 21], ... ... % faces orthogonal to XY plane, parallel to Oz axis [ 9 10 34 33], [ 9 11 35 33], [10 12 36 34], [11 12 36 35], ... [13 14 38 37], [13 15 39 37], [14 16 40 38], [15 16 40 39], ... ... % faces orthogonal to YZ plane, parallel to Oy axis [17 18 34 33], [17 19 37 33], [18 20 38 34], [19 20 38 37], ... [21 22 36 35], [21 23 39 35], [22 24 40 36], [23 24 40 39], ... ...% faces orthogonal to the YZ plane, parallel to Ox axis [25 33 35 26], [25 33 37 27], [26 35 39 28], [27 37 39 28], ... [29 30 36 34], [29 31 38 34], [30 32 40 36], [31 32 40 38], ... }; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/removeUnreferencedVertices.m0000644000000000000000000000013214576357161022442 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/removeUnreferencedVertices.m0000644000175000017500000000753214576357161024231 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = removeUnreferencedVertices(v, varargin) %REMOVEUNREFERENCEDVERTICES Remove unreferenced vertices of a mesh. % % [V2, F2] = removeUnreferencedVertices(V, F) % Remove unreferenced/unindexed vertices of a mesh defined by the % vertices V and faces F. % % [VIDX, FIDX] = removeUnreferencedVertices(V, F, 'indexOutput', true) % Gives the indices instead of the final mesh. This means: % V2 = V(VIDX,:) % F2 = FIDX(F) % % Example: % [v, f] = createCube; % % Add unreferenced vertices % for idx = [2, 5, 7] % v = [v(1:idx,:); rand(1,3); v(idx+1:end,:)]; % f(find(f>idx))=f(find(f>idx))+1; %#ok % end % [v2, f2] = removeUnreferencedVertices(v, f); % % See also % trimMesh, removeDuplicateFaces, removeDuplicateVertices % % Source % remove_unreferenced.m by Alec Jacobson: % https://github.com/alecjacobson/gptoolbox % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-07-14, using Matlab 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 %% Parse input if isstruct(v) [v, f] = parseMeshData(v); else f = varargin{1}; varargin(1) = []; end parser = inputParser; logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addParameter(parser, 'indexOutput', false, logParValidFunc); parse(parser, varargin{:}); indexOutput = parser.Results.indexOutput; %% Remove unreferenced/unindexed vertices if isempty(f) [vIdx, fIdx] = deal([]); else % Get list of unique vertex indices that occur in faces sF = sort(f(:)); I = [true;diff(sF)~=0]; U = sF(I); % Get list of vertices that do not occur in faces n = size(v,1); NU = find(0==sparse(U,1,1,n,1)); % assert((size(U,1) + size(NU,1)) == n); % Allocate space for an indexmap fIdx = zeros(n,1); % Reindex vertices that occur in faces to be first fIdx(U) = 1:size(U,1); % Reindex vertices that do not occur in faces to come after those that do fIdx(NU) = size(U,1) + (1:size(NU,1)); % New vertices vIdx = ismember(1:length(v),U); % v2(fIdx,:) = v; % v2 = v2(1:max(fIdx(f(:))),:); end %% Parse output if indexOutput % If indices are requested varargout = {vIdx, fIdx}; else v2 = v(vIdx,:); f2 = fIdx(f); varargout = formatMeshOutput(nargout, v2, f2); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/cutMeshByPlane.m0000644000000000000000000000013214576357161017775 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/cutMeshByPlane.m0000644000175000017500000001262614576357161021564 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cutMeshByPlane(v, f, plane, varargin) %CUTMESHBYPLANE Cut a mesh by a plane. % % [ABOVE, IN, BELOW] = cutMeshByPlane(MESH, PLANE) % where MESH, ABOVE, IN, BELOW are structs with the fields vertices and % faces, and PLANE is given as a row containing initial point and 2 % direction vectors. ABOVE, IN, BELOW contain the corresponding parts of % the input mesh. % % [ABOVE_V, ABOVE_F, IN_V, IN_F, BELOW_V,BELOW_F] = ... % cutMeshByPlane(V, F, PLANE) where V is a [NVx3] array containing % coordinates and F is a [NFx3] array containing indices of vertices of % the triangular faces. % % BELOW = cutMeshByPlane(V, F, PLANE, 'part', 'below') BELOW is a struct % with the fields vertices and faces. Other options are: % 'part' - 'above': Faces above the plane % - 'in' : Faces in the plane % - 'below': Faces below the plane % % [BELOW_V, BELOW_F] = cutMeshByPlane(MESH, PLANE, 'part', 'below') is % possible, too. % % ------ % Authors: oqilipo, David Legland % E-mail: david.legland@inrae.fr % Created: 2017-07-09 % Copyright 2017-2023 narginchk(2,5) nargoutchk(1,6) %% Parse inputs % If first argument is a struct if nargin == 2 || nargin == 4 if ~isempty(varargin) varargin = [{plane}, varargin(:)']; end plane = f; [v, f] = parseMeshData(v); end p = inputParser; addRequired(p,'plane',@isPlane) validStrings = {'above','in','below'}; addParameter(p,'part','above',@(x) any(validatestring(x, validStrings))) parse(p, plane, varargin{:}); part=p.Results.part; %% Algorithm % Logical index to the vertices below the plane VBPl_LI = isBelowPlane(v, plane); % Logical index to three vertices of each face FBP_LI = VBPl_LI(f); switch nargout case {1, 2} switch part case 'above' % Faces above the plane, all three vertices == 0 -> sum has to be 0 above = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 0) ); case 'in' % Faces in the plane, 1 or 2 vertices == 0 -> sum can be 1 or 2 inside = removeMeshFaces(v, f, ~((sum(FBP_LI, 2) > 0 & sum(FBP_LI, 2) < 3))); case 'below' % Faces below the plane, all three vertices == 1 -> sum has to be 3 below = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 3) ); end case {3, 6} % Faces above the plane, all three vertices == 0 -> sum has to be 0 above = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 0) ); % Faces in the plane, 1 or 2 vertices == 0 -> sum can be 1 or 2 inside = removeMeshFaces(v, f, ~((sum(FBP_LI, 2) > 0 & sum(FBP_LI, 2) < 3))); % Faces below the plane, all three vertices == 1 -> sum has to be 3 below = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 3) ); otherwise error('Invalid number of output arguments') end %% Parse outputs switch nargout case 1 switch part case 'above' varargout{1}=above; case 'in' varargout{1}=inside; case 'below' varargout{1}=below; end case 2 switch part case 'above' varargout{1}=above.vertices; varargout{2}=above.faces; case 'in' varargout{1}=inside.vertices; varargout{2}=inside.faces; case 'below' varargout{1}=below.vertices; varargout{2}=below.faces; end case 3 varargout{1}=above; varargout{2}=inside; varargout{3}=below; case 6 varargout{1}=above.vertices; varargout{2}=above.faces; varargout{3}=inside.vertices; varargout{4}=inside.faces; varargout{5}=below.vertices; varargout{6}=below.faces; otherwise error('Invalid number of output arguments') end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/surfToMesh.m0000644000000000000000000000013214576357161017211 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/surfToMesh.m0000644000175000017500000001030214576357161020765 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = surfToMesh(x, y, varargin) %SURFTOMESH Convert surface grids into face-vertex mesh. % % [V, F] = surfToMesh(X, Y) % [V, F] = surfToMesh(X, Y, Z) % Converts the surface grid given by two or three coordinate arrays into % a face-vertex quad mesh. % % Example % % transform a surface into a mesh % [X, Y] = meshgrid(-2:.2:2, -2:.2:2); % Z = X .* exp(-X.^2 - Y.^2); % [V, F] = surfToMesh(X, Y, Z); % figure; % drawMesh(V, F); view(3); % % % Transform surface of a cylinder as a mesh % [x, y, z] = cylinder(5*ones(1, 10)); % [v, f] = surfToMesh(x, y, z, 'xPeriodic', true); % figure; % drawMesh(v, f); % view(3); axis equal; % % See also % meshes3d, meshgrid, drawMesh, torusMesh, sphereMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-10-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform %% Parse inputs % check if z-value is present if ~isempty(varargin) && isnumeric(varargin{1}) z = varargin{1}; varargin(1) = []; end % default periodicities xPeriodic = false; yPeriodic = false; % parse input options while length(varargin) > 1 paramName = lower(varargin{1}); switch paramName case 'xperiodic' xPeriodic = varargin{2}; case 'yperiodic' yPeriodic = varargin{2}; otherwise error(['Unknown parameter name: ' paramName]); end varargin(1:2) = []; end %% Compute vertex indices % size along each direction (arrays are (y,x)-indexed) n1 = size(x, 1); n2 = size(x, 2); % in case of periodicity, the last vertex of the grid is drop (it is % assumed to be the same as the first one) if xPeriodic n2 = n2 - 1; end if yPeriodic n1 = n1 - 1; end % new size of vertex grid dim = [n1 n2]; nv = n1 * n2; %% Create vertex array % eventually remove boundary vertices x = x(1:n1, 1:n2); y = y(1:n1, 1:n2); % create vertex array if ~exist('z', 'var') vertices = [x(:) y(:)]; else z = z(1:n1, 1:n2); vertices = [x(:) y(:) z(:)]; end %% Create face array % vertex indices in grid inds = reshape(1:nv, dim); if xPeriodic inds = inds(:, [1:end 1]); end if yPeriodic inds = inds([1:end 1], :); end % vertex indices for each face v1 = inds(1:end-1, 1:end-1); v2 = inds(1:end-1, 2:end); v3 = inds(2:end, 2:end); v4 = inds(2:end, 1:end-1); % concatenate indices faces = [v1(:) v2(:) v3(:) v4(:)]; %% format output varargout = formatMeshOutput(nargout, vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/createRhombododecahedron.m0000644000000000000000000000013214576357161022064 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createRhombododecahedron.m0000644000175000017500000000603414576357161023647 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createRhombododecahedron() %CREATERHOMBODODECAHEDRON Create a 3D mesh representing a rhombododecahedron. % % [V, E, F] = createRhombododecahedron % V is a 14-by-3 array with vertex coordinate, % E is a 12-by-2 array containing indices of neighbour vertices, % F is a 8-by-3 array containing vertices array of each face. % % [V, F] = createRhombododecahedron; % Returns only the vertices and the face vertex indices. % % MESH = createRhombododecahedron; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % Example % [v, e, f] = createRhombododecahedron; % drawMesh(v, f); % % % See also % meshes3d, drawMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE nodes = [0 0 2;... 1 -1 1;1 1 1;-1 1 1;-1 -1 1;... 2 0 0;0 2 0;-2 0 0;0 -2 0;... 1 -1 -1;1 1 -1;-1 1 -1;-1 -1 -1;... 0 0 -2]; edges = [... 1 2;1 3;1 4;1 5;... 2 6;2 9;3 6;3 7;4 7;4 8;5 8;5 9;... 6 10;6 11;7 11;7 12;8 12;8 13;9 10;9 13; ... 10 14;11 14;12 14;13 14]; faces = [... 1 2 6 3;... 1 3 7 4;... 1 4 8 5;... 1 5 9 2;... 2 9 10 6;... 3 6 11 7;... 4 7 12 8;... 5 8 13 9;... 6 10 14 11;... 7 11 14 12;... 8 12 14 13;... 9 13 14 10]; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/createCube.m0000644000000000000000000000013214576357161017154 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createCube.m0000644000175000017500000000602514576357161020737 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createCube() %CREATECUBE Create a 3D mesh representing the unit cube. % % [V, E, F] = createCube % Create a unit cube, as a polyhedra representation. % c has the form [V E F], where V is a 8-by-3 array with vertices % coordinates, E is a 12-by-2 array containing indices of neighbour % vertices, and F is a 6-by-4 array containing vertices array of each % face. % % [V, F] = createCube; % Returns only the vertices and the face vertex indices. % % MESH = createCube; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % Example % [n, e, f] = createCube; % drawMesh(n, f); % % See also % meshes3d, drawMesh % createOctahedron, createTetrahedron, createDodecahedron % createIcosahedron, createCubeOctahedron % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE x0 = 0; dx= 1; y0 = 0; dy= 1; z0 = 0; dz= 1; nodes = [... x0 y0 z0; ... x0+dx y0 z0; ... x0 y0+dy z0; ... x0+dx y0+dy z0; ... x0 y0 z0+dz; ... x0+dx y0 z0+dz; ... x0 y0+dy z0+dz; ... x0+dx y0+dy z0+dz]; edges = [1 2;1 3;1 5;2 4;2 6;3 4;3 7;4 8;5 6;5 7;6 8;7 8]; % faces are oriented such that normals point outwards faces = [1 3 4 2;5 6 8 7;2 4 8 6;1 5 7 3;1 2 6 5;3 7 8 4]; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/drawMesh.m0000644000000000000000000000013214576357161016664 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/drawMesh.m0000644000175000017500000001521614576357161020451 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawMesh(varargin) %DRAWMESH Draw a 3D mesh defined by vertex and face arrays. % % drawMesh(VERTICES, FACES) % Draws the 3D mesh defined by vertices VERTICES and the faces FACES. % vertices is a NV-by-3 array containing coordinates of vertices, and % FACES is either a NF-by-3 or NF-by-4 array containing face vertex % indices of the triangular or rectangular faces. % FACES can also be a cell array, each cell containing an array of vertex % indices for the corresponding face. In this case the faces may have % variable number of vertices. % % drawMesh(MESH) % Specifies the mesh as a structure containing at least the fields % 'vertices' and 'faces', using the same conventions as above. % % drawMesh(..., COLOR) % Use the specified color to render the mesh faces. % % drawMesh(..., NAME, VALUE) % Use one or several pairs of parameter name/value to specify drawing % options. Options are the same as the 'patch' function. % % drawMesh(AX,...) % Draw into the axis specified by AX instead of the current axis. % % % H = drawMesh(...); % Also returns a handle to the created patch. % % Example: % % display a polyhedra with polygonal faces % [v, f] = createSoccerBall; % drawMesh(v, f); % % % Display a mesh representing a torus, using uniform face color % [v, f] = torusMesh; % figure; hold on; axis equal; view(3); % drawMesh(v, f, 'FaceColor', 'g') % % paint the mesh according to vertex x-coordinate % figure; hold on; axis equal; view(3); % drawMesh(v, f, 'VertexColor', v(:,1), 'LineStyle', 'none'); % % See also % meshes3d, polyhedra, patch % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% Parse input arguments % extract first argument var1 = varargin{1}; varargin(1) = []; % Check if first input argument is an axes handle if isAxisHandle(var1) ax = var1; var1 = varargin{1}; varargin(1) = []; else ax = gca; end % Check if the input is a mesh structure if isstruct(var1) % extract data to display vertices = var1.vertices; faces = var1.faces; else % assumes input is given with vertices+faces arrays vertices = var1; faces = varargin{1}; varargin(1) = []; end % if vertices are 2D points, add a z=0 coordinate if size(vertices, 2) == 2 vertices(1, 3) = 0; end %% Pre-processing for formatting display options % default color for drawing mesh faceColor = [1 0 0]; % combine defualt face color with varargin if isempty(varargin) varargin = [{'FaceColor'}, faceColor]; elseif length(varargin) == 1 % if only one optional argument is provided, it is assumed to be color faceColor = varargin{1}; varargin = [{'FaceColor'}, varargin]; elseif length(varargin) > 1 % check if FaceColor option is specified, % and if not use default face color indFC = strcmpi(varargin(1:2:end), 'FaceColor'); if ~any(indFC) varargin = [{'FaceColor'}, {faceColor}, varargin]; end end % check if simplified options are present indVC = find(strcmpi(varargin(1:2:end), 'VertexColor')); if ~isempty(indVC) vertexColor = varargin{indVC * 2}; varargin([indVC*2-1 indVC*2]) = []; indFC = find(strcmpi(varargin(1:2:end), 'FaceColor')); if ~isempty(indFC) varargin([indFC*2-1 indFC*2]) = []; end varargin = [{'FaceVertexCData'}, {vertexColor}, {'FaceColor'}, {'interp'}, varargin]; end %% Draw the mesh % overwrite on current figure hold(ax, 'on'); % Use different processing depending on the type of faces if isnumeric(faces) % array FACES is a NF-by-NV indices array, with NF: number of faces, % and NV: number of vertices per face h = patch('Parent', ax, ... 'vertices', vertices, 'faces', faces, ... varargin{:}); elseif iscell(faces) % array FACES is a cell array. Need to draw each face as a single % patch. h = zeros(length(faces(:)), 1); for iFace = 1:length(faces(:)) % get vertices of the cell face = faces{iFace}; % Special processing in case of multiple polygonal face: % each polygonal loop is separated by a NaN. if sum(isnan(face)) ~= 0 % find indices of loops breaks inds = find(isnan(face)); % replace NaNs by index of first vertex of each polygon face(inds(2:end)) = face(inds(1:end-1)+1); face(inds(1)) = face(1); face(length(face)+1)= face(inds(end)+1); end % draw current face cnodes = vertices(face, :); h(iFace) = patch(ax, cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), faceColor); end % set up drawing options set(h, varargin{:}); else error('MatGeom:drawMesh', 'Second argument must be a face array'); end %% Process output arguments % format output parameters if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/apple.ply0000644000000000000000000000013214576357160016562 xustar0030 mtime=1710874224.654193807 30 atime=1710874224.646193816 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/apple.ply0000644000175000017500000014212614576357160020350 0ustar00juanpijuanpi00000000000000ply format ascii 1.0 element vertex 867 property float32 x property float32 y property float32 z element face 1704 property list uint8 int32 vertex_indices end_header 0.00472708 0.0012 -0.000833515 0.0048 0.0012 0 0 0 0 0.00451052 0.0012 -0.0016417 0.00415692 0.0012 -0.00240001 0.00367701 0.0012 -0.00308539 0.00308537 0.0012 -0.00367702 0.00239999 0.0012 -0.00415693 0.00164168 0.0012 -0.00451053 0.000833496 0.0012 -0.00472708 -1.79482e-08 0.0012 -0.0048 -0.00083353 0.0012 -0.00472707 -0.00164172 0.0012 -0.00451052 -0.00240002 0.0012 -0.00415691 -0.0030854 0.0012 -0.003677 -0.00367703 0.0012 -0.00308536 -0.00415694 0.0012 -0.00239997 -0.00451054 0.0012 -0.00164167 -0.00472708 0.0012 -0.000833477 -0.0048 0.0012 3.70407e-08 -0.00472707 0.0012 0.000833549 -0.00451051 0.0012 0.00164173 -0.0041569 0.0012 0.00240004 -0.00367698 0.0012 0.00308542 -0.00308534 0.0012 0.00367704 -0.00239996 0.0012 0.00415694 -0.00164165 0.0012 0.00451054 -0.000833458 0.0012 0.00472709 5.49888e-08 0.0012 0.0048 0.000833568 0.0012 0.00472707 0.00164175 0.0012 0.0045105 0.00240005 0.0012 0.00415689 0.00308543 0.0012 0.00367697 0.00367705 0.0012 0.00308533 0.00415695 0.0012 0.00239994 0.00451055 0.0012 0.00164163 0.00472709 0.0012 0.000833438 0.00945418 0.0024 -0.00166703 0.0096 0.0024 0 0.00902102 0.0024 -0.0032834 0.00831384 0.0024 -0.0048 0.00735403 0.0024 -0.00617078 0.00617074 0.0024 -0.00735403 0.00479998 0.0024 -0.00831384 0.00328337 0.0024 -0.00902107 0.00166699 0.0024 -0.00945418 -3.58963e-08 0.0024 -0.0096 -0.00166706 0.0024 -0.00945413 -0.00328344 0.0024 -0.00902102 -0.00480005 0.0024 -0.00831384 -0.00617078 0.0024 -0.00735398 -0.00735408 0.0024 -0.00617074 -0.00831389 0.0024 -0.00479995 -0.00902107 0.0024 -0.00328333 -0.00945418 0.0024 -0.00166695 -0.0096 0.0024 7.40813e-08 -0.00945413 0.0024 0.0016671 -0.00902102 0.0024 0.00328347 -0.00831379 0.0024 0.0048001 -0.00735398 0.0024 0.00617083 -0.00617069 0.0024 0.00735408 -0.00479991 0.0024 0.00831389 -0.0032833 0.0024 0.00902107 -0.00166692 0.0024 0.00945418 1.09978e-07 0.0024 0.0096 0.00166714 0.0024 0.00945413 0.0032835 0.0024 0.00902102 0.0048001 0.0024 0.00831379 0.00617088 0.0024 0.00735394 0.00735413 0.0024 0.00617064 0.00831389 0.0024 0.00479988 0.00902112 0.0024 0.00328326 0.00945418 0.0024 0.00166688 0.0155994 0.0012 -0.00275059 0.01584 0.0012 0 0.0148847 0.0012 -0.00541762 0.0137178 0.0012 -0.00792 0.0121341 0.0012 -0.0101818 0.0101817 0.0012 -0.0121342 0.00791995 0.0012 -0.0137179 0.00541757 0.0012 -0.0148848 0.00275053 0.0012 -0.0155994 -5.92291e-08 0.0012 -0.01584 -0.00275065 0.0012 -0.0155993 -0.00541766 0.0012 -0.0148847 -0.00792005 0.0012 -0.0137178 -0.0101818 0.0012 -0.0121341 -0.0121342 0.0012 -0.0101817 -0.0137179 0.0012 -0.0079199 -0.0148848 0.0012 -0.00541752 -0.0155994 0.0012 -0.00275047 -0.01584 0.0012 1.22234e-07 -0.0155993 0.0012 0.00275071 -0.0148847 0.0012 0.00541771 -0.0137178 0.0012 0.00792014 -0.0121341 0.0012 0.0101819 -0.0101816 0.0012 0.0121343 -0.00791986 0.0012 0.0137179 -0.00541742 0.0012 0.0148848 -0.00275041 0.0012 0.0155994 1.81464e-07 0.0012 0.01584 0.00275077 0.0012 0.0155993 0.00541776 0.0012 0.0148847 0.00792019 0.0012 0.0137177 0.0101819 0.0012 0.012134 0.0121343 0.0012 0.0101816 0.013718 0.0012 0.00791981 0.0148848 0.0012 0.00541738 0.0155994 0.0012 0.00275035 0.0212718 -0.00048 -0.00375081 0.0216 -0.00048 0 0.0202974 -0.00048 -0.00738763 0.0187061 -0.00048 -0.0108 0.0165466 -0.00048 -0.0138842 0.0138842 -0.00048 -0.0165466 0.0108 -0.00048 -0.0187062 0.00738758 -0.00048 -0.0202974 0.00375073 -0.00048 -0.0212719 -8.07667e-08 -0.00048 -0.0216 -0.00375089 -0.00048 -0.0212718 -0.00738773 -0.00048 -0.0202973 -0.0108001 -0.00048 -0.0187061 -0.0138843 -0.00048 -0.0165465 -0.0165467 -0.00048 -0.0138841 -0.0187062 -0.00048 -0.0107999 -0.0202974 -0.00048 -0.00738749 -0.0212719 -0.00048 -0.00375065 -0.0216 -0.00048 1.66683e-07 -0.0212718 -0.00048 0.00375097 -0.0202973 -0.00048 0.00738782 -0.018706 -0.00048 0.0108002 -0.0165464 -0.00048 0.0138844 -0.013884 -0.00048 0.0165467 -0.0107998 -0.00048 0.0187063 -0.00738744 -0.00048 0.0202974 -0.00375057 -0.00048 0.0212719 2.4745e-07 -0.00048 0.0216 0.00375106 -0.00048 0.0212718 0.00738787 -0.00048 0.0202973 0.0108002 -0.00048 0.018706 0.0138844 -0.00048 0.0165464 0.0165468 -0.00048 0.013884 0.0187063 -0.00048 0.0107997 0.0202975 -0.00048 0.00738734 0.0212719 -0.00048 0.00375048 0.0250535 -0.0012 -0.00441762 0.02544 -0.0012 0 0.0239058 -0.0012 -0.00870101 0.0220317 -0.0012 -0.01272 0.0194881 -0.0012 -0.0163525 0.0163525 -0.0012 -0.0194882 0.01272 -0.0012 -0.0220317 0.00870091 -0.0012 -0.0239058 0.00441753 -0.0012 -0.0250535 -9.51254e-08 -0.0012 -0.02544 -0.00441771 -0.0012 -0.0250535 -0.0087011 -0.0012 -0.0239057 -0.0127201 -0.0012 -0.0220316 -0.0163526 -0.0012 -0.0194881 -0.0194883 -0.0012 -0.0163524 -0.0220318 -0.0012 -0.0127199 -0.0239058 -0.0012 -0.00870082 -0.0250536 -0.0012 -0.00441743 -0.02544 -0.0012 1.96316e-07 -0.0250535 -0.0012 0.00441781 -0.0239057 -0.0012 0.0087012 -0.0220316 -0.0012 0.0127202 -0.019488 -0.0012 0.0163527 -0.0163524 -0.0012 0.0194883 -0.0127198 -0.0012 0.0220318 -0.00870072 -0.0012 0.0239059 -0.00441733 -0.0012 0.0250536 2.91441e-07 -0.0012 0.02544 0.00441791 -0.0012 0.0250535 0.0087013 -0.0012 0.0239057 0.0127203 -0.0012 0.0220315 0.0163528 -0.0012 0.019488 0.0194884 -0.0012 0.0163523 0.0220319 -0.0012 0.0127197 0.0239059 -0.0012 0.00870063 0.0250536 -0.0012 0.00441723 0.0283625 0 -0.00500107 0.0288 0 0 0.0270631 0 -0.00985022 0.0249415 0 -0.0144 0.0220621 0 -0.0185123 0.0185123 0 -0.0220621 0.0144 0 -0.0249416 0.00985008 0 -0.0270632 0.00500098 0 -0.0283625 -1.07689e-07 0 -0.0288 -0.00500117 0 -0.0283624 -0.00985032 0 -0.0270631 -0.0144001 0 -0.0249415 -0.0185124 0 -0.022062 -0.0220622 0 -0.0185122 -0.0249416 0 -0.0143999 -0.0270632 0 -0.00984998 -0.0283625 0 -0.00500088 -0.0288 0 2.22244e-07 -0.0283624 0 0.00500131 -0.0270631 0 0.00985042 -0.0249414 0 0.0144002 -0.0220619 0 0.0185125 -0.0185121 0 0.0220622 -0.0143998 0 0.0249417 -0.00984989 0 0.0270633 -0.00500074 0 0.0283625 3.29933e-07 0 0.0288 0.00500141 0 0.0283624 0.00985051 0 0.027063 0.0144003 0 0.0249413 0.0185126 0 0.0220619 0.0220623 0 0.018512 0.0249418 0 0.0143997 0.0270633 0 0.00984979 0.0283625 0 0.00500064 0.0354531 0.0072 -0.00625133 0.036 0.0072 0 0.0338289 0.0072 -0.0123128 0.0311769 0.0072 -0.018 0.0275776 0.0072 -0.0231404 0.0231403 0.0072 -0.0275776 0.0179999 0.0072 -0.031177 0.0123126 0.0072 -0.033829 0.00625123 0.0072 -0.0354531 -1.34611e-07 0.0072 -0.036 -0.00625147 0.0072 -0.035453 -0.0123129 0.0072 -0.0338289 -0.0180001 0.0072 -0.0311768 -0.0231405 0.0072 -0.0275775 -0.0275777 0.0072 -0.0231402 -0.031177 0.0072 -0.0179998 -0.033829 0.0072 -0.0123125 -0.0354531 0.0072 -0.00625109 -0.036 0.0072 2.77805e-07 -0.035453 0.0072 0.00625162 -0.0338288 0.0072 0.012313 -0.0311768 0.0072 0.0180003 -0.0275774 0.0072 0.0231406 -0.0231401 0.0072 0.0275778 -0.0179997 0.0072 0.0311771 -0.0123124 0.0072 0.0338291 -0.00625094 0.0072 0.0354531 4.12417e-07 0.0072 0.036 0.00625176 0.0072 0.035453 0.0123132 0.0072 0.0338288 0.0180004 0.0072 0.0311767 0.0231407 0.0072 0.0275773 0.0275779 0.0072 0.02314 0.0311772 0.0072 0.0179996 0.0338291 0.0072 0.0123122 0.0354532 0.0072 0.0062508 0.0415983 0.0144 -0.00733493 0.04224 0.0144 0 0.0396926 0.0144 -0.0144469 0.0365809 0.0144 -0.02112 0.0323577 0.0144 -0.0271514 0.0271513 0.0144 -0.0323578 0.0211199 0.0144 -0.0365809 0.0144468 0.0144 -0.0396926 0.00733478 0.0144 -0.0415983 -1.57944e-07 0.0144 -0.04224 -0.00733507 0.0144 -0.0415982 -0.0144471 0.0144 -0.0396925 -0.0211202 0.0144 -0.0365808 -0.0271515 0.0144 -0.0323576 -0.0323579 0.0144 -0.0271512 -0.036581 0.0144 -0.0211198 -0.0396927 0.0144 -0.0144467 -0.0415983 0.0144 -0.00733459 -0.04224 0.0144 3.25958e-07 -0.0415982 0.0144 0.00733522 -0.0396925 0.0144 0.0144473 -0.0365807 0.0144 0.0211203 -0.0323575 0.0144 0.0271517 -0.0271511 0.0144 0.032358 -0.0211196 0.0144 0.0365811 -0.0144465 0.0144 0.0396928 -0.00733445 0.0144 0.0415983 4.83902e-07 0.0144 0.04224 0.00733541 0.0144 0.0415982 0.0144474 0.0144 0.0396925 0.0211205 0.0144 0.0365807 0.0271518 0.0144 0.0323574 0.0323581 0.0144 0.0271509 0.0365812 0.0144 0.0211195 0.0396928 0.0144 0.0144464 0.0415984 0.0144 0.00733426 0.0472708 0.024 -0.00833515 0.048 0.024 0 0.0451052 0.024 -0.016417 0.0415692 0.024 -0.024 0.0367701 0.024 -0.0308539 0.0308537 0.024 -0.0367702 0.0239999 0.024 -0.0415693 0.0164168 0.024 -0.0451053 0.00833496 0.024 -0.0472708 -1.79482e-07 0.024 -0.048 -0.0083353 0.024 -0.0472707 -0.0164172 0.024 -0.0451052 -0.0240002 0.024 -0.0415691 -0.030854 0.024 -0.03677 -0.0367703 0.024 -0.0308536 -0.0415694 0.024 -0.0239997 -0.0451054 0.024 -0.0164167 -0.0472708 0.024 -0.00833477 -0.048 0.024 3.70407e-07 -0.0472707 0.024 0.00833549 -0.0451051 0.024 0.0164173 -0.041569 0.024 0.0240004 -0.0367698 0.024 0.0308542 -0.0308534 0.024 0.0367705 -0.0239996 0.024 0.0415695 -0.0164165 0.024 0.0451054 -0.00833458 0.024 0.0472709 5.49888e-07 0.024 0.048 0.00833568 0.024 0.0472707 0.0164175 0.024 0.045105 0.0240005 0.024 0.0415689 0.0308543 0.024 0.0367697 0.0367705 0.024 0.0308533 0.0415696 0.024 0.0239994 0.0451055 0.024 0.0164163 0.0472709 0.024 0.00833438 0.0496344 0.0336 -0.00875189 0.0504 0.0336 0 0.0473605 0.0336 -0.0172379 0.0436477 0.0336 -0.0252 0.0386086 0.0336 -0.0323965 0.0323964 0.0336 -0.0386087 0.0251999 0.0336 -0.0436477 0.0172377 0.0336 -0.0473605 0.0087517 0.0336 -0.0496344 -1.88456e-07 0.0336 -0.0504 -0.00875208 0.0336 -0.0496344 -0.017238 0.0336 -0.0473605 -0.0252002 0.0336 -0.0436476 -0.0323967 0.0336 -0.0386085 -0.0386089 0.0336 -0.0323963 -0.0436478 0.0336 -0.0251997 -0.0473606 0.0336 -0.0172375 -0.0496344 0.0336 -0.0087515 -0.0504 0.0336 3.88928e-07 -0.0496344 0.0336 0.00875227 -0.0473604 0.0336 0.0172382 -0.0436475 0.0336 0.0252004 -0.0386083 0.0336 0.0323969 -0.0323961 0.0336 0.0386089 -0.0251996 0.0336 0.0436479 -0.0172373 0.0336 0.0473607 -0.00875131 0.0336 0.0496344 5.77382e-07 0.0336 0.0504 0.00875246 0.0336 0.0496344 0.0172384 0.0336 0.0473603 0.0252006 0.0336 0.0436474 0.032397 0.0336 0.0386082 0.0386091 0.0336 0.032396 0.043648 0.0336 0.0251994 0.0473608 0.0336 0.0172371 0.0496344 0.0336 0.00875112 0.051289 0.0432 -0.00904363 0.05208 0.0432 0 0.0489394 0.0432 -0.0178125 0.0451026 0.0432 -0.0260401 0.0398955 0.0432 -0.0334764 0.0334763 0.0432 -0.0398956 0.0260399 0.0432 -0.0451027 0.0178123 0.0432 -0.0489394 0.00904344 0.0432 -0.051289 -1.94737e-07 0.0432 -0.05208 -0.00904382 0.0432 -0.051289 -0.0178127 0.0432 -0.0489389 -0.0260402 0.0432 -0.0451025 -0.0334766 0.0432 -0.0398954 -0.0398958 0.0432 -0.0334762 -0.0451028 0.0432 -0.0260397 -0.0489394 0.0432 -0.0178121 -0.051289 0.0432 -0.0090432 -0.05208 0.0432 4.01892e-07 -0.0512885 0.0432 0.00904402 -0.0489389 0.0432 0.0178128 -0.0451024 0.0432 0.0260404 -0.0398953 0.0432 0.0334767 -0.033476 0.0432 0.0398959 -0.0260395 0.0432 0.0451029 -0.0178119 0.0432 0.0489394 -0.00904301 0.0432 0.051289 5.9663e-07 0.0432 0.05208 0.00904421 0.0432 0.0512885 0.017813 0.0432 0.0489389 0.0260406 0.0432 0.0451023 0.0334769 0.0432 0.0398952 0.0398961 0.0432 0.0334758 0.045103 0.0432 0.0260394 0.0489394 0.0432 0.0178117 0.051289 0.0432 0.00904282 0.0510523 0.05232 -0.00900192 0.05184 0.05232 0 0.0487138 0.05232 -0.0177304 0.0448947 0.05232 -0.0259201 0.0397117 0.05232 -0.0333222 0.033322 0.05232 -0.0397118 0.0259199 0.05232 -0.0448948 0.0177302 0.05232 -0.0487138 0.00900178 0.05232 -0.0510523 -1.9384e-07 0.05232 -0.05184 -0.00900211 0.05232 -0.0510523 -0.0177305 0.05232 -0.0487138 -0.0259202 0.05232 -0.0448946 -0.0333223 0.05232 -0.0397116 -0.0397119 0.05232 -0.0333219 -0.0448949 0.05232 -0.0259197 -0.0487138 0.05232 -0.01773 -0.0510523 0.05232 -0.00900154 -0.05184 0.05232 4.0004e-07 -0.0510523 0.05232 0.00900235 -0.0487133 0.05232 0.0177307 -0.0448945 0.05232 0.0259204 -0.0397114 0.05232 0.0333225 -0.0333217 0.05232 0.0397121 -0.0259196 0.05232 0.044895 -0.0177298 0.05232 0.0487138 -0.00900134 0.05232 0.0510523 5.9388e-07 0.05232 0.05184 0.00900254 0.05232 0.0510523 0.0177309 0.05232 0.0487133 0.0259206 0.05232 0.0448944 0.0333227 0.05232 0.0397113 0.0397122 0.05232 0.0333216 0.0448951 0.05232 0.0259194 0.0487138 0.05232 0.0177296 0.0510528 0.05232 0.00900115 0.0501072 0.05904 -0.00883522 0.05088 0.05904 0 0.0478116 0.05904 -0.017402 0.0440633 0.05904 -0.0254401 0.0389763 0.05904 -0.0327051 0.0327049 0.05904 -0.0389764 0.0254399 0.05904 -0.0440634 0.0174019 0.05904 -0.0478116 0.00883507 0.05904 -0.0501072 -1.9025e-07 0.05904 -0.05088 -0.00883541 0.05904 -0.0501072 -0.0174022 0.05904 -0.0478115 -0.0254402 0.05904 -0.0440632 -0.0327052 0.05904 -0.0389761 -0.0389765 0.05904 -0.0327048 -0.0440635 0.05904 -0.0254397 -0.0478117 0.05904 -0.0174017 -0.0501072 0.05904 -0.00883483 -0.05088 0.05904 3.92632e-07 -0.0501067 0.05904 0.00883565 -0.0478114 0.05904 0.0174024 -0.0440631 0.05904 0.0254404 -0.0389761 0.05904 0.0327054 -0.0327047 0.05904 0.0389767 -0.0254396 0.05904 0.0440636 -0.0174015 0.05904 0.0478117 -0.00883469 0.05904 0.0501072 5.82883e-07 0.05904 0.05088 0.00883579 0.05904 0.0501067 0.0174026 0.05904 0.0478114 0.0254406 0.05904 0.044063 0.0327056 0.05904 0.0389759 0.0389768 0.05904 0.0327045 0.0440637 0.05904 0.0254394 0.0478118 0.05904 0.0174013 0.0501072 0.05904 0.00883445 0.0467981 0.066 -0.00825178 0.04752 0.066 0 0.0446542 0.066 -0.0162528 0.0411535 0.066 -0.02376 0.0364024 0.066 -0.0305453 0.0305452 0.066 -0.0364025 0.0237599 0.066 -0.0411536 0.0162527 0.066 -0.0446543 0.00825158 0.066 -0.0467981 -1.77687e-07 0.066 -0.04752 -0.00825197 0.066 -0.046798 -0.016253 0.066 -0.0446541 -0.0237602 0.066 -0.0411534 -0.0305455 0.066 -0.0364023 -0.0364026 0.066 -0.030545 -0.0411537 0.066 -0.0237598 -0.0446543 0.066 -0.0162525 -0.0467981 0.066 -0.00825144 -0.04752 0.066 3.66703e-07 -0.046798 0.066 0.00825216 -0.0446541 0.066 0.0162532 -0.0411533 0.066 0.0237604 -0.0364021 0.066 0.0305456 -0.0305449 0.066 0.0364027 -0.0237596 0.066 0.0411538 -0.0162523 0.066 0.0446544 -0.00825125 0.066 0.0467982 5.44392e-07 0.066 0.04752 0.0082523 0.066 0.046798 0.0162533 0.066 0.044654 0.0237605 0.066 0.0411532 0.0305458 0.066 0.0364021 0.0364029 0.066 0.0305448 0.0411539 0.066 0.0237594 0.0446545 0.066 0.0162521 0.0467982 0.066 0.00825106 0.0430164 0.07032 -0.00758496 0.04368 0.07032 0 0.0410458 0.07032 -0.0149395 0.037828 0.07032 -0.0218401 0.0334608 0.07032 -0.028077 0.0280769 0.07032 -0.0334609 0.0218399 0.07032 -0.037828 0.0149393 0.07032 -0.0410458 0.00758482 0.07032 -0.0430164 -1.63328e-07 0.07032 -0.04368 -0.00758515 0.07032 -0.0430164 -0.0149396 0.07032 -0.0410457 -0.0218402 0.07032 -0.0378279 -0.0280772 0.07032 -0.0334607 -0.033461 0.07032 -0.0280768 -0.0378281 0.07032 -0.0218398 -0.0410459 0.07032 -0.0149391 -0.0430164 0.07032 -0.00758462 -0.04368 0.07032 3.3707e-07 -0.0430164 0.07032 0.0075853 -0.0410457 0.07032 0.0149398 -0.0378278 0.07032 0.0218403 -0.0334606 0.07032 0.0280773 -0.0280766 0.07032 0.0334611 -0.0218396 0.07032 0.0378282 -0.014939 0.07032 0.041046 -0.00758448 0.07032 0.0430165 5.004e-07 0.07032 0.04368 0.00758549 0.07032 0.0430163 0.01494 0.07032 0.0410456 0.0218405 0.07032 0.0378277 0.0280774 0.07032 0.0334605 0.0334612 0.07032 0.0280765 0.0378283 0.07032 0.0218395 0.041046 0.07032 0.0149388 0.0430165 0.07032 0.00758429 0.0382893 0.07272 -0.00675144 0.03888 0.07272 0 0.0365352 0.07272 -0.0132978 0.033671 0.07272 -0.01944 0.0297838 0.07272 -0.0249916 0.0249915 0.07272 -0.0297839 0.0194399 0.07272 -0.0336711 0.0132976 0.07272 -0.0365353 0.0067513 0.07272 -0.0382894 -1.4538e-07 0.07272 -0.03888 -0.00675158 0.07272 -0.0382893 -0.0132979 0.07272 -0.0365352 -0.0194402 0.07272 -0.033671 -0.0249917 0.07272 -0.0297837 -0.029784 0.07272 -0.0249914 -0.0336712 0.07272 -0.0194398 -0.0365353 0.07272 -0.0132975 -0.0382894 0.07272 -0.00675115 -0.03888 0.07272 3.0003e-07 -0.0382893 0.07272 0.00675178 -0.0365352 0.07272 0.0132981 -0.0336709 0.07272 0.0194403 -0.0297836 0.07272 0.0249919 -0.0249913 0.07272 0.029784 -0.0194397 0.07272 0.0336713 -0.0132973 0.07272 0.0365354 -0.00675101 0.07272 0.0382894 4.4541e-07 0.07272 0.03888 0.00675192 0.07272 0.0382893 0.0132982 0.07272 0.0365351 0.0194404 0.07272 0.0336708 0.024992 0.07272 0.0297835 0.0297841 0.07272 0.0249912 0.0336713 0.07272 0.0194395 0.0365354 0.07272 0.0132972 0.0382894 0.07272 0.00675086 0.0330895 0.07416 -0.00583459 0.0336 0.07416 0 0.0315737 0.07416 -0.0114919 0.0290984 0.07416 -0.0168 0.025739 0.07416 -0.0215977 0.0215976 0.07416 -0.0257391 0.0168 0.07416 -0.0290985 0.0114918 0.07416 -0.0315737 0.00583445 0.07416 -0.0330896 -1.25637e-07 0.07416 -0.0336 -0.00583474 0.07416 -0.0330895 -0.011492 0.07416 -0.0315736 -0.0168001 0.07416 -0.0290984 -0.0215978 0.07416 -0.025739 -0.0257392 0.07416 -0.0215975 -0.0290986 0.07416 -0.0167998 -0.0315737 0.07416 -0.0114917 -0.0330896 0.07416 -0.00583435 -0.0336 0.07416 2.59285e-07 -0.0330895 0.07416 0.00583483 -0.0315736 0.07416 0.0114922 -0.0290983 0.07416 0.0168002 -0.0257389 0.07416 0.0215979 -0.0215974 0.07416 0.0257393 -0.0167997 0.07416 0.0290986 -0.0114915 0.07416 0.0315738 -0.00583421 0.07416 0.0330896 3.84922e-07 0.07416 0.0336 0.00583498 0.07416 0.0330895 0.0114923 0.07416 0.0315735 0.0168004 0.07416 0.0290982 0.021598 0.07416 0.0257388 0.0257394 0.07416 0.0215973 0.0290987 0.07416 0.0167996 0.0315738 0.07416 0.0114914 0.0330896 0.07416 0.00583406 0.0271807 0.0744 -0.0047927 0.0276 0.0744 0 0.0259355 0.0744 -0.00943978 0.0239023 0.0744 -0.0138 0.0211428 0.0744 -0.017741 0.0177409 0.0744 -0.0211428 0.0138 0.0744 -0.0239023 0.00943968 0.0744 -0.0259356 0.0047926 0.0744 -0.0271807 -1.03202e-07 0.0744 -0.0276 -0.0047928 0.0744 -0.0271807 -0.00943987 0.0744 -0.0259355 -0.0138001 0.0744 -0.0239022 -0.017741 0.0744 -0.0211428 -0.0211429 0.0744 -0.0177408 -0.0239024 0.0744 -0.0137999 -0.0259356 0.0744 -0.00943958 -0.0271807 0.0744 -0.00479249 -0.0276 0.0744 2.12984e-07 -0.0271807 0.0744 0.00479291 -0.0259355 0.0744 0.00943997 -0.0239022 0.0744 0.0138002 -0.0211427 0.0744 0.0177411 -0.0177408 0.0744 0.021143 -0.0137998 0.0744 0.0239025 -0.00943949 0.0744 0.0259356 -0.00479239 0.0744 0.0271808 3.16186e-07 0.0744 0.0276 0.00479301 0.0744 0.0271806 0.00944006 0.0744 0.0259354 0.0138003 0.0744 0.0239021 0.0177412 0.0744 0.0211426 0.0211431 0.0744 0.0177407 0.0239025 0.0744 0.0137997 0.0259356 0.0744 0.00943939 0.0271808 0.0744 0.00479228 0.0212718 0.07416 -0.00375081 0.0216 0.07416 0 0.0202974 0.07416 -0.00738763 0.0187061 0.07416 -0.0108 0.0165466 0.07416 -0.0138842 0.0138842 0.07416 -0.0165466 0.0108 0.07416 -0.0187062 0.00738758 0.07416 -0.0202974 0.00375073 0.07416 -0.0212719 -8.07667e-08 0.07416 -0.0216 -0.00375089 0.07416 -0.0212718 -0.00738773 0.07416 -0.0202973 -0.0108001 0.07416 -0.0187061 -0.0138843 0.07416 -0.0165465 -0.0165467 0.07416 -0.0138841 -0.0187062 0.07416 -0.0107999 -0.0202974 0.07416 -0.00738749 -0.0212719 0.07416 -0.00375065 -0.0216 0.07416 1.66683e-07 -0.0212718 0.07416 0.00375097 -0.0202973 0.07416 0.00738782 -0.018706 0.07416 0.0108002 -0.0165464 0.07416 0.0138844 -0.013884 0.07416 0.0165467 -0.0107998 0.07416 0.0187063 -0.00738744 0.07416 0.0202974 -0.00375057 0.07416 0.0212719 2.4745e-07 0.07416 0.0216 0.00375106 0.07416 0.0212718 0.00738787 0.07416 0.0202973 0.0108002 0.07416 0.018706 0.0138844 0.07416 0.0165464 0.0165468 0.07416 0.013884 0.0187063 0.07416 0.0107997 0.0202975 0.07416 0.00738734 0.0212719 0.07416 0.00375048 0.0155994 0.07344 -0.00275059 0.01584 0.07344 0 0.0148847 0.07344 -0.00541762 0.0137178 0.07344 -0.00792 0.0121341 0.07344 -0.0101818 0.0101817 0.07344 -0.0121342 0.00791995 0.07344 -0.0137179 0.00541757 0.07344 -0.0148848 0.00275053 0.07344 -0.0155994 -5.92291e-08 0.07344 -0.01584 -0.00275065 0.07344 -0.0155993 -0.00541766 0.07344 -0.0148847 -0.00792005 0.07344 -0.0137178 -0.0101818 0.07344 -0.0121341 -0.0121342 0.07344 -0.0101817 -0.0137179 0.07344 -0.0079199 -0.0148848 0.07344 -0.00541752 -0.0155994 0.07344 -0.00275047 -0.01584 0.07344 1.22234e-07 -0.0155993 0.07344 0.00275071 -0.0148847 0.07344 0.00541771 -0.0137178 0.07344 0.00792014 -0.0121341 0.07344 0.0101819 -0.0101816 0.07344 0.0121343 -0.00791986 0.07344 0.0137179 -0.00541742 0.07344 0.0148848 -0.00275041 0.07344 0.0155994 1.81464e-07 0.07344 0.01584 0.00275077 0.07344 0.0155993 0.00541776 0.07344 0.0148847 0.00792019 0.07344 0.0137177 0.0101819 0.07344 0.012134 0.0121343 0.07344 0.0101816 0.013718 0.07344 0.00791981 0.0148848 0.07344 0.00541738 0.0155994 0.07344 0.00275035 0.0103996 0.072 -0.00183373 0.01056 0.072 0 0.00992314 0.072 -0.00361174 0.0091452 0.072 -0.00528 0.00808944 0.072 -0.00678787 0.00678782 0.072 -0.00808944 0.00528 0.072 -0.00914525 0.0036117 0.072 -0.00992318 0.00183369 0.072 -0.0103996 -3.9486e-08 0.072 -0.01056 -0.00183377 0.072 -0.0103996 -0.00361178 0.072 -0.00992314 -0.00528005 0.072 -0.0091452 -0.00678787 0.072 -0.00808939 -0.00808949 0.072 -0.00678778 -0.00914525 0.072 -0.00527995 -0.00992318 0.072 -0.00361166 -0.0103996 0.072 -0.00183365 -0.01056 0.072 8.14896e-08 -0.0103995 0.072 0.00183381 -0.00992314 0.072 0.00361182 -0.0091452 0.072 0.0052801 -0.00808934 0.072 0.00678792 -0.00678778 0.072 0.00808949 -0.0052799 0.072 0.0091453 -0.00361163 0.072 0.00992318 -0.00183361 0.072 0.0103996 1.20975e-07 0.072 0.01056 0.00183385 0.072 0.0103995 0.00361186 0.072 0.00992309 0.0052801 0.072 0.00914515 0.00678797 0.072 0.00808934 0.00808954 0.072 0.00678773 0.0091453 0.072 0.00527986 0.00992318 0.072 0.00361159 0.0103996 0.072 0.00183357 0.00543614 0.0696 -0.000958541 0.00552 0.0696 0 0.00518712 0.0696 -0.00188796 0.00478045 0.0696 -0.00276 0.00422856 0.0696 -0.00354819 0.00354818 0.0696 -0.00422857 0.00275999 0.0696 -0.00478047 0.00188794 0.0696 -0.00518712 0.000958522 0.0696 -0.00543614 -2.06404e-08 0.0696 -0.00552 -0.00095856 0.0696 -0.00543614 -0.00188797 0.0696 -0.00518707 -0.00276002 0.0696 -0.00478045 -0.00354821 0.0696 -0.00422855 -0.00422858 0.0696 -0.00354816 -0.00478048 0.0696 -0.00275997 -0.00518712 0.0696 -0.00188792 -0.00543614 0.0696 -0.000958498 -0.00552 0.0696 4.25968e-08 -0.00543614 0.0696 0.000958584 -0.00518707 0.0696 0.00188799 -0.00478044 0.0696 0.00276004 -0.00422853 0.0696 0.00354823 -0.00354815 0.0696 0.0042286 -0.00275995 0.0696 0.00478049 -0.0018879 0.0696 0.00518712 -0.000958478 0.0696 0.00543614 6.32371e-08 0.0696 0.00552 0.000958603 0.0696 0.00543614 0.00188802 0.0696 0.00518707 0.00276006 0.0696 0.00478043 0.00354824 0.0696 0.00422852 0.00422861 0.0696 0.00354813 0.0047805 0.0696 0.00275993 0.00518712 0.0696 0.00188787 0.00543614 0.0696 0.000958454 0 0.0672 0 0.00162276 0.0648 -0.000434817 0.00231822 0.072 -0.000621168 0.0024 0.072 0 0.00168 0.0648 0 0.00370916 0.0792 -0.000993869 0.00384 0.0792 0 0.00145492 0.0648 -0.00084 0.00207846 0.072 -0.0012 0.00332554 0.0792 -0.00192 0.00118794 0.0648 -0.00118794 0.00169705 0.072 -0.00169706 0.00271528 0.0792 -0.00271529 0.000839995 0.0648 -0.00145492 0.0012 0.072 -0.00207846 0.00191999 0.0792 -0.00332554 0.000434811 0.0648 -0.00162276 0.000621158 0.072 -0.00231822 0.000993854 0.0792 -0.00370916 -6.28186e-09 0.0648 -0.00168 -8.97408e-09 0.072 -0.0024 -1.43585e-08 0.0792 -0.00384 -0.000434823 0.0648 -0.00162276 -0.000621178 0.072 -0.00231822 -0.000993883 0.0792 -0.00370915 -0.00084001 0.0648 -0.00145492 -0.00120001 0.072 -0.00207845 -0.00192002 0.0792 -0.00332553 -0.00118795 0.0648 -0.00118793 -0.00169706 0.072 -0.00169704 -0.00271531 0.0792 -0.00271527 -0.00145493 0.0648 -0.00083999 -0.00207847 0.072 -0.00119999 -0.00332555 0.0792 -0.00191998 -0.00162276 0.0648 -0.000434805 -0.00231823 0.072 -0.000621149 -0.00370916 0.0792 -0.00099384 -0.00168 0.0648 1.29643e-08 -0.0024 0.072 1.85204e-08 -0.00384 0.0792 2.96326e-08 -0.00162275 0.0648 0.00043483 -0.00231822 0.072 0.000621187 -0.00370915 0.0792 0.000993898 -0.00145491 0.0648 0.000840014 -0.00207845 0.072 0.00120002 -0.00332552 0.0792 0.00192003 -0.00118793 0.0648 0.00118795 -0.00169704 0.072 0.00169707 -0.00271526 0.0792 0.00271532 -0.000839986 0.0648 0.00145493 -0.00119998 0.072 0.00207847 -0.00191997 0.0792 0.00332556 -0.000434799 0.0648 0.00162276 -0.000621139 0.072 0.00231823 -0.000993826 0.0792 0.00370917 1.8445e-08 0.0648 0.00168 2.635e-08 0.072 0.0024 4.216e-08 0.0792 0.00384 0.000434834 0.0648 0.00162275 0.000621192 0.072 0.00231821 0.000993907 0.0792 0.00370914 0.000840019 0.0648 0.00145491 0.00120002 0.072 0.00207845 0.00192004 0.0792 0.00332552 0.00118795 0.0648 0.00118792 0.00169708 0.072 0.00169704 0.00271532 0.0792 0.00271526 0.00145493 0.0648 0.000839981 0.00207848 0.072 0.00119998 0.00332556 0.0792 0.00191996 0.00162276 0.0648 0.000434795 0.00231823 0.072 0.000621134 0.00370917 0.0792 0.000993816 0 0.07776 0 3 0 1 2 3 3 0 2 3 4 3 2 3 5 4 2 3 6 5 2 3 7 6 2 3 8 7 2 3 9 8 2 3 10 9 2 3 11 10 2 3 12 11 2 3 13 12 2 3 14 13 2 3 15 14 2 3 16 15 2 3 17 16 2 3 18 17 2 3 19 18 2 3 20 19 2 3 21 20 2 3 22 21 2 3 23 22 2 3 24 23 2 3 25 24 2 3 26 25 2 3 27 26 2 3 28 27 2 3 29 28 2 3 30 29 2 3 31 30 2 3 32 31 2 3 33 32 2 3 34 33 2 3 35 34 2 3 36 35 2 3 1 36 2 3 0 37 38 3 0 38 1 3 3 39 37 3 3 37 0 3 4 40 39 3 4 39 3 3 5 41 40 3 5 40 4 3 6 42 41 3 6 41 5 3 7 43 42 3 7 42 6 3 8 44 43 3 8 43 7 3 9 45 44 3 9 44 8 3 10 46 45 3 10 45 9 3 11 47 46 3 11 46 10 3 12 48 47 3 12 47 11 3 13 49 48 3 13 48 12 3 14 50 49 3 14 49 13 3 15 51 50 3 15 50 14 3 16 52 51 3 16 51 15 3 17 53 52 3 17 52 16 3 18 54 53 3 18 53 17 3 19 55 54 3 19 54 18 3 20 56 55 3 20 55 19 3 21 57 56 3 21 56 20 3 22 58 57 3 22 57 21 3 23 59 58 3 23 58 22 3 24 60 59 3 24 59 23 3 25 61 60 3 25 60 24 3 26 62 61 3 26 61 25 3 27 63 62 3 27 62 26 3 28 64 63 3 28 63 27 3 29 65 64 3 29 64 28 3 30 66 65 3 30 65 29 3 31 67 66 3 31 66 30 3 32 68 67 3 32 67 31 3 33 69 68 3 33 68 32 3 34 70 69 3 34 69 33 3 35 71 70 3 35 70 34 3 36 72 71 3 36 71 35 3 1 38 72 3 1 72 36 3 37 73 74 3 37 74 38 3 39 75 73 3 39 73 37 3 40 76 75 3 40 75 39 3 41 77 76 3 41 76 40 3 42 78 77 3 42 77 41 3 43 79 78 3 43 78 42 3 44 80 79 3 44 79 43 3 45 81 80 3 45 80 44 3 46 82 81 3 46 81 45 3 47 83 82 3 47 82 46 3 48 84 83 3 48 83 47 3 49 85 84 3 49 84 48 3 50 86 85 3 50 85 49 3 51 87 86 3 51 86 50 3 52 88 87 3 52 87 51 3 53 89 88 3 53 88 52 3 54 90 89 3 54 89 53 3 55 91 90 3 55 90 54 3 56 92 91 3 56 91 55 3 57 93 92 3 57 92 56 3 58 94 93 3 58 93 57 3 59 95 94 3 59 94 58 3 60 96 95 3 60 95 59 3 61 97 96 3 61 96 60 3 62 98 97 3 62 97 61 3 63 99 98 3 63 98 62 3 64 100 99 3 64 99 63 3 65 101 100 3 65 100 64 3 66 102 101 3 66 101 65 3 67 103 102 3 67 102 66 3 68 104 103 3 68 103 67 3 69 105 104 3 69 104 68 3 70 106 105 3 70 105 69 3 71 107 106 3 71 106 70 3 72 108 107 3 72 107 71 3 38 74 108 3 38 108 72 3 73 109 110 3 73 110 74 3 75 111 109 3 75 109 73 3 76 112 111 3 76 111 75 3 77 113 112 3 77 112 76 3 78 114 113 3 78 113 77 3 79 115 114 3 79 114 78 3 80 116 115 3 80 115 79 3 81 117 116 3 81 116 80 3 82 118 117 3 82 117 81 3 83 119 118 3 83 118 82 3 84 120 119 3 84 119 83 3 85 121 120 3 85 120 84 3 86 122 121 3 86 121 85 3 87 123 122 3 87 122 86 3 88 124 123 3 88 123 87 3 89 125 124 3 89 124 88 3 90 126 125 3 90 125 89 3 91 127 126 3 91 126 90 3 92 128 127 3 92 127 91 3 93 129 128 3 93 128 92 3 94 130 129 3 94 129 93 3 95 131 130 3 95 130 94 3 96 132 131 3 96 131 95 3 97 133 132 3 97 132 96 3 98 134 133 3 98 133 97 3 99 135 134 3 99 134 98 3 100 136 135 3 100 135 99 3 101 137 136 3 101 136 100 3 102 138 137 3 102 137 101 3 103 139 138 3 103 138 102 3 104 140 139 3 104 139 103 3 105 141 140 3 105 140 104 3 106 142 141 3 106 141 105 3 107 143 142 3 107 142 106 3 108 144 143 3 108 143 107 3 74 110 144 3 74 144 108 3 109 145 146 3 109 146 110 3 111 147 145 3 111 145 109 3 112 148 147 3 112 147 111 3 113 149 148 3 113 148 112 3 114 150 149 3 114 149 113 3 115 151 150 3 115 150 114 3 116 152 151 3 116 151 115 3 117 153 152 3 117 152 116 3 118 154 153 3 118 153 117 3 119 155 154 3 119 154 118 3 120 156 155 3 120 155 119 3 121 157 156 3 121 156 120 3 122 158 157 3 122 157 121 3 123 159 158 3 123 158 122 3 124 160 159 3 124 159 123 3 125 161 160 3 125 160 124 3 126 162 161 3 126 161 125 3 127 163 162 3 127 162 126 3 128 164 163 3 128 163 127 3 129 165 164 3 129 164 128 3 130 166 165 3 130 165 129 3 131 167 166 3 131 166 130 3 132 168 167 3 132 167 131 3 133 169 168 3 133 168 132 3 134 170 169 3 134 169 133 3 135 171 170 3 135 170 134 3 136 172 171 3 136 171 135 3 137 173 172 3 137 172 136 3 138 174 173 3 138 173 137 3 139 175 174 3 139 174 138 3 140 176 175 3 140 175 139 3 141 177 176 3 141 176 140 3 142 178 177 3 142 177 141 3 143 179 178 3 143 178 142 3 144 180 179 3 144 179 143 3 110 146 180 3 110 180 144 3 145 181 182 3 145 182 146 3 147 183 181 3 147 181 145 3 148 184 183 3 148 183 147 3 149 185 184 3 149 184 148 3 150 186 185 3 150 185 149 3 151 187 186 3 151 186 150 3 152 188 187 3 152 187 151 3 153 189 188 3 153 188 152 3 154 190 189 3 154 189 153 3 155 191 190 3 155 190 154 3 156 192 191 3 156 191 155 3 157 193 192 3 157 192 156 3 158 194 193 3 158 193 157 3 159 195 194 3 159 194 158 3 160 196 195 3 160 195 159 3 161 197 196 3 161 196 160 3 162 198 197 3 162 197 161 3 163 199 198 3 163 198 162 3 164 200 199 3 164 199 163 3 165 201 200 3 165 200 164 3 166 202 201 3 166 201 165 3 167 203 202 3 167 202 166 3 168 204 203 3 168 203 167 3 169 205 204 3 169 204 168 3 170 206 205 3 170 205 169 3 171 207 206 3 171 206 170 3 172 208 207 3 172 207 171 3 173 209 208 3 173 208 172 3 174 210 209 3 174 209 173 3 175 211 210 3 175 210 174 3 176 212 211 3 176 211 175 3 177 213 212 3 177 212 176 3 178 214 213 3 178 213 177 3 179 215 214 3 179 214 178 3 180 216 215 3 180 215 179 3 146 182 216 3 146 216 180 3 181 217 218 3 181 218 182 3 183 219 217 3 183 217 181 3 184 220 219 3 184 219 183 3 185 221 220 3 185 220 184 3 186 222 221 3 186 221 185 3 187 223 222 3 187 222 186 3 188 224 223 3 188 223 187 3 189 225 224 3 189 224 188 3 190 226 225 3 190 225 189 3 191 227 226 3 191 226 190 3 192 228 227 3 192 227 191 3 193 229 228 3 193 228 192 3 194 230 229 3 194 229 193 3 195 231 230 3 195 230 194 3 196 232 231 3 196 231 195 3 197 233 232 3 197 232 196 3 198 234 233 3 198 233 197 3 199 235 234 3 199 234 198 3 200 236 235 3 200 235 199 3 201 237 236 3 201 236 200 3 202 238 237 3 202 237 201 3 203 239 238 3 203 238 202 3 204 240 239 3 204 239 203 3 205 241 240 3 205 240 204 3 206 242 241 3 206 241 205 3 207 243 242 3 207 242 206 3 208 244 243 3 208 243 207 3 209 245 244 3 209 244 208 3 210 246 245 3 210 245 209 3 211 247 246 3 211 246 210 3 212 248 247 3 212 247 211 3 213 249 248 3 213 248 212 3 214 250 249 3 214 249 213 3 215 251 250 3 215 250 214 3 216 252 251 3 216 251 215 3 182 218 252 3 182 252 216 3 217 253 254 3 217 254 218 3 219 255 253 3 219 253 217 3 220 256 255 3 220 255 219 3 221 257 256 3 221 256 220 3 222 258 257 3 222 257 221 3 223 259 258 3 223 258 222 3 224 260 259 3 224 259 223 3 225 261 260 3 225 260 224 3 226 262 261 3 226 261 225 3 227 263 262 3 227 262 226 3 228 264 263 3 228 263 227 3 229 265 264 3 229 264 228 3 230 266 265 3 230 265 229 3 231 267 266 3 231 266 230 3 232 268 267 3 232 267 231 3 233 269 268 3 233 268 232 3 234 270 269 3 234 269 233 3 235 271 270 3 235 270 234 3 236 272 271 3 236 271 235 3 237 273 272 3 237 272 236 3 238 274 273 3 238 273 237 3 239 275 274 3 239 274 238 3 240 276 275 3 240 275 239 3 241 277 276 3 241 276 240 3 242 278 277 3 242 277 241 3 243 279 278 3 243 278 242 3 244 280 279 3 244 279 243 3 245 281 280 3 245 280 244 3 246 282 281 3 246 281 245 3 247 283 282 3 247 282 246 3 248 284 283 3 248 283 247 3 249 285 284 3 249 284 248 3 250 286 285 3 250 285 249 3 251 287 286 3 251 286 250 3 252 288 287 3 252 287 251 3 218 254 288 3 218 288 252 3 253 289 290 3 253 290 254 3 255 291 289 3 255 289 253 3 256 292 291 3 256 291 255 3 257 293 292 3 257 292 256 3 258 294 293 3 258 293 257 3 259 295 294 3 259 294 258 3 260 296 295 3 260 295 259 3 261 297 296 3 261 296 260 3 262 298 297 3 262 297 261 3 263 299 298 3 263 298 262 3 264 300 299 3 264 299 263 3 265 301 300 3 265 300 264 3 266 302 301 3 266 301 265 3 267 303 302 3 267 302 266 3 268 304 303 3 268 303 267 3 269 305 304 3 269 304 268 3 270 306 305 3 270 305 269 3 271 307 306 3 271 306 270 3 272 308 307 3 272 307 271 3 273 309 308 3 273 308 272 3 274 310 309 3 274 309 273 3 275 311 310 3 275 310 274 3 276 312 311 3 276 311 275 3 277 313 312 3 277 312 276 3 278 314 313 3 278 313 277 3 279 315 314 3 279 314 278 3 280 316 315 3 280 315 279 3 281 317 316 3 281 316 280 3 282 318 317 3 282 317 281 3 283 319 318 3 283 318 282 3 284 320 319 3 284 319 283 3 285 321 320 3 285 320 284 3 286 322 321 3 286 321 285 3 287 323 322 3 287 322 286 3 288 324 323 3 288 323 287 3 254 290 324 3 254 324 288 3 289 325 326 3 289 326 290 3 291 327 325 3 291 325 289 3 292 328 327 3 292 327 291 3 293 329 328 3 293 328 292 3 294 330 329 3 294 329 293 3 295 331 330 3 295 330 294 3 296 332 331 3 296 331 295 3 297 333 332 3 297 332 296 3 298 334 333 3 298 333 297 3 299 335 334 3 299 334 298 3 300 336 335 3 300 335 299 3 301 337 336 3 301 336 300 3 302 338 337 3 302 337 301 3 303 339 338 3 303 338 302 3 304 340 339 3 304 339 303 3 305 341 340 3 305 340 304 3 306 342 341 3 306 341 305 3 307 343 342 3 307 342 306 3 308 344 343 3 308 343 307 3 309 345 344 3 309 344 308 3 310 346 345 3 310 345 309 3 311 347 346 3 311 346 310 3 312 348 347 3 312 347 311 3 313 349 348 3 313 348 312 3 314 350 349 3 314 349 313 3 315 351 350 3 315 350 314 3 316 352 351 3 316 351 315 3 317 353 352 3 317 352 316 3 318 354 353 3 318 353 317 3 319 355 354 3 319 354 318 3 320 356 355 3 320 355 319 3 321 357 356 3 321 356 320 3 322 358 357 3 322 357 321 3 323 359 358 3 323 358 322 3 324 360 359 3 324 359 323 3 290 326 360 3 290 360 324 3 325 361 362 3 325 362 326 3 327 363 361 3 327 361 325 3 328 364 363 3 328 363 327 3 329 365 364 3 329 364 328 3 330 366 365 3 330 365 329 3 331 367 366 3 331 366 330 3 332 368 367 3 332 367 331 3 333 369 368 3 333 368 332 3 334 370 369 3 334 369 333 3 335 371 370 3 335 370 334 3 336 372 371 3 336 371 335 3 337 373 372 3 337 372 336 3 338 374 373 3 338 373 337 3 339 375 374 3 339 374 338 3 340 376 375 3 340 375 339 3 341 377 376 3 341 376 340 3 342 378 377 3 342 377 341 3 343 379 378 3 343 378 342 3 344 380 379 3 344 379 343 3 345 381 380 3 345 380 344 3 346 382 381 3 346 381 345 3 347 383 382 3 347 382 346 3 348 384 383 3 348 383 347 3 349 385 384 3 349 384 348 3 350 386 385 3 350 385 349 3 351 387 386 3 351 386 350 3 352 388 387 3 352 387 351 3 353 389 388 3 353 388 352 3 354 390 389 3 354 389 353 3 355 391 390 3 355 390 354 3 356 392 391 3 356 391 355 3 357 393 392 3 357 392 356 3 358 394 393 3 358 393 357 3 359 395 394 3 359 394 358 3 360 396 395 3 360 395 359 3 326 362 396 3 326 396 360 3 361 397 398 3 361 398 362 3 363 399 397 3 363 397 361 3 364 400 399 3 364 399 363 3 365 401 400 3 365 400 364 3 366 402 401 3 366 401 365 3 367 403 402 3 367 402 366 3 368 404 403 3 368 403 367 3 369 405 404 3 369 404 368 3 370 406 405 3 370 405 369 3 371 407 406 3 371 406 370 3 372 408 407 3 372 407 371 3 373 409 408 3 373 408 372 3 374 410 409 3 374 409 373 3 375 411 410 3 375 410 374 3 376 412 411 3 376 411 375 3 377 413 412 3 377 412 376 3 378 414 413 3 378 413 377 3 379 415 414 3 379 414 378 3 380 416 415 3 380 415 379 3 381 417 416 3 381 416 380 3 382 418 417 3 382 417 381 3 383 419 418 3 383 418 382 3 384 420 419 3 384 419 383 3 385 421 420 3 385 420 384 3 386 422 421 3 386 421 385 3 387 423 422 3 387 422 386 3 388 424 423 3 388 423 387 3 389 425 424 3 389 424 388 3 390 426 425 3 390 425 389 3 391 427 426 3 391 426 390 3 392 428 427 3 392 427 391 3 393 429 428 3 393 428 392 3 394 430 429 3 394 429 393 3 395 431 430 3 395 430 394 3 396 432 431 3 396 431 395 3 362 398 432 3 362 432 396 3 397 433 434 3 397 434 398 3 399 435 433 3 399 433 397 3 400 436 435 3 400 435 399 3 401 437 436 3 401 436 400 3 402 438 437 3 402 437 401 3 403 439 438 3 403 438 402 3 404 440 439 3 404 439 403 3 405 441 440 3 405 440 404 3 406 442 441 3 406 441 405 3 407 443 442 3 407 442 406 3 408 444 443 3 408 443 407 3 409 445 444 3 409 444 408 3 410 446 445 3 410 445 409 3 411 447 446 3 411 446 410 3 412 448 447 3 412 447 411 3 413 449 448 3 413 448 412 3 414 450 449 3 414 449 413 3 415 451 450 3 415 450 414 3 416 452 451 3 416 451 415 3 417 453 452 3 417 452 416 3 418 454 453 3 418 453 417 3 419 455 454 3 419 454 418 3 420 456 455 3 420 455 419 3 421 457 456 3 421 456 420 3 422 458 457 3 422 457 421 3 423 459 458 3 423 458 422 3 424 460 459 3 424 459 423 3 425 461 460 3 425 460 424 3 426 462 461 3 426 461 425 3 427 463 462 3 427 462 426 3 428 464 463 3 428 463 427 3 429 465 464 3 429 464 428 3 430 466 465 3 430 465 429 3 431 467 466 3 431 466 430 3 432 468 467 3 432 467 431 3 398 434 468 3 398 468 432 3 433 469 470 3 433 470 434 3 435 471 469 3 435 469 433 3 436 472 471 3 436 471 435 3 437 473 472 3 437 472 436 3 438 474 473 3 438 473 437 3 439 475 474 3 439 474 438 3 440 476 475 3 440 475 439 3 441 477 476 3 441 476 440 3 442 478 477 3 442 477 441 3 443 479 478 3 443 478 442 3 444 480 479 3 444 479 443 3 445 481 480 3 445 480 444 3 446 482 481 3 446 481 445 3 447 483 482 3 447 482 446 3 448 484 483 3 448 483 447 3 449 485 484 3 449 484 448 3 450 486 485 3 450 485 449 3 451 487 486 3 451 486 450 3 452 488 487 3 452 487 451 3 453 489 488 3 453 488 452 3 454 490 489 3 454 489 453 3 455 491 490 3 455 490 454 3 456 492 491 3 456 491 455 3 457 493 492 3 457 492 456 3 458 494 493 3 458 493 457 3 459 495 494 3 459 494 458 3 460 496 495 3 460 495 459 3 461 497 496 3 461 496 460 3 462 498 497 3 462 497 461 3 463 499 498 3 463 498 462 3 464 500 499 3 464 499 463 3 465 501 500 3 465 500 464 3 466 502 501 3 466 501 465 3 467 503 502 3 467 502 466 3 468 504 503 3 468 503 467 3 434 470 504 3 434 504 468 3 469 505 506 3 469 506 470 3 471 507 505 3 471 505 469 3 472 508 507 3 472 507 471 3 473 509 508 3 473 508 472 3 474 510 509 3 474 509 473 3 475 511 510 3 475 510 474 3 476 512 511 3 476 511 475 3 477 513 512 3 477 512 476 3 478 514 513 3 478 513 477 3 479 515 514 3 479 514 478 3 480 516 515 3 480 515 479 3 481 517 516 3 481 516 480 3 482 518 517 3 482 517 481 3 483 519 518 3 483 518 482 3 484 520 519 3 484 519 483 3 485 521 520 3 485 520 484 3 486 522 521 3 486 521 485 3 487 523 522 3 487 522 486 3 488 524 523 3 488 523 487 3 489 525 524 3 489 524 488 3 490 526 525 3 490 525 489 3 491 527 526 3 491 526 490 3 492 528 527 3 492 527 491 3 493 529 528 3 493 528 492 3 494 530 529 3 494 529 493 3 495 531 530 3 495 530 494 3 496 532 531 3 496 531 495 3 497 533 532 3 497 532 496 3 498 534 533 3 498 533 497 3 499 535 534 3 499 534 498 3 500 536 535 3 500 535 499 3 501 537 536 3 501 536 500 3 502 538 537 3 502 537 501 3 503 539 538 3 503 538 502 3 504 540 539 3 504 539 503 3 470 506 540 3 470 540 504 3 505 541 542 3 505 542 506 3 507 543 541 3 507 541 505 3 508 544 543 3 508 543 507 3 509 545 544 3 509 544 508 3 510 546 545 3 510 545 509 3 511 547 546 3 511 546 510 3 512 548 547 3 512 547 511 3 513 549 548 3 513 548 512 3 514 550 549 3 514 549 513 3 515 551 550 3 515 550 514 3 516 552 551 3 516 551 515 3 517 553 552 3 517 552 516 3 518 554 553 3 518 553 517 3 519 555 554 3 519 554 518 3 520 556 555 3 520 555 519 3 521 557 556 3 521 556 520 3 522 558 557 3 522 557 521 3 523 559 558 3 523 558 522 3 524 560 559 3 524 559 523 3 525 561 560 3 525 560 524 3 526 562 561 3 526 561 525 3 527 563 562 3 527 562 526 3 528 564 563 3 528 563 527 3 529 565 564 3 529 564 528 3 530 566 565 3 530 565 529 3 531 567 566 3 531 566 530 3 532 568 567 3 532 567 531 3 533 569 568 3 533 568 532 3 534 570 569 3 534 569 533 3 535 571 570 3 535 570 534 3 536 572 571 3 536 571 535 3 537 573 572 3 537 572 536 3 538 574 573 3 538 573 537 3 539 575 574 3 539 574 538 3 540 576 575 3 540 575 539 3 506 542 576 3 506 576 540 3 541 577 578 3 541 578 542 3 543 579 577 3 543 577 541 3 544 580 579 3 544 579 543 3 545 581 580 3 545 580 544 3 546 582 581 3 546 581 545 3 547 583 582 3 547 582 546 3 548 584 583 3 548 583 547 3 549 585 584 3 549 584 548 3 550 586 585 3 550 585 549 3 551 587 586 3 551 586 550 3 552 588 587 3 552 587 551 3 553 589 588 3 553 588 552 3 554 590 589 3 554 589 553 3 555 591 590 3 555 590 554 3 556 592 591 3 556 591 555 3 557 593 592 3 557 592 556 3 558 594 593 3 558 593 557 3 559 595 594 3 559 594 558 3 560 596 595 3 560 595 559 3 561 597 596 3 561 596 560 3 562 598 597 3 562 597 561 3 563 599 598 3 563 598 562 3 564 600 599 3 564 599 563 3 565 601 600 3 565 600 564 3 566 602 601 3 566 601 565 3 567 603 602 3 567 602 566 3 568 604 603 3 568 603 567 3 569 605 604 3 569 604 568 3 570 606 605 3 570 605 569 3 571 607 606 3 571 606 570 3 572 608 607 3 572 607 571 3 573 609 608 3 573 608 572 3 574 610 609 3 574 609 573 3 575 611 610 3 575 610 574 3 576 612 611 3 576 611 575 3 542 578 612 3 542 612 576 3 577 613 614 3 577 614 578 3 579 615 613 3 579 613 577 3 580 616 615 3 580 615 579 3 581 617 616 3 581 616 580 3 582 618 617 3 582 617 581 3 583 619 618 3 583 618 582 3 584 620 619 3 584 619 583 3 585 621 620 3 585 620 584 3 586 622 621 3 586 621 585 3 587 623 622 3 587 622 586 3 588 624 623 3 588 623 587 3 589 625 624 3 589 624 588 3 590 626 625 3 590 625 589 3 591 627 626 3 591 626 590 3 592 628 627 3 592 627 591 3 593 629 628 3 593 628 592 3 594 630 629 3 594 629 593 3 595 631 630 3 595 630 594 3 596 632 631 3 596 631 595 3 597 633 632 3 597 632 596 3 598 634 633 3 598 633 597 3 599 635 634 3 599 634 598 3 600 636 635 3 600 635 599 3 601 637 636 3 601 636 600 3 602 638 637 3 602 637 601 3 603 639 638 3 603 638 602 3 604 640 639 3 604 639 603 3 605 641 640 3 605 640 604 3 606 642 641 3 606 641 605 3 607 643 642 3 607 642 606 3 608 644 643 3 608 643 607 3 609 645 644 3 609 644 608 3 610 646 645 3 610 645 609 3 611 647 646 3 611 646 610 3 612 648 647 3 612 647 611 3 578 614 648 3 578 648 612 3 613 649 650 3 613 650 614 3 615 651 649 3 615 649 613 3 616 652 651 3 616 651 615 3 617 653 652 3 617 652 616 3 618 654 653 3 618 653 617 3 619 655 654 3 619 654 618 3 620 656 655 3 620 655 619 3 621 657 656 3 621 656 620 3 622 658 657 3 622 657 621 3 623 659 658 3 623 658 622 3 624 660 659 3 624 659 623 3 625 661 660 3 625 660 624 3 626 662 661 3 626 661 625 3 627 663 662 3 627 662 626 3 628 664 663 3 628 663 627 3 629 665 664 3 629 664 628 3 630 666 665 3 630 665 629 3 631 667 666 3 631 666 630 3 632 668 667 3 632 667 631 3 633 669 668 3 633 668 632 3 634 670 669 3 634 669 633 3 635 671 670 3 635 670 634 3 636 672 671 3 636 671 635 3 637 673 672 3 637 672 636 3 638 674 673 3 638 673 637 3 639 675 674 3 639 674 638 3 640 676 675 3 640 675 639 3 641 677 676 3 641 676 640 3 642 678 677 3 642 677 641 3 643 679 678 3 643 678 642 3 644 680 679 3 644 679 643 3 645 681 680 3 645 680 644 3 646 682 681 3 646 681 645 3 647 683 682 3 647 682 646 3 648 684 683 3 648 683 647 3 614 650 684 3 614 684 648 3 649 685 686 3 649 686 650 3 651 687 685 3 651 685 649 3 652 688 687 3 652 687 651 3 653 689 688 3 653 688 652 3 654 690 689 3 654 689 653 3 655 691 690 3 655 690 654 3 656 692 691 3 656 691 655 3 657 693 692 3 657 692 656 3 658 694 693 3 658 693 657 3 659 695 694 3 659 694 658 3 660 696 695 3 660 695 659 3 661 697 696 3 661 696 660 3 662 698 697 3 662 697 661 3 663 699 698 3 663 698 662 3 664 700 699 3 664 699 663 3 665 701 700 3 665 700 664 3 666 702 701 3 666 701 665 3 667 703 702 3 667 702 666 3 668 704 703 3 668 703 667 3 669 705 704 3 669 704 668 3 670 706 705 3 670 705 669 3 671 707 706 3 671 706 670 3 672 708 707 3 672 707 671 3 673 709 708 3 673 708 672 3 674 710 709 3 674 709 673 3 675 711 710 3 675 710 674 3 676 712 711 3 676 711 675 3 677 713 712 3 677 712 676 3 678 714 713 3 678 713 677 3 679 715 714 3 679 714 678 3 680 716 715 3 680 715 679 3 681 717 716 3 681 716 680 3 682 718 717 3 682 717 681 3 683 719 718 3 683 718 682 3 684 720 719 3 684 719 683 3 650 686 720 3 650 720 684 3 685 721 722 3 685 722 686 3 687 723 721 3 687 721 685 3 688 724 723 3 688 723 687 3 689 725 724 3 689 724 688 3 690 726 725 3 690 725 689 3 691 727 726 3 691 726 690 3 692 728 727 3 692 727 691 3 693 729 728 3 693 728 692 3 694 730 729 3 694 729 693 3 695 731 730 3 695 730 694 3 696 732 731 3 696 731 695 3 697 733 732 3 697 732 696 3 698 734 733 3 698 733 697 3 699 735 734 3 699 734 698 3 700 736 735 3 700 735 699 3 701 737 736 3 701 736 700 3 702 738 737 3 702 737 701 3 703 739 738 3 703 738 702 3 704 740 739 3 704 739 703 3 705 741 740 3 705 740 704 3 706 742 741 3 706 741 705 3 707 743 742 3 707 742 706 3 708 744 743 3 708 743 707 3 709 745 744 3 709 744 708 3 710 746 745 3 710 745 709 3 711 747 746 3 711 746 710 3 712 748 747 3 712 747 711 3 713 749 748 3 713 748 712 3 714 750 749 3 714 749 713 3 715 751 750 3 715 750 714 3 716 752 751 3 716 751 715 3 717 753 752 3 717 752 716 3 718 754 753 3 718 753 717 3 719 755 754 3 719 754 718 3 720 756 755 3 720 755 719 3 686 722 756 3 686 756 720 3 721 757 758 3 721 758 722 3 723 759 757 3 723 757 721 3 724 760 759 3 724 759 723 3 725 761 760 3 725 760 724 3 726 762 761 3 726 761 725 3 727 763 762 3 727 762 726 3 728 764 763 3 728 763 727 3 729 765 764 3 729 764 728 3 730 766 765 3 730 765 729 3 731 767 766 3 731 766 730 3 732 768 767 3 732 767 731 3 733 769 768 3 733 768 732 3 734 770 769 3 734 769 733 3 735 771 770 3 735 770 734 3 736 772 771 3 736 771 735 3 737 773 772 3 737 772 736 3 738 774 773 3 738 773 737 3 739 775 774 3 739 774 738 3 740 776 775 3 740 775 739 3 741 777 776 3 741 776 740 3 742 778 777 3 742 777 741 3 743 779 778 3 743 778 742 3 744 780 779 3 744 779 743 3 745 781 780 3 745 780 744 3 746 782 781 3 746 781 745 3 747 783 782 3 747 782 746 3 748 784 783 3 748 783 747 3 749 785 784 3 749 784 748 3 750 786 785 3 750 785 749 3 751 787 786 3 751 786 750 3 752 788 787 3 752 787 751 3 753 789 788 3 753 788 752 3 754 790 789 3 754 789 753 3 755 791 790 3 755 790 754 3 756 792 791 3 756 791 755 3 722 758 792 3 722 792 756 3 757 793 758 3 759 793 757 3 760 793 759 3 761 793 760 3 762 793 761 3 763 793 762 3 764 793 763 3 765 793 764 3 766 793 765 3 767 793 766 3 768 793 767 3 769 793 768 3 770 793 769 3 771 793 770 3 772 793 771 3 773 793 772 3 774 793 773 3 775 793 774 3 776 793 775 3 777 793 776 3 778 793 777 3 779 793 778 3 780 793 779 3 781 793 780 3 782 793 781 3 783 793 782 3 784 793 783 3 785 793 784 3 786 793 785 3 787 793 786 3 788 793 787 3 789 793 788 3 790 793 789 3 791 793 790 3 792 793 791 3 758 793 792 3 794 795 796 3 794 796 797 3 795 798 799 3 795 799 796 3 800 801 795 3 800 795 794 3 801 802 798 3 801 798 795 3 803 804 801 3 803 801 800 3 804 805 802 3 804 802 801 3 806 807 804 3 806 804 803 3 807 808 805 3 807 805 804 3 809 810 807 3 809 807 806 3 810 811 808 3 810 808 807 3 812 813 810 3 812 810 809 3 813 814 811 3 813 811 810 3 815 816 813 3 815 813 812 3 816 817 814 3 816 814 813 3 818 819 816 3 818 816 815 3 819 820 817 3 819 817 816 3 821 822 819 3 821 819 818 3 822 823 820 3 822 820 819 3 824 825 822 3 824 822 821 3 825 826 823 3 825 823 822 3 827 828 825 3 827 825 824 3 828 829 826 3 828 826 825 3 830 831 828 3 830 828 827 3 831 832 829 3 831 829 828 3 833 834 831 3 833 831 830 3 834 835 832 3 834 832 831 3 836 837 834 3 836 834 833 3 837 838 835 3 837 835 834 3 839 840 837 3 839 837 836 3 840 841 838 3 840 838 837 3 842 843 840 3 842 840 839 3 843 844 841 3 843 841 840 3 845 846 843 3 845 843 842 3 846 847 844 3 846 844 843 3 848 849 846 3 848 846 845 3 849 850 847 3 849 847 846 3 851 852 849 3 851 849 848 3 852 853 850 3 852 850 849 3 854 855 852 3 854 852 851 3 855 856 853 3 855 853 852 3 857 858 855 3 857 855 854 3 858 859 856 3 858 856 855 3 860 861 858 3 860 858 857 3 861 862 859 3 861 859 858 3 863 864 861 3 863 861 860 3 864 865 862 3 864 862 861 3 797 796 864 3 797 864 863 3 796 799 865 3 796 865 864 3 866 799 798 3 866 798 802 3 866 802 805 3 866 805 808 3 866 808 811 3 866 811 814 3 866 814 817 3 866 817 820 3 866 820 823 3 866 823 826 3 866 826 829 3 866 829 832 3 866 832 835 3 866 835 838 3 866 838 841 3 866 841 844 3 866 844 847 3 866 847 850 3 866 850 853 3 866 853 856 3 866 856 859 3 866 859 862 3 866 862 865 3 866 865 799 matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFaceNumber.m0000644000000000000000000000013214576357161017776 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFaceNumber.m0000644000175000017500000000474314576357161021566 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function nFaces = meshFaceNumber(varargin) %MESHFACENUMBER Returns the number of faces in this mesh. % % NF = meshFaceNumber(V, F) % NF = meshFaceNumber(V, E, F) % NF = meshFaceNumber(MESH) % Returns the number of faces in the given mesh. As the face array may be % represented either as numeric array or as cell array of indices, this % function is a convenient way to get the number of faces independanlty % of the mesh representation. % % Example % [v f] = createCube; % meshFaceNumber(v, f) % ans = % 6 % % See also % meshes3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2013-08-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2013-2023 INRA - Cepia Software Platform [vertices, faces] = parseMeshData(varargin{:}); %#ok if iscell(faces) nFaces = length(faces); else nFaces = size(faces, 1); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/isPointInMesh.m0000644000000000000000000000013214576357161017643 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/isPointInMesh.m0000644000175000017500000000571214576357161021430 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = isPointInMesh(point, v, f, varargin) %ISPOINTINMESH Check if a point is inside a 3D mesh. % % B = isPointInMesh(PT, V, F) % Check if the point PT (given as a 1-by-3 array) is inside the mesh % defined by the vertices V and the face array F. The result is a % boolean. % % If PT is a N-by-3 point array, the result is a N-by-1 array of logical. % % Example % [v, f] = torusMesh([50 50 50 30 10 30 45]); % [x, y, z] = meshgrid(5:5:100, 5:5:100, 5:5:100); % res = false(size(x)); % res(:) = isPointInMesh([x(:) y(:) z(:)], v, f); % figure; plot3(x(res), y(res), z(res), 'b.'); axis equal; % % Algorithm: % The method computes the intersection with a ray starting from the % point(s) and with a random orientation. Some errors are possible if % rays crosses the mesh between two or three faces. % % See also % meshes3d, intersectLineMesh3d % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-01-26, using Matlab 9.3.0.713579 (R2017b) % Copyright 2018-2023 INRA - Cepia Software Platform % choose a random vector vect = rand(1, 3); % initialize array for result np = size(point, 1); res = false(np, 1); % iterate over the various points for i = 1:np % disp(i); line = createLine3d(point(i,:), vect); [inters, pos] = intersectLineMesh3d(line, v, f); %#ok res(i) = mod(sum(pos > 0), 2) > 0; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/bunny_F1k.ply0000644000000000000000000000013214576357160017315 xustar0030 mtime=1710874224.670193794 30 atime=1710874224.670193794 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/bunny_F1k.ply0000644000175000017500000012665114576357160021110 0ustar00juanpijuanpi00000000000000ply format ascii 1.0 comment Created by MatGeom for MATLAB element vertex 502 property double x property double y property double z element face 1000 property list int int vertex_index end_header -3.48539883366533898 7.00777557509960225 7.89424713147410273 -3.82133883366533844 6.92186557509960210 8.37174713147410188 -3.74748883366533825 6.80100557509960169 6.93464713147410272 -4.13364883366533942 6.25341557509960211 7.22994713147410195 -4.55052883366533933 6.39433557509960249 8.36264713147410177 -3.50781883366533798 6.35997557509960210 7.82014713147410312 -3.84419883366533810 6.40576557509960232 6.36294713147410285 -4.17350883366533854 6.11248557509960211 6.31334713147410387 -3.90799883366533818 6.50694557509960170 8.50734713147410204 -3.44894883366533822 6.71904557509960121 7.13894713147410176 -4.28755883366533741 6.52534557509960145 8.63414713147410140 -3.53830883366533788 4.98749557509960173 7.06664713147410239 -4.62154883366533831 4.85644557509960251 6.94874713147410361 -5.03705883366533769 5.67207557509960125 7.97244713147410344 -4.30301883366533833 5.26317557509960210 5.63244713147410270 -3.94156883366533917 5.42799557509960184 5.79604713147410244 -4.49229883366533844 4.66518557509960186 7.86104713147410283 -4.72520883366533795 5.90191557509960152 8.46684713147410406 -4.51966883366533878 4.94130557509960155 5.67094713147410268 -3.88523883366533873 4.42017557509960124 7.43254713147410140 -3.54599883366533852 4.95566557509960237 6.40584713147410145 -5.13826883366533771 4.43157557509960132 7.23044713147410167 0.20145116633466104 4.67048557509960194 -1.64102286852589740 1.12876116633466128 4.78455557509960094 -1.97562286852589741 0.24032116633466127 4.57062557509960143 -0.82600286852589777 0.97274116633466123 4.81202557509960194 -0.99572286852589731 2.33603916633466113 4.63537557509960152 -1.03213286852589792 1.38295116633466120 4.54308557509960220 -0.30331286852589706 -3.93509883366533897 3.08034557509960161 5.14514713147410063 0.38725116633466122 4.48370557509960133 -2.69597286852589768 1.17060116633466116 4.67016557509960251 -2.88072286852589787 3.56375016633466135 4.23635557509960137 -2.15147286852589703 3.33422516633466115 4.19222557509960225 -0.52962286852589746 -4.54932883366533769 3.00935557509960150 5.20024713147410367 1.46248116633466108 4.36206557509960202 -3.82421286852589759 2.87425216633466096 4.30461557509960180 -3.14713286852589835 2.41140916633466107 4.43447557509960166 -2.54688286852589751 3.58162116633466132 4.05313557509960187 -3.05743286852589735 -0.39270883366533882 4.10415557509960216 -1.64404286852589809 0.42477116633466117 4.24021557509960090 -0.19555286852589726 2.53868516633466124 4.09215557509960171 0.09277713147410188 0.86610116633466094 3.72298557509960215 -4.94077286852589825 3.06689916633466142 3.94719557509960195 -4.27711286852589812 4.02908116633466129 4.00229557509960188 -1.61552286852589821 -5.07410883366533927 5.22552557509960192 7.93594713147410236 -1.23206883366533848 3.82194557509960164 -5.96807286852589769 -0.60740883366533871 3.88094557509960225 -5.30626286852589768 1.00296116633466115 3.68110557509960179 -5.58454286852589732 1.87049316633466112 3.56449557509960213 -5.16394286852589790 4.05916116633466117 3.88704557509960136 -0.45650286852589733 1.05200116633466134 3.40172557509960205 0.44172713147410253 2.17525616633466123 3.36437557509960117 0.55704713147410190 -3.57238883366533821 2.49511557509960191 5.29694713147410301 -3.44139883366533939 3.35079557509960235 6.29564713147410249 -5.06728883366533811 3.38748557509960158 6.66574713147410325 -4.17025883366533812 2.82250557509960176 7.05804713147410201 -1.68519883366533874 3.57392557509960129 -6.05595286852589787 -0.50487883366533881 3.90354557509960198 -6.01072286852589777 -1.28414883366533883 3.12712557509960121 -4.95849286852589710 4.62209116633466088 3.67553557509960172 -3.70602286852589735 -0.22365883366533867 3.53330557509960164 -3.09503286852589721 5.19687116633466140 3.38456557509960199 -1.29521286852589812 -4.90206883366533752 2.43195557509960159 5.97974713147410331 1.35294116633466110 3.65563557509960146 8.89014713147410163 1.25504116633466101 3.28721557509960149 9.02094713147410232 0.73352116633466113 3.00209557509960190 -6.05403286852589773 1.91125416633466116 3.30290557509960170 -6.02327286852589694 0.24336116633466126 3.63391557509960128 -4.69873286852589800 -0.23791883366533900 3.06721557509960174 -4.41243286852589822 4.61105116633466050 3.36509557509960189 -4.46615286852589755 5.32593116633466135 3.06208557509960189 -4.12146286852589760 5.66837116633466120 2.94424557509960172 -3.18542286852589740 -0.58912883366533908 3.53603557509960176 -1.02031286852589798 4.65102116633466078 3.14445557509960150 0.47338713147410255 4.08946116633466072 3.31965557509960174 0.19061713147410231 -4.88229883366533812 2.01925557509960152 5.57494713147410348 1.81874916633466133 3.46290557509960228 7.85194713147410184 4.26685116633466155 3.17017557509960124 -5.32123286852589761 3.54432516633466088 3.54039557509960146 -4.83185286852589702 4.92145116633466184 3.63084557509960204 -2.48187286852589750 -0.13456883366533867 3.42698557509960189 -0.04851286852589759 5.43866116633466135 3.02028557509960160 -0.22517286852589830 1.61513116633466125 3.82776557509960158 8.24834713147410170 0.83814116633466118 3.11661557509960163 9.06474713147410149 4.00831116633466156 2.83098557509960180 -5.98293286852589734 -2.79747883366533889 3.10855557509960168 -0.21809286852589732 -1.48769883366533895 3.11050557509960202 -0.66751286852589775 -1.61231883366533868 3.10167557509960190 0.26370713147410296 -0.27980883366533899 3.14582557509960203 0.95184713147410260 3.57544616633466150 3.02855557509960160 0.84354713147410254 0.62998116633466128 2.97003557509960148 1.52544713147410160 1.88834616633466101 2.57944557509960148 2.09714713147410148 2.45836016633466103 2.99121557509960168 1.69734713147410288 1.44516116633466107 2.68150557509960175 7.53964713147410315 -0.04362883366533891 2.77480557509960146 -5.78883286852589762 4.52086116633466073 2.76079557509960205 -5.61629286852589793 -1.51676883366533888 2.20457557509960145 -4.81844286852589754 5.12898116633466117 2.66597557509960170 -4.82268286852589778 5.88833116633466069 2.84830557509960203 -1.90135286852589758 -2.76395883366533868 3.04773557509960158 -1.36401286852589765 -2.85690883366533876 2.85345557509960202 0.89764713147410247 -1.56249883366533893 2.87254557509960140 1.31384713147410226 -0.08634883366533883 2.67684557509960186 1.71804713147410282 1.67098116633466121 3.12157557509960171 7.27434713147410150 0.97951116633466129 2.79396557509960175 8.92294713147410157 0.75280116633466110 2.72183557509960172 9.16874713147410247 -1.17063883366533883 2.53303557509960164 -6.05363286852589777 3.08156616633466118 2.56659557509960168 -6.00350286852589754 3.94092116633466150 1.95744557509960204 -6.00678286852589771 5.86802116633466131 2.33266557509960171 -3.96484286852589740 -0.72239883366533897 2.50521557509960191 -2.86476286852589812 -3.68427883366533848 2.60498557509960182 -1.93528286852589781 6.33223116633466088 2.60184557509960168 -1.13395286852589772 -3.59365883366533900 2.84268557509960162 -1.14099286852589743 -3.61300883366533920 2.72832557509960161 0.14048713147410269 5.42144116633466133 2.38317557509960176 1.16394713147410234 4.04098116633466109 2.68634557509960148 1.76014713147410173 -4.73269883366533861 2.38006557509960182 6.78104713147410187 -2.34562883366533859 1.98000557509960196 -6.10235286852589720 4.48070116633466053 2.10867557509960157 -5.94707286852589778 -0.60199883366533857 2.33183557509960160 -5.64811286852589767 1.70836116633466117 2.39052557509960151 -5.59714286852589815 6.56906116633466119 1.54395757509960174 -3.72982286852589784 -0.99605883366533887 2.88576557509960185 -1.73294286852589829 -2.63444883366533888 2.01016557509960192 -2.85090286852589792 -4.67126883366533896 2.41019557509960158 -1.01114286852589808 6.25635116633466204 2.32258557509960184 -0.09783286852589751 -3.71567883366533813 2.56743557509960185 0.96394713147410216 -0.95261883366533873 2.37144557509960174 2.20034713147410210 3.79707116633466102 2.37806557509960204 2.40754713147410282 0.32176116633466123 2.39122557509960165 6.72044713147410278 -0.31953883366533897 1.51821357509960175 7.12854713147410290 0.27059116633466118 1.91552657509960200 8.65924713147410152 -1.46711883366533913 2.14933557509960194 -3.51741286852589718 -1.86753883366533913 2.79136557509960159 -1.71874286852589786 6.77952116633466062 1.88393657509960200 -1.37380286852589739 -4.91416883366533863 2.19796557509960166 0.05974713147410271 -2.15393883366533867 2.35354557509960172 2.34214713147410247 1.29495116633466134 1.99655557509960180 2.62254713147410268 -0.42539883366533893 2.49766557509960174 7.08774713147410385 -3.89948883366533927 0.83415987509960177 6.00114713147410228 0.45042116633466112 3.03146557509960202 8.16844713147410140 -0.43921883366533876 1.50057457509960157 7.41814713147410121 -2.18466883366533837 2.28568557509960169 -5.95207286852589768 3.03764816633466106 1.93682557509960152 -5.57101286852589794 -0.48772883366533898 1.96836557509960164 -4.21106286852589751 5.44424116633466060 1.62245957509960159 -5.02766286852589772 -1.82314883366533853 2.44515557509960146 -2.72939286852589813 -3.90692883366533783 1.18290057509960178 -3.07825286852589786 -4.65302883366533848 1.68814257509960175 -2.18881286852589829 -5.67390883366533760 1.37871757509960169 -0.45025286852589802 6.86947116633466059 1.65940657509960166 -0.22931286852589799 6.26764116633466184 1.88938357509960198 0.87294713147410274 -3.13768883366533924 2.50171557509960163 1.73294713147410251 2.59004716633466137 1.94470557509960162 2.90784713147410212 4.30733116633466206 1.68192657509960197 2.82304713147410169 -3.83511883366533812 1.75418057509960157 4.64254713147410314 -3.51849883366533867 1.61092457509960174 5.40554713147410304 1.39769116633466117 2.38006557509960182 6.83304713147410148 -1.59261883366533907 1.89821957509960160 6.47614713147410281 -1.49774883366533862 1.27501157509960183 -6.06516286852589737 -2.11618883366533872 1.84483657509960164 -4.50215286852589802 -3.59751883366533898 1.86124457509960162 2.47334713147410179 5.05926116633466094 1.80487157509960161 2.27514713147410186 -0.30045883366533882 1.54894757509960179 2.78074713147410257 -0.98698883366533896 1.52875457509960189 3.03194713147410244 -1.55013883366533878 1.56133657509960178 5.73214713147410215 -3.86410883366533886 1.50745957509960182 -5.48099286852589795 -2.89008883366533897 1.54665857509960158 -4.92093286852589795 6.17083116633466133 1.63525257509960187 -4.26555286852589788 6.67253116633466092 1.97890557509960141 -2.53523286852589802 -5.27031883366533815 1.46902157509960185 -1.57153286852589757 -5.63161883366533900 1.31729357509960177 0.42678713147410174 5.96361116633466093 1.42051257509960172 1.79794713147410223 -4.88581883366533809 1.67649257509960159 3.10554713147410144 -2.38166883366533932 1.37710457509960182 3.35324713147410192 -3.66497883366533905 2.14273557509960177 6.19294713147410292 -2.65583883366533913 1.21365357509960181 5.80494713147410302 0.97338116633466121 1.69269257509960180 6.70604713147410259 -0.51885883366533903 1.23906757509960164 7.98454713147410100 -0.04383883366533871 1.85223657509960171 8.65054713147410048 -4.03180883366533838 1.49133357509960196 -5.95796286852589763 -0.50421883366533848 0.93679457509960185 -5.66267286852589713 7.45276116633466046 1.28968757509960175 -4.54415286852589784 -2.82475883366533864 1.16316957509960184 -4.19077286852589825 7.30286116633466076 1.47502957509960164 -3.78216286852589789 -4.65886883366533855 1.58620057509960177 1.97554713147410221 3.39635316633466111 1.50795057509960162 3.22354713147410266 -2.78987883366533884 1.18163657509960185 4.48434713147410324 -5.25334883366533845 1.45297057509960181 3.68784713147410326 -3.21190883366533875 1.14287457509960166 5.26704713147410342 -4.72682883366533879 1.60520257509960174 4.88614713147410296 -1.53206883366533875 1.75044357509960169 7.47444713147410145 -4.42292883366533918 0.86794457509960177 -5.95431286852589725 4.95351116633466049 0.96255987509960184 -5.93730286852589728 -3.18018883366533878 0.71629257509960176 -4.67875286852589767 7.88236116633466111 1.30337457509960175 -3.68461286852589787 6.98250116633466078 1.21064357509960185 -3.20544286852589710 7.40677116633466071 0.33488857509960174 -2.17977286852589769 7.16938116633466116 0.98993617509960175 -1.04079286852589714 -5.48279883366533838 0.91189727509960183 1.64024713147410273 -5.91095883366533936 1.09598957509960182 2.62264713147410244 1.57232116633466101 1.43369357509960182 3.12324713147410238 3.05896616633466101 0.75344257509960177 3.57514713147410168 -5.01774883366533775 1.23277457509960175 5.81044713147410263 -0.20880883366533876 1.52422957509960177 5.99704713147410384 -2.40929883366533870 0.83466287509960169 6.95534713147410155 4.16053116633466136 0.74966657509960177 -6.00938286852589787 2.66640296633466134 -1.28563442490039836 -5.61309286852589739 7.97279116633466156 0.94979877509960187 -2.89072286852589810 -5.72314883366533866 0.43321857509960177 -1.53538286852589745 -6.06107883366533873 0.35323357509960174 0.32346713147410194 6.81976116633466045 0.63018757509960177 0.94114713147410289 -5.47773883366533809 1.03973357509960174 4.50284713147410276 -1.40909883366533872 1.32369857509960176 5.49234713147410147 -0.19649883366533899 1.14254557509960186 6.04304713147410233 -3.26276883366533887 0.66570057509960179 6.05944713147410230 -2.32676883366533893 0.16353957509960176 -6.07046286852589745 2.33505416633466112 0.27671857509960174 -5.60528286852589730 -4.11025883366533851 0.72334257509960165 -5.13729286852589784 7.72245116633466111 0.54696357509960181 -4.90381286852589771 8.25280116633466143 0.63237257509960176 -4.18777286852589814 8.54107116633466212 0.58650557509960177 -3.50831286852589797 7.21061116633466170 0.21055057509960176 -0.04832286852589768 -5.83688883366533773 0.28233257509960180 1.50004713147410262 5.99491116633466170 0.53625057509960172 2.17684713147410225 -6.19593883366533937 0.47729157509960168 3.78154713147410293 -0.16665883366533893 0.38391157509960178 3.08814713147410336 -6.24596883366533895 -0.28754442490039822 5.33254713147410264 0.11819116633466110 1.04947457509960174 6.46664713147410097 -1.22484883366533914 0.64678657509960180 7.13384713147410210 -1.28403883366533900 1.24350157509960169 7.82104713147410102 -3.07048883366533909 -0.04007942490039818 -3.70779286852589784 -3.01969883366533898 1.08989657509960169 -3.52237286852589770 -4.80663883366533895 0.75201357509960176 -2.58187286852589715 -6.08858883366533821 0.23141757509960179 -0.66584286852589825 4.80771116633466100 0.81403857509960176 3.04464713147410126 -1.61201883366533893 0.09842557509960170 3.48884713147410164 -2.04576883366533924 0.17706057509960177 3.93904713147410224 -1.62585883366533857 0.48443957509960178 5.35234713147410268 -4.63894883366533772 0.56997657509960176 6.08354713147410120 -1.05288883366533903 0.47910457509960180 6.21314713147410291 -1.27130883366533864 0.64449957509960176 6.50224713147410061 3.16143216633466162 0.63788357509960170 -6.00323286852589799 5.21963116633466129 -0.01556242490039824 -6.01498286852589814 -2.79893883366533869 0.01250257509960179 -4.10215286852589767 -4.18356883366533783 0.12656157509960184 -3.27651286852589774 8.41670116633466137 0.03909157509960175 -2.35125286852589799 -6.51506883366533884 0.01360657509960183 2.84664713147410176 1.65560116633466103 0.60324657509960178 3.43644713147410208 2.55138316633466111 0.08348457509960178 3.64224713147410206 3.92830116633466142 0.66981957509960177 3.47114713147410336 -2.21023883366533891 0.57666257509960184 4.86194713147410340 -4.45750883366533834 0.17193657509960175 -5.69145286852589738 -2.33472883366533912 -0.95073442490039817 -6.13190286852589761 -0.45685883366533875 -0.30617442490039826 -6.07040286852589706 6.20444116633466081 -0.23515442490039828 -5.84870286852589771 6.58479116633466077 0.86358547509960171 -5.43292286852589790 7.59423116633466133 -0.00692742490039817 -5.13606286852589822 -3.80767883366533866 0.12147357509960169 -4.98148286852589806 8.52488116633466042 0.55365257509960175 -2.87669286852589723 -5.27244883366533834 0.19036257509960181 -2.27892286852589843 7.66574116633466041 -0.16430442490039820 -2.12883286852589837 -6.47871883366533829 -0.14201442490039823 2.15954713147410304 4.58833116633466087 -0.00673542490039827 3.28954713147410205 -5.99581883366533841 0.04039957509960179 4.66804713147410144 -1.14473883366533857 -0.35943442490039818 -5.86282286852589785 -2.60762883366533860 -0.78352442490039820 -4.94228286852589793 8.42664116633466165 -0.36910442490039835 -4.36850286852589775 8.77607116633465978 -0.22781442490039816 -3.52903286852589781 1.51332116633466107 -0.44311442490039821 3.50044713147410214 3.56561116633466124 -0.28760442490039817 3.66844713147410362 -2.33749883366533906 -0.40727442490039822 5.15384713147410167 4.27993116633466109 -0.37691442490039828 -5.65449286852589772 8.65907116633466067 -0.41534442490039836 -2.52213286852589746 -5.83125883366533859 -0.64880442490039825 -1.50166286852589792 6.59161116633466104 -0.51526442490039814 1.41534713147410263 -5.97246883366533865 -0.81259442490039835 1.42794713147410279 6.10273116633466106 -1.14881442490039820 2.02664713147410191 5.43235116633466131 -0.85540442490039803 2.74324713147410248 -6.15388883366533879 -0.50597442490039823 5.66454713147410160 -2.45030883366533869 -0.34734442490039830 5.83684713147410150 -5.33290883366533830 -0.84281442490039826 6.01974713147410156 -1.72366883366533896 0.50682057509960177 7.09744713147410256 2.86471516633466150 -0.70813442490039835 -5.99171286852589713 3.57555216633466122 -0.93446442490039838 -6.00313286852589734 -3.18628883366533922 -1.09475442490039843 -5.42239286852589775 -6.20282883366533877 -0.73310442490039829 0.36025713147410238 7.03816116633466127 -1.30921442490039830 0.12768713147410238 -6.42361883366533881 -0.77304442490039837 1.93354713147410173 -0.04179883366533868 -0.76911442490039805 3.07454713147410352 -1.22953883366533856 -2.19245442490039810 -6.02653286852589787 4.96950116633466088 -1.22026442490039821 -5.95907286852589735 -2.28693883366533868 -0.67675442490039805 -4.20229286852589734 -4.33834883366533841 -0.93529442490039827 -3.14875286852589742 7.38680116633466088 -1.05483442490039825 -2.22417286852589768 8.10846116633466174 -0.74817442490039832 -2.13199286852589776 -1.54559883366533857 -0.92234442490039814 3.29284713147410280 2.81872076633466140 -1.03797442490039837 3.62664713147410334 4.16225116633466108 -0.90582442490039838 3.44474713147410183 -6.35232883366533851 -0.82013442490039834 4.20114713147410335 6.28250116633466149 -1.26249442490039820 -5.61016286852589730 8.18278116633466190 -1.01927442490039843 -4.57468286852589756 -6.70255883366533833 -1.08076442490039826 2.86314713147410149 -6.54841883366533839 -0.53876442490039833 3.53544713147410095 -2.50399883366533871 -1.68282442490039830 4.39604713147410120 -2.92697883366533862 -0.13408442490039832 6.18474713147410249 -0.61184883366533871 -1.34710442490039828 -6.02452286852589758 3.83732116633466092 -1.83791442490039847 -5.96153286852589748 0.10911116633466125 -0.98668442490039832 -5.69850286852589782 7.49317116633466096 -1.37406442490039837 -4.97490286852589758 -2.62495883366533844 -1.20934442490039817 -3.74449286852589758 8.58219116633466150 -1.19929442490039828 -3.67935286852589716 -4.92404883366533852 -1.59761442490039807 -2.35688286852589757 8.54158116633466058 -1.08005442490039827 -2.63084286852589821 -2.68269883366533834 -1.62557442490039827 5.64564713147410213 -6.36599883366533881 -1.41640442490039820 5.33294713147410260 -2.48277883366533869 -1.98557442490039815 -4.36780286852589761 -3.69394883366533788 -2.30782442490039852 -2.77734286852589785 -5.67763883366533850 -1.37674442490039817 -1.39049286852589704 -6.16564883366533856 -1.06438442490039842 -0.42304286852589829 -6.26032883366533799 -1.91506442490039830 2.08804713147410226 -0.00116883366533885 -1.95094442490039821 2.51634713147410194 3.49274116633466125 -1.59969442490039837 3.44714713147410157 -0.36352883366533895 -2.25694442490039826 -5.67205286852589730 -2.50248883366533903 -1.63914442490039813 -4.26056286852589761 8.10710116633466171 -1.76359442490039808 -3.96402286852589736 7.99827116633466151 -1.54736442490039816 -2.56479286852589761 7.06073116633466036 -1.73479442490039815 -0.89430286852589802 -6.52312883366533836 -2.08442442490039825 2.83864713147410219 -1.09334883366533875 -1.73676442490039817 2.81974713147410272 4.52432116633466119 -1.79138442490039829 3.02784713147410267 -6.29583883366533925 -3.06919442490039796 3.64354713147410347 -1.83529883366533908 -1.79577442490039818 2.72724713147410158 2.02769516633466118 -1.61937442490039829 3.43294713147410135 -5.95375883366533909 -1.50478442490039810 5.71364713147410352 -3.91819883366533883 -2.19540442490039833 -5.81476286852589741 -3.74890883366533911 -1.82048442490039819 -5.55754286852589807 5.73633116633466145 -1.90847442490039820 -5.46146286852589835 -3.47772883366533891 -2.13718442490039795 -4.99072286852589819 -5.43655883366533743 -2.01766442490039832 1.38724713147410217 -6.17552883366533933 -1.74653442490039823 4.24394713147410130 -3.02942883366533922 -2.03884442490039808 5.86024713147410292 8.35149116633466093 -1.64606442490039839 -3.15967286852589790 -5.27418883366533819 -2.09341442490039809 -1.63817286852589739 -5.88614883366533892 -1.65632442490039811 0.53361713147410250 5.68330116633466176 -1.96876442490039816 2.10124713147410302 -6.23590883366533788 -2.20940442490039812 4.69114713147410178 -5.82193883366533793 -2.38474442490039840 5.36394713147410318 7.09898116633466181 -2.15552442490039819 -4.61563286852589805 7.10412116633466084 -1.75821442490039814 -2.69060286852589714 -5.50698883366533831 -2.16740442490039831 -1.05079286852589737 -4.05927883366533937 -1.66474442490039820 6.08964713147410208 -3.53346883366533904 -0.95755442490039822 -6.05116286852589802 1.51800116633466131 -2.90021442490039805 -5.53951286852589764 6.09555116633466199 -2.23586442490039827 -4.60345286852589819 -2.47310883366533885 -2.27513442490039797 -3.23114286852589760 6.71856116633466094 -2.15463442490039814 -3.44959286852589786 7.74592116633466166 -2.05545442490039809 -3.31210286852589775 6.44001116633466086 -2.58144442490039783 -0.02393286852589716 -5.36323883366533849 -2.41802442490039837 0.21179713147410212 -4.98607883366533855 -2.75059442490039840 1.38184713147410232 1.27015116633466119 -2.11558442490039855 2.94154713147410218 -2.28553883366533883 -2.20484442490039800 3.43034713147410120 2.39526916633466103 -2.41731442490039816 2.96554713147410265 -3.24980883366533924 -2.59064442490039815 5.48184713147410196 -4.92271883366533913 -2.45754442490039837 5.77924713147410252 3.76878116633466131 -2.55034442490039792 -5.93978286852589754 7.27831116633466113 -2.26317442490039822 -3.83995286852589768 6.70457116633466121 -2.39764442490039809 -1.94665286852589725 -4.38385883366533857 -2.64440442490039818 -2.08522286852589733 6.53203116633466063 -1.67225442490039833 1.10964713147410210 5.44647116633466144 -2.72739442490039830 1.50124713147410249 -2.43655883366533876 -2.43238442490039830 2.19334713147410199 -1.30468883366533883 -2.54518442490039831 1.89984713147410278 -6.52337883366533866 -2.71894442490039800 2.29214713147410221 3.59252016633466109 -2.54738442490039851 2.78204713147410221 -3.53288883366533879 -2.76351442490039823 4.29454713147410239 -3.54376883366533812 -3.14812442490039768 -5.96033286852589761 -3.75022883366533799 -2.60133442490039801 -5.24165286852589762 4.86863116633466131 -2.97963442490039832 -5.62615286852589769 5.53639116633466166 -2.82454442490039836 -4.64751286852589818 -5.02706883366533752 -2.80078442490039858 -0.80792286852589823 -0.66992883366533873 -2.83940442490039802 1.44784713147410171 -2.93358883366533885 -2.53615442490039822 3.93844713147410141 -5.19982883366533866 -3.00843442490039781 5.33394713147410116 6.11920116633466193 -3.05510442490039802 -2.10979286852589754 6.09809116633466086 -3.18782442490039841 -0.57827286852589754 -4.53510883366533868 -3.14889442490039873 0.03083713147410266 -4.61439883366533810 -2.76917442490039845 0.99544713147410180 -6.12813883366533751 -3.27495442490039768 1.89034713147410294 4.64497116633466156 -2.51103442490039797 2.40774713147410280 2.59708216633466105 -2.99847442490039828 2.32724713147410256 -3.91399883366533885 -2.65965442490039816 5.72244713147410078 -0.86437883366533885 -3.49573442490039854 -5.96392286852589759 -3.65213883366533887 -3.26996442490039829 -5.75172286852589743 0.22982116633466115 -2.88223442490039794 -5.57956286852589756 2.21877516633466110 -3.24276442490039774 -5.96305286852589767 2.82630836633466132 -2.53412442490039780 -5.52832286852589760 -0.14294883366533889 -2.76136442490039791 -3.96575286852589803 -1.41241883366533849 -3.02320442490039820 -4.48275286852589794 6.12555116633466135 -2.97649442490039817 -3.18516286852589836 -0.28007883366533876 -3.25810442490039875 -1.56553286852589713 0.06202116633466127 -3.06771442490039847 -2.86848286852589718 -2.95824883366533875 -2.91805442490039812 -2.48181286852589844 5.74918116633466081 -2.89241442490039802 0.75464713147410234 -3.81599883366533899 -2.80789442490039809 1.60854713147410289 -2.39413883366533886 -2.83183442490039816 1.55744713147410163 -3.32112883366533929 -3.15121442490039749 2.42094713147410223 -5.85496883366533893 -3.23346442490039809 4.60744713147410145 4.22620116633466125 -3.06886442490039801 -5.95456286852589756 -3.28286883366533955 -3.11168442490039832 -4.89627286852589805 -2.33074883366533925 -2.53788442490039845 -4.35955286852589730 0.58232116633466124 -3.59370442490039865 -4.33943286852589782 -1.48701883366533893 -3.18227442490039847 -2.90119286852589831 -0.81204883366533909 -3.17679442490039765 -2.74555286852589830 0.75231116633466133 -3.95030442490039846 -3.33742286852589798 -2.02705883366533879 -3.30468442490039749 -1.93461286852589787 -3.94181883366533770 -3.40051442490039868 -1.03443286852589744 -3.35957883366533849 -3.31915442490039858 0.54374713147410247 1.45721116633466119 -2.78035442490039797 2.41844713147410229 -6.52033883366533829 -3.24061442490039830 2.68754713147410218 -3.70321883366533777 -2.97665442490039789 5.10064713147410398 -1.20636883366533842 -3.27684442490039762 -5.97638286852589751 -1.12800883366533888 -3.19866442490039793 -5.03856286852589719 -2.81871883366533904 -3.52661442490039834 -5.09020286852589798 -2.85975883366533878 -3.45275442490039763 -1.56616286852589726 -0.57876883366533882 -3.30822442490039803 -1.04080286852589743 -0.36688883366533875 -3.48242442490039883 0.35039713147410195 -1.82733883366533911 -3.21361442490039773 0.90394713147410188 3.93424116633466081 -3.05157442490039843 1.61154713147410167 -5.35411883366533914 -3.53152442490039808 1.67274713147410181 2.91304416633466090 -3.29901442490039809 1.62464713147410222 0.74749116633466106 -3.53737442490039822 -5.96056286852589778 -0.55792883366533907 -4.11063442490039854 -5.41847286852589782 4.49159116633466127 -3.37711442490039859 -4.71415286852589777 4.89600116633466076 -3.63888442490039887 -3.97043286852589805 0.29678116633466112 -4.46056442490039817 -1.33892286852589781 -1.40640883366533909 -3.36165442490039812 -1.35861286852589780 5.37158116633466154 -3.75162442490039894 -1.17852286852589838 -3.49562883366533894 -3.59038442490039866 -0.48050286852589774 5.26591116633466072 -3.64265442490039870 -0.06671286852589775 -2.71659883366533927 -3.58629442490039763 -0.56590286852589711 -2.08526883366533911 -3.54721442490039829 -0.49571286852589797 -1.05502883366533862 -3.44109442490039807 -0.35142286852589827 -1.33219883366533898 -3.24401442490039882 0.38571713147410175 0.83810116633466114 -3.58613442490039880 0.37457713147410199 0.89228116633466126 -3.25309442490039746 1.34814713147410203 3.93437116633466122 -3.69271442490039803 0.84574713147410185 2.69712606633466123 -3.51676442490039820 0.74854713147410190 -4.50456883366533845 -3.80929442490039882 1.74354713147410179 -3.38044883366533933 -3.34816442490039901 3.00494713147410186 -2.26502883366533858 -3.66711442490039863 -5.72865286852589772 2.43437016633466108 -3.62231442490039823 -5.96484286852589740 -3.16687883366533907 -3.68223442490039776 -5.70908286852589786 4.18184116633466108 -3.45523442490039834 -5.78369286852589770 3.50150016633466121 -3.66389442490039752 -5.04940286852589804 4.97070116633466075 -3.75653442490039868 -2.75572286852589787 -5.59269883366533804 -3.91249442490039812 2.26834713147410216 -6.16259883366533767 -3.70354442490039837 2.60434713147410246 -5.78359883366533900 -3.90311442490039884 3.75264713147410145 -4.17264883366533912 -3.98803442490039828 3.59314713147410325 -0.12704883366533892 -4.26145442490039894 -5.88103286852589768 2.55571216633466136 -3.75124442490039778 -5.09572286852589773 1.40030116633466117 -3.88687442490039814 -4.65729286852589741 3.76275116633466089 -4.24410442490039852 -4.07048286852589758 4.54093116633466032 -3.92740442490039765 -3.69757286852589750 4.61683116633466106 -4.22381442490039927 -1.25044286852589726 3.39075816633466109 -3.98258442490039855 0.38412713147410182 -4.26272883366533861 -3.52085442490039791 4.81864713147410217 -5.15410883366533845 -3.83430442490039791 4.49914713147410161 1.08823116633466133 -4.20707442490039796 -5.82481286852589797 -0.03840883366533869 -3.88458442490039868 -4.69205286852589776 2.49959816633466092 -4.35784442490039758 -4.29799286852589724 1.13611116633466103 -4.24821442490039836 -3.57376286852589731 3.76769116633466128 -4.47214442490039854 -3.02052286852589758 4.71052116633466067 -3.68867442490039821 0.45144713147410170 4.03087116633466103 -4.29507442490039804 -0.32188286852589815 0.93445116633466097 -4.42231442490039761 -0.11539286852589731 1.90169016633466104 -4.14821442490039871 0.37564713147410222 -4.02928883366533874 -3.97729442490039897 2.08524713147410212 -5.27865883366533772 -4.32740442490039801 3.25094713147410230 -4.17370883366533896 -4.32510442490039893 2.84114713147410169 0.03001116633466125 -4.42858442490039916 -5.38359286852589758 3.97112116633466083 -4.54104442490039784 -1.88127286852589748 0.46578116633466116 -4.55252442490039755 -0.85905286852589746 -0.07501883366533880 -3.58144442490039872 -0.35869286852589777 3.00895716633466126 -4.49485442490039766 -0.00981286852589774 -4.36177883366533869 -4.33698442490039859 2.34074713147410218 -4.90776883366533845 -4.28962442490039830 3.74344713147410335 0.57671116633466124 -4.37644442490039864 -5.08508286852589730 1.97587916633466110 -4.65320442490039810 -3.26668286852589773 1.53029116633466100 -4.53917442490039846 -2.67431286852589789 0.89178116633466109 -4.77426442490039804 -1.33956286852589823 1.70592116633466118 -4.61142442490039794 -0.09055286852589772 2.99776216633466142 -4.64494442490039727 -3.37482286852589786 3.79441116633466091 -4.51426442490039825 -1.12133286852589831 2.40266116633466087 -4.83917442490039829 -2.30670286852589790 3.07509316633466145 -4.74584442490039837 -1.76209286852589830 2.06104616633466087 -4.90085442490039824 -1.69572286852589782 1.61701116633466113 -4.77165442490039826 -0.69887286852589736 3.02259016633466127 -4.76993442490039854 -0.87750286852589787 3 9 2 0 3 2 1 0 3 9 0 5 3 1 2 3 3 3 4 1 3 0 1 5 3 5 1 8 3 8 1 10 3 9 6 2 3 7 2 6 3 10 1 4 3 3 2 7 3 4 3 12 3 13 17 4 3 10 4 17 3 8 10 17 3 15 14 6 3 7 6 14 3 15 6 9 3 20 15 9 3 9 11 20 3 9 5 11 3 13 4 12 3 13 44 17 3 8 17 16 3 18 7 14 3 11 5 19 3 8 19 5 3 19 8 16 3 12 3 7 3 12 21 13 3 13 21 44 3 30 29 22 3 23 30 22 3 24 25 23 3 22 24 23 3 25 26 23 3 26 25 27 3 28 14 15 3 17 44 16 3 30 34 29 3 30 23 36 3 23 31 36 3 23 26 31 3 32 31 26 3 38 24 22 3 24 27 25 3 14 33 18 3 29 34 41 3 34 30 35 3 30 36 35 3 36 31 37 3 29 38 22 3 24 38 72 3 72 39 24 3 27 32 26 3 39 27 24 3 42 41 34 3 34 35 42 3 36 37 35 3 29 60 38 3 31 32 43 3 32 27 40 3 27 39 51 3 40 27 51 3 14 28 33 3 45 46 57 3 47 57 46 3 41 42 48 3 29 41 67 3 35 37 42 3 59 42 37 3 67 60 29 3 43 79 31 3 32 49 43 3 39 72 80 3 74 32 40 3 49 32 74 3 50 51 39 3 52 15 20 3 20 11 53 3 12 54 21 3 19 16 55 3 57 56 45 3 45 56 46 3 56 58 46 3 46 41 47 3 46 58 67 3 46 67 41 3 42 78 48 3 37 31 59 3 31 79 59 3 43 49 61 3 80 50 39 3 52 20 53 3 62 12 7 3 21 117 44 3 16 44 117 3 64 76 82 3 63 64 82 3 57 65 56 3 57 47 66 3 47 41 48 3 67 58 68 3 78 42 59 3 78 59 69 3 69 59 70 3 71 70 59 3 59 79 71 3 43 61 79 3 61 49 73 3 49 74 73 3 51 74 40 3 75 18 33 3 18 75 7 3 54 12 62 3 11 176 53 3 11 19 176 3 54 117 21 3 141 63 82 3 57 66 65 3 66 47 77 3 47 48 77 3 48 78 77 3 78 69 77 3 60 67 68 3 73 81 61 3 80 88 50 3 75 62 7 3 157 52 53 3 76 103 82 3 141 83 63 3 64 63 83 3 56 65 106 3 84 66 77 3 98 71 79 3 110 38 60 3 61 98 79 3 110 123 72 3 38 110 72 3 61 81 98 3 86 72 123 3 85 87 86 3 80 72 86 3 86 87 80 3 85 101 87 3 87 88 80 3 51 89 74 3 89 73 74 3 88 90 50 3 50 92 51 3 92 89 51 3 28 15 52 3 64 93 76 3 106 65 94 3 95 84 77 3 58 56 143 3 143 96 58 3 97 95 77 3 69 97 77 3 70 97 69 3 145 60 68 3 111 113 99 3 99 86 134 3 85 86 99 3 113 114 85 3 113 85 99 3 85 114 100 3 100 101 85 3 73 115 81 3 73 89 115 3 87 101 88 3 50 90 91 3 90 88 102 3 92 50 91 3 139 141 82 3 104 93 64 3 83 105 104 3 104 64 83 3 66 107 65 3 66 108 107 3 71 109 70 3 110 60 145 3 147 134 123 3 134 86 123 3 112 98 81 3 125 114 113 3 114 127 100 3 100 153 101 3 88 101 102 3 89 116 115 3 89 92 116 3 91 90 138 3 116 92 129 3 157 53 176 3 176 19 55 3 117 55 16 3 130 139 82 3 82 103 130 3 158 103 93 3 103 76 93 3 66 84 108 3 84 95 119 3 106 94 120 3 121 94 65 3 121 65 107 3 94 121 120 3 97 119 95 3 68 58 96 3 70 109 97 3 170 71 98 3 124 111 99 3 124 99 134 3 135 98 112 3 125 113 111 3 81 126 112 3 127 153 100 3 101 153 137 3 101 137 128 3 102 101 128 3 92 91 154 3 129 92 154 3 104 131 93 3 132 104 105 3 143 56 118 3 56 106 118 3 145 68 96 3 109 71 122 3 147 123 133 3 147 124 134 3 125 111 149 3 135 112 126 3 136 114 125 3 136 127 114 3 152 126 81 3 152 81 115 3 138 102 128 3 138 90 102 3 130 103 158 3 140 55 117 3 83 141 192 3 105 83 192 3 84 119 108 3 120 121 218 3 121 107 144 3 107 108 144 3 109 146 97 3 109 122 169 3 133 123 110 3 170 122 71 3 124 148 111 3 150 136 125 3 126 151 135 3 127 136 186 3 163 116 129 3 115 116 163 3 162 137 153 3 137 162 175 3 138 154 91 3 129 154 187 3 155 129 187 3 28 191 33 3 156 28 52 3 62 204 54 3 204 117 54 3 139 130 166 3 159 192 141 3 141 139 159 3 131 104 142 3 132 142 104 3 180 132 105 3 160 106 120 3 96 143 161 3 161 145 96 3 161 133 145 3 161 147 133 3 133 110 145 3 124 147 161 3 148 149 111 3 98 135 170 3 125 149 171 3 150 125 171 3 153 127 186 3 152 115 163 3 153 186 162 3 164 138 128 3 163 129 155 3 175 128 137 3 156 191 28 3 75 33 191 3 159 139 166 3 166 130 214 3 130 205 214 3 158 205 130 3 178 158 93 3 93 131 178 3 118 106 160 3 160 120 182 3 146 119 97 3 218 121 144 3 143 167 168 3 161 143 168 3 146 109 169 3 161 184 124 3 136 150 172 3 152 151 126 3 173 152 163 3 186 174 162 3 164 128 165 3 165 128 175 3 202 154 138 3 174 156 162 3 189 156 174 3 157 156 52 3 205 158 178 3 177 192 159 3 142 132 179 3 181 143 118 3 181 167 143 3 218 144 108 3 161 168 184 3 169 185 183 3 169 122 185 3 135 151 199 3 200 186 136 3 174 186 201 3 162 188 175 3 156 190 162 3 162 190 188 3 189 191 156 3 204 62 75 3 159 166 177 3 176 55 140 3 178 131 229 3 105 192 231 3 231 180 105 3 180 179 132 3 194 119 146 3 181 193 167 3 195 168 167 3 169 183 146 3 185 196 183 3 197 185 122 3 233 124 184 3 233 148 124 3 170 197 122 3 198 197 170 3 148 234 149 3 135 199 170 3 172 200 136 3 173 163 236 3 155 236 163 3 201 189 174 3 202 138 164 3 203 154 202 3 155 187 251 3 213 191 189 3 190 156 157 3 204 75 191 3 215 178 229 3 205 178 215 3 192 206 231 3 179 180 231 3 118 160 217 3 243 108 207 3 108 119 207 3 207 119 194 3 182 120 208 3 257 194 146 3 183 257 146 3 195 184 168 3 196 221 183 3 196 185 260 3 197 209 185 3 185 209 260 3 149 234 171 3 171 210 150 3 211 172 150 3 212 151 152 3 225 173 236 3 227 202 164 3 201 226 189 3 249 203 202 3 203 187 154 3 226 213 189 3 213 204 191 3 166 190 177 3 190 166 214 3 157 176 140 3 190 157 140 3 204 240 117 3 240 140 117 3 192 177 216 3 131 242 229 3 216 206 192 3 353 193 181 3 181 118 353 3 218 108 243 3 120 218 208 3 219 167 193 3 195 167 219 3 196 222 221 3 196 260 222 3 209 197 198 3 171 234 210 3 198 170 199 3 199 151 223 3 223 151 212 3 172 224 200 3 152 173 212 3 225 212 173 3 201 186 200 3 227 164 165 3 251 236 155 3 251 187 203 3 188 238 175 3 190 252 188 3 190 214 252 3 213 228 204 3 214 205 239 3 214 239 252 3 190 140 216 3 190 216 177 3 215 239 205 3 242 131 230 3 131 142 230 3 142 179 230 3 353 118 217 3 257 183 220 3 183 221 220 3 232 233 184 3 233 246 148 3 210 235 150 3 211 224 172 3 237 165 175 3 238 237 175 3 240 204 228 3 241 215 229 3 242 241 229 3 283 231 206 3 283 230 231 3 231 230 179 3 217 160 255 3 207 194 244 3 245 184 195 3 148 246 234 3 260 209 247 3 209 198 247 3 210 234 261 3 235 211 150 3 224 201 200 3 237 227 165 3 227 249 202 3 264 236 251 3 250 203 249 3 238 188 252 3 226 265 213 3 265 228 213 3 241 239 215 3 253 193 353 3 353 217 254 3 160 182 255 3 182 208 309 3 256 194 257 3 193 253 219 3 257 220 258 3 259 219 253 3 259 195 219 3 246 233 232 3 246 261 234 3 247 198 262 3 276 212 225 3 263 201 224 3 263 248 201 3 264 225 236 3 201 248 226 3 251 203 250 3 206 216 306 3 306 283 206 3 217 255 266 3 194 256 244 3 257 258 256 3 268 220 221 3 245 232 184 3 222 269 221 3 269 222 260 3 198 199 223 3 224 211 277 3 270 249 227 3 271 264 251 3 271 251 250 3 238 252 272 3 280 240 228 3 240 216 140 3 242 283 241 3 283 242 230 3 243 207 273 3 207 244 273 3 258 220 268 3 267 195 259 3 267 245 195 3 268 221 269 3 269 260 274 3 274 260 247 3 235 210 275 3 223 212 276 3 225 264 279 3 227 290 270 3 270 250 249 3 252 239 272 3 281 239 241 3 283 281 241 3 306 281 283 3 218 243 284 3 243 273 285 3 286 259 253 3 275 210 261 3 287 211 235 3 288 223 276 3 277 211 287 3 289 263 224 3 276 225 278 3 225 279 278 3 304 226 248 3 290 227 237 3 265 226 304 3 239 281 272 3 282 240 280 3 243 285 284 3 253 353 286 3 255 182 309 3 273 244 292 3 245 293 232 3 246 294 261 3 269 274 314 3 295 262 198 3 296 247 262 3 287 235 320 3 289 224 277 3 248 263 303 3 299 279 264 3 298 250 270 3 299 264 271 3 297 237 238 3 228 265 300 3 266 255 307 3 217 266 291 3 208 218 284 3 292 244 301 3 244 256 301 3 267 293 245 3 268 302 258 3 293 311 232 3 294 246 232 3 275 261 294 3 274 247 296 3 295 296 262 3 198 223 295 3 303 304 248 3 298 271 250 3 304 300 265 3 297 238 305 3 238 272 305 3 217 291 254 3 307 255 309 3 284 285 308 3 267 259 286 3 256 258 310 3 310 258 302 3 268 269 312 3 311 294 232 3 312 269 314 3 313 275 294 3 274 296 314 3 319 235 275 3 320 235 319 3 289 303 263 3 297 290 237 3 271 298 299 3 316 228 300 3 228 316 280 3 272 281 315 3 352 216 240 3 266 307 291 3 285 273 292 3 256 310 301 3 317 267 286 3 293 267 317 3 312 302 268 3 313 319 275 3 295 223 288 3 345 277 287 3 288 276 371 3 321 289 277 3 299 298 323 3 306 315 281 3 282 352 240 3 352 306 216 3 208 284 308 3 325 293 317 3 302 312 326 3 311 293 325 3 294 311 318 3 327 296 295 3 296 327 314 3 329 303 289 3 329 289 321 3 322 362 290 3 330 290 297 3 299 331 279 3 332 304 303 3 334 270 290 3 334 298 270 3 300 304 332 3 335 280 316 3 335 282 280 3 353 254 291 3 336 337 353 3 309 324 307 3 292 301 338 3 337 286 353 3 337 339 286 3 317 286 339 3 310 302 326 3 312 314 343 3 294 318 313 3 295 328 350 3 320 319 351 3 287 320 345 3 277 345 340 3 371 276 278 3 277 340 321 3 278 279 346 3 331 346 279 3 330 297 333 3 290 330 322 3 362 334 290 3 297 305 333 3 316 300 347 3 338 301 310 3 325 356 311 3 326 312 343 3 343 314 327 3 319 313 344 3 295 288 328 3 345 320 351 3 371 278 346 3 329 332 303 3 323 331 299 3 323 298 334 3 341 347 300 3 316 348 335 3 366 282 335 3 352 282 366 3 306 342 315 3 342 306 352 3 285 292 308 3 349 338 310 3 310 326 349 3 358 343 327 3 350 327 295 3 344 351 319 3 333 305 363 3 300 332 341 3 272 315 305 3 353 291 423 3 324 309 396 3 208 354 309 3 355 338 349 3 412 317 339 3 356 325 317 3 326 358 368 3 358 326 343 3 318 311 356 3 358 327 350 3 350 328 369 3 328 288 359 3 288 371 359 3 345 360 340 3 361 321 340 3 374 330 333 3 364 334 362 3 323 334 364 3 363 305 384 3 305 315 365 3 335 348 366 3 315 342 365 3 308 292 367 3 324 291 307 3 309 354 396 3 367 208 308 3 398 208 367 3 379 339 337 3 326 368 349 3 355 368 357 3 368 350 357 3 358 350 368 3 313 318 370 3 357 350 369 3 344 313 370 3 328 359 369 3 360 345 351 3 346 405 371 3 375 329 321 3 372 346 391 3 333 363 373 3 391 346 331 3 364 376 323 3 323 376 331 3 305 377 384 3 393 342 352 3 378 336 353 3 379 337 336 3 380 292 338 3 354 208 398 3 355 380 338 3 355 349 368 3 355 357 381 3 351 344 370 3 382 360 351 3 371 405 359 3 405 346 372 3 374 383 330 3 407 374 333 3 322 420 362 3 331 376 391 3 362 420 364 3 347 341 332 3 365 377 305 3 348 385 366 3 342 393 365 3 366 393 352 3 353 423 378 3 367 292 410 3 355 381 380 3 379 411 339 3 411 412 339 3 412 414 317 3 414 356 317 3 318 356 404 3 417 404 356 3 370 382 351 3 387 369 359 3 388 389 360 3 389 340 360 3 340 389 361 3 321 361 390 3 375 321 390 3 373 408 406 3 373 406 407 3 407 333 373 3 383 322 330 3 364 420 392 3 291 394 423 3 395 336 378 3 324 396 291 3 410 292 380 3 379 336 395 3 412 400 414 3 381 357 401 3 399 402 415 3 402 399 403 3 357 369 401 3 356 414 417 3 369 386 401 3 370 318 404 3 369 387 386 3 382 388 360 3 406 361 389 3 430 372 391 3 430 391 376 3 364 392 376 3 451 373 363 3 451 408 373 3 409 347 332 3 316 347 409 3 316 409 348 3 377 365 422 3 469 422 365 3 469 365 393 3 367 410 397 3 398 367 397 3 354 398 397 3 424 399 400 3 399 472 413 3 436 435 381 3 415 400 399 3 400 415 414 3 416 399 413 3 436 381 401 3 403 399 416 3 382 370 418 3 419 406 389 3 429 445 374 3 383 374 445 3 407 429 374 3 430 405 372 3 420 322 383 3 447 420 383 3 376 392 432 3 432 430 376 3 421 329 375 3 329 421 332 3 384 451 363 3 451 384 377 3 385 348 409 3 385 393 366 3 410 380 455 3 354 397 433 3 380 381 455 3 381 435 455 3 379 395 411 3 412 411 425 3 400 412 425 3 424 400 425 3 399 424 472 3 426 370 404 3 417 426 404 3 415 438 414 3 427 438 415 3 402 427 415 3 418 388 382 3 441 387 359 3 405 441 359 3 419 389 388 3 428 383 445 3 419 407 406 3 428 447 383 3 361 406 450 3 390 361 431 3 420 447 432 3 432 392 420 3 421 375 390 3 291 396 394 3 433 394 396 3 397 410 453 3 433 396 354 3 455 453 410 3 424 452 423 3 424 423 434 3 454 411 395 3 411 454 425 3 424 425 452 3 457 436 401 3 457 401 386 3 402 403 437 3 414 438 417 3 426 418 370 3 387 439 386 3 426 440 418 3 441 439 387 3 442 440 426 3 438 443 417 3 427 444 438 3 444 445 438 3 486 427 402 3 427 486 444 3 440 419 388 3 419 442 443 3 438 445 443 3 445 429 443 3 444 428 445 3 443 429 419 3 429 407 419 3 405 476 441 3 446 447 428 3 446 449 447 3 476 405 430 3 449 432 447 3 430 432 449 3 450 406 480 3 406 408 480 3 421 390 459 3 460 409 332 3 409 470 385 3 470 393 385 3 393 470 469 3 378 423 452 3 433 397 453 3 395 378 454 3 454 378 452 3 455 456 463 3 456 455 435 3 403 416 437 3 386 439 457 3 417 443 426 3 443 442 426 3 418 440 388 3 442 419 440 3 486 428 444 3 486 446 428 3 446 479 449 3 449 448 430 3 448 476 430 3 361 450 431 3 390 431 458 3 390 458 459 3 408 451 480 3 421 459 332 3 332 459 460 3 451 377 461 3 461 377 422 3 409 460 470 3 422 469 461 3 433 453 394 3 455 471 453 3 471 455 463 3 452 425 454 3 456 464 463 3 465 456 435 3 466 465 435 3 466 435 436 3 466 436 457 3 476 467 441 3 439 441 467 3 479 468 449 3 468 476 448 3 449 468 448 3 394 471 462 3 394 453 471 3 394 462 423 3 471 463 490 3 472 424 434 3 490 463 464 3 473 464 456 3 473 474 464 3 413 464 474 3 416 413 474 3 466 457 475 3 457 439 467 3 402 437 486 3 467 476 496 3 476 477 496 3 478 446 486 3 476 468 477 3 458 431 450 3 482 451 461 3 489 461 469 3 462 434 423 3 483 472 434 3 472 483 490 3 472 490 413 3 490 464 413 3 465 473 456 3 466 475 465 3 416 474 437 3 457 484 475 3 486 437 485 3 479 446 478 3 477 468 487 3 458 450 488 3 450 480 488 3 458 488 481 3 480 482 488 3 482 480 451 3 459 458 481 3 482 461 489 3 481 460 459 3 460 481 470 3 470 481 489 3 489 469 470 3 462 483 434 3 471 490 462 3 490 483 462 3 465 495 473 3 473 491 474 3 475 495 465 3 474 493 437 3 484 457 467 3 485 478 486 3 478 494 479 3 468 479 487 3 479 494 487 3 488 482 481 3 482 489 481 3 473 495 491 3 491 492 474 3 497 495 475 3 492 493 474 3 475 498 497 3 484 498 475 3 484 467 496 3 496 498 484 3 477 501 496 3 485 500 478 3 478 500 494 3 487 494 501 3 501 477 487 3 495 497 491 3 491 497 492 3 497 493 492 3 493 497 499 3 501 499 498 3 499 500 493 3 498 496 501 3 493 485 437 3 501 500 499 3 493 500 485 3 500 501 494 3 499 497 498 matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshBoundaryEdgeIndices.m0000644000000000000000000000013214576357161021636 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshBoundaryEdgeIndices.m0000644000175000017500000000567614576357161023434 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function inds = meshBoundaryEdgeIndices(varargin) %MESHBOUNDARYEDGEINDICES Indices of boundary edges of a mesh. % % INDS = meshBoundaryVertexIndices(V, F) % INDS = meshBoundaryVertexIndices(V, E, F) % % Example % % create centered icosahedron % [v, f] = createIcosahedron; % v(:,3) = v(:,3) - mean(v(:,3)); % % convert to simili-sphere % [v2, f2] = subdivideMesh(v, f, 3); % v3 = normalizeVector3d(v2); % % clip with plane % plane = createPlane([0 0 0], [-1 -2 3]); % [vc, fc] = clipMeshVertices(v3, f2, plane, 'shape', 'plane'); % figure; drawMesh(vc, fc); axis equal; view(3); % % draw boundary vertices % ec = meshEdges(vc, fc); % inds = meshBoundaryEdgeIndices(vc, ec, fc); % edges = [vc(ec(inds, 1), :) vc(ec(inds, 2), :)]; % hold on; drawEdge3d(edges, 'linewidth', 2, 'color', 'b'); % % See also % meshes3d, meshBoundary, meshBoundaryVertexIndices, meshEdgeFaces % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-05-01, using Matlab 8.6.0.267246 (R2015b) % Copyright 2019-2023 INRA - Cepia Software Platform [vertices, edges, faces] = parseMeshData(varargin{:}); % Compute edge-vertex map if not specified if isempty(edges) edges = meshEdges(vertices, faces); end % compute edges to faces map edgeFaces = meshEdgeFaces(vertices, edges, faces); inds = find(sum(edgeFaces == 0, 2) > 0); matgeom-1.2.4/inst/meshes3d/PaxHeaders/readMesh_off.m0000644000000000000000000000013214576357161017474 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/readMesh_off.m0000644000175000017500000001226014576357161021255 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = readMesh_off(fileName) %READMESH_OFF Read mesh data stored in OFF format. % % [VERTICES, FACES] = readMesh_off(FILENAME) % Read the data stored in file FILENAME and return the vertex and face % arrays as NV-by-3 array and NF-by-N array respectively, where NV is the % number of vertices and NF is the number of faces. % % MESH = readMesh_off(FILENAME) % Read the data stored in file FILENAME and return the mesh into a struct % with fields 'vertices' and 'faces'. % % Example % [v, f] = readMesh_off('mushroom.off'); % figure; drawMesh(v, f, 'faceColor', [0 1 0], 'edgeColor', 'none') % view([5 80]); light; lighting gouraud % % See also % meshes3d, readMesh, writeMesh_off, readMesh_obj, drawMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-12-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Read header % open file f = fopen(fileName, 'r'); if f == -1 error('matGeom:readMesh_off:FileNotFound', ... ['Could not open input file: ' fileName]); end % check format line = fgetl(f); % -1 if eof if ~strcmp(line(1:3), 'OFF') error('matGeom:readMesh_off:FileFormatError', ... 'Not a valid OFF file'); end % number of faces and vertices line = fgetl(f); vals = sscanf(line, '%d %d'); nVertices = vals(1); nFaces = vals(2); %% Read vertex data [vertices, count] = fscanf(f, '%f ', [3 nVertices]); if count ~= nVertices * 3 error('matGeom:readMesh_off:FileFormatError', ... ['Could not read all the ' num2str(nVertices) ' vertices']); end vertices = vertices'; %% Read Face data % First try to read faces as an homogeneous array. It if fails, start from % face offset and parse each face individually. In the latter case, faces % can have different number of vertices. % keep position of face info within file faceOffset = ftell(f); % read first face to assess number of vertices per face line = fgetl(f); if line == -1 error('matGeom:readMesh_off:FileFormatError', ... 'Unexpected end of file'); end tokens = split(line); face1 = str2double(tokens(2:end))' + 1; nv = length(face1); try % attempt to read the remaining faces assuming they all have the same % number of vertices pattern = ['%d' repmat(' %d', 1, nv) '\n']; [faces, count] = fscanf(f, pattern, [(nv+1) (nFaces-1)]); if count ~= (nFaces-1) * (nv+1) error('matGeom:readMesh_off:FileFormatError', ... 'Could not read all the %d faces', nFaces); end % transpose, remove first column, use 1-indexing, and concatenate with % first face faces = [face1 ; faces(2:end,:)'+1]; catch % if attempt failed, switch to slower face-by-face parsing disp('readMesh_off: Inhomogeneous number of vertices per face, switching to face-per-face parsing'); fseek(f, faceOffset, 'bof'); % allocate cell array faces = cell(1, nFaces); % iterate over faces for iFace = 1:nFaces % read next line line = fgetl(f); if line == -1 error('matGeom:readMesh_off:FileFormatError', ... 'Unexpected end of file'); end % parse vertex indices for current face tokens = split(line); faces{iFace} = str2double(tokens(2:end))' + 1; end end %% Post-processing % close the file fclose(f); % format output arguments if nargout < 2 mesh.vertices = vertices; mesh.faces = faces; varargout = {mesh}; else varargout = {vertices, faces}; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshVolume.m0000644000000000000000000000013214576357161017236 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshVolume.m0000644000175000017500000000642414576357161021024 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function vol = meshVolume(varargin) %MESHVOLUME (Signed) volume of the space enclosed by a polygonal mesh. % % V = meshVolume(VERTS, FACES) % Computes the volume of the space enclosed by the polygonal mesh % represented by vertices VERTS (as a Nv-by-3 array of cooridnates) and % the array of faces FACES (either as a Nf-by-3 array of vertex indices, % or as a cell array of arrays of vertex indices). % % The volume is computed as the sum of the signed volumes of tetrahedra % formed by triangular faces and the centroid of the mesh. Faces need to % be oriented such that normal points outwards the mesh. See: % http://stackoverflow.com/questions/1838401/general-formula-to-calculate-polyhedron-volume % % Example % % computes the volume of a unit cube (should be equal to 1...) % [v f] = createCube; % meshVolume(v, f) % ans = % 1 % % See also % meshes3d, meshSurfaceArea, tetrahedronVolume, meshComplement % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-10-01, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % parse input [vertices, faces] = parseMeshData(varargin{:}); % ensure mesh has triangle faces faces = triangulateFaces(faces); % initialize an array of volume nFaces = size(faces, 1); vols = zeros(nFaces, 1); % Shift all vertices to the mesh centroid vertices = bsxfun(@minus, vertices, mean(vertices,1)); % compute volume of each tetraedron for i = 1:nFaces % consider the tetrahedron formed by face and mesh centroid tetra = vertices(faces(i, :), :); % volume of current tetrahedron vols(i) = det(tetra) / 6; end vol = sum(vols); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFaceCentroids.m0000644000000000000000000000013214576357161020500 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFaceCentroids.m0000644000175000017500000000730514576357161022265 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function centroids = meshFaceCentroids(varargin) %MESHFACECENTROIDS Compute centroids of faces in a mesh. % % CENTROIDS = meshFaceCentroids(VERTICES, FACES) % VERTICES is a set of 3D points (as a N-by-3 array), and FACES is % either a N-by-3 index array or a cell array of indices. The function % computes the centroid of each face, and returns a Nf-by-3 array % containing their coordinates. % % Example % [v, e, f] = createIcosahedron; % normals1 = meshFaceNormals(v, f); % centros1 = meshFaceCentroids(v, f); % figure; hold on; axis equal; view(3); % drawMesh(v, f); % drawVector3d(centros1, normals1); % % % See also % meshes3d, drawMesh, meshFaceNormals, meshFaceAreas, convhull % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-07-05 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % parse input data [vertices, faces] = parseMeshData(varargin{:}); if isnumeric(faces) % trimesh or quadmesh nf = size(faces, 1); centroids = zeros(nf, size(vertices, 2)); if size(vertices, 2) == 2 % planar case for f = 1:nf centroids(f,:) = polygonCentroid(vertices(faces(f,:), :)); end else % 3D case if size(faces, 2) == 3 % For triangular meshes, uses accelerated method % (taken from https://github.com/alecjacobson/gptoolbox) for ff = 1:3 centroids = centroids + 1/3 * vertices(faces(:,ff),:); end else % for quad (or larger) meshes, use slower but more precise method for f = 1:nf centroids(f,:) = polygonCentroid3d(vertices(faces(f,:), :)); end end end else % mesh with faces stored as cell array nf = length(faces); centroids = zeros(nf, size(vertices, 2)); if size(vertices, 2) == 2 % planar case for f = 1:nf centroids(f,:) = polygonCentroid(vertices(faces{f}, :)); end else % 3D case for f = 1:nf centroids(f,:) = polygonCentroid3d(vertices(faces{f}, :)); end end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/collapseEdgesWithManyFaces.m0000644000000000000000000000013214576357161022307 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/collapseEdgesWithManyFaces.m0000644000175000017500000000572014576357161024073 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [vertices, faces] = collapseEdgesWithManyFaces(vertices, faces, varargin) %COLLAPSEEDGESWITHMANYFACES Remove mesh edges adjacent to more than two faces. % % [V2, F2] = collapseEdgesWithManyFaces(V, F) % Count the number of faces adjacent to each edge, and collapse the edges % adjacent to more than two faces. % % % Example % collapseEdgesWithManyFaces % % See also % trimMesh, isManifoldMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-31, using Matlab 9.5.0.944444 (R2018b) % Copyright 2019-2023 INRA - Cepia Software Platform verbose = false; while length(varargin) > 1 && ischar(varargin{1}) name = varargin{1}; if strcmpi(name, 'verbose') verbose = varargin{2}; else error(['Unknown optional argument: ' name]); end varargin(1:2) = []; end while true % compute edge to vertex mapping edges = meshEdges(faces); % compute number of faces incident to each edge edgeFaces = trimeshEdgeFaces(faces); edgeFaceDegrees = sum(edgeFaces > 0, 2); inds = find(edgeFaceDegrees > 2); if isempty(inds) break; end edge = edges(inds(1), :); if verbose fprintf('remove edge with index %d: (%d, %d)\n', inds(1), edge); end [vertices, faces] = mergeMeshVertices(vertices, faces, edge); end % trim [vertices, faces] = trimMesh(vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/minConvexHull.m0000644000000000000000000000013214576357161017705 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/minConvexHull.m0000644000175000017500000001144714576357161021474 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function newFaces = minConvexHull(points, varargin) %MINCONVEXHULL Return the unique minimal convex hull of a set of 3D points. % % FACES = minConvexHull(PTS) % NODES is a set of 3D points (as a Nx3 array). The function computes % the convex hull, and merge contiguous coplanar faces. The result is a % set of polygonal faces, such that there are no coplanar faces. % FACES is a cell array, each cell containing the vector of indices of % nodes given in NODES for the corresponding face. % % FACES = minConvexHull(PTS, PRECISION) % Adjust the threshold for deciding if two faces are coplanar or % parallel. Default value is 1e-14. % % Example % % extract square faces from a cube % [n, e, f] = createCube; % f2 = minConvexHull(n); % drawMesh(n, f2); % % % Subdivides and smooths a mesh rpresenting a cube % [n, e, f] = createCube; % [n2, f2] = subdivideMesh(n, triangulateFaces(f), 4); % [n3, f3] = smoothMesh(n2, f2); % figure; drawMesh(n3, f3); % axis equal; view(3); % % merge coplanar faces, making apparent the faces of the original cube % f4 = minConvexHull(n3); % figure; drawMesh(n3, f4); % axis equal; view(3); % % % See also % meshes3d, mergeCoplanarFaces, drawMesh, convhull, convhulln % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-07-05 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % set up precision acc = 1e-14; if ~isempty(varargin) acc = varargin{1}; end % triangulated convex hull. It is not uniquely defined. faces = convhulln(points); % compute centroid of the nodes pointsCentroid = centroid(points); % number of base triangular faces N = size(faces, 1); % compute normals of given faces normals = planeNormal(createPlane(... points(faces(:,1),:), points(faces(:,2),:), points(faces(:,3),:))); % initialize empty faces newFaces = {}; % Processing flag for each triangle % 1 : triangle to process, 0 : already processed % in the beginning, every triangle face need to be processed flag = ones(N, 1); % iterate on each triangular face of the convex hull for iFace = 1:N % check if face was already performed if ~flag(iFace) continue; end % indices of faces with same normal ind = find(abs(vectorNorm3d(cross(repmat(normals(iFace, :), [N 1]), normals))) end end % compute order of the vertices in current face faceVertices = unique(faces(ind2, :)); [tmp, I] = angleSort3d(points(faceVertices, :)); %#ok % create the new face, ensuring it is a row vector face = faceVertices(I); face = face(:)'; % ensure face has normal pointing outwards outerNormal = meshFaceCentroids(points, face) - pointsCentroid; if dot(meshFaceNormals(points, face), outerNormal, 2) < 0 face = face([1 end:-1:2]); end % add a new face to the list newFaces = [newFaces {face}]; %#ok % mark processed faces flag(ind2) = 0; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/readMesh_ply.m0000644000000000000000000000013214576357161017526 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/readMesh_ply.m0000644000175000017500000004146614576357161021321 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = readMesh_ply(fileName) %READMESH_PLY Read mesh data stored in PLY (Stanford triangle) format. % % [V, F] = readMesh_ply(FNAME) % V is a NV-by-3 numeric array containing vertex coordinates, % F is a NF-by-3 or NF-by-4 array containg vertex indices of each face. % % MESH = readMesh_ply(FNAME) % Returns mesh vertex and face information into a single structure with % fields 'vertices' and 'faces'. % % Example % [v, f] = readMesh_ply('bunny_F1k.ply'); % trisurf(f, v(:,1),v(:,2),v(:,3)); % colormap(gray); axis equal; % % References % Adapted from Gabriel Peyré's "read_ply" function, that is was a wrapper % for the "plyread" function written by Pascal Getreuer. % % See also % meshes3d, readMesh, readMesh_off, readMesh_stl % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2018-04-26, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018-2023 INRA - Cepia Software Platform %% Open file % check existence of file if ~exist(fileName, 'file') error('matGeom:readMesh_ply:FileNotFound', ... ['Could not find file: ' fileName]); end % open file in read text mode [fid, msg] = fopen(fileName, 'rt'); % check file was properly open if fid == -1 error(msg); end % check file format marker buf = fscanf(fid, '%s', 1); if ~strcmp(buf, 'ply') fclose(fid); error('Not a PLY file.'); end %% Read header % initialize empty fields ftell(fid); dataFormat = ''; numComments = 0; comments = {}; % for storing any file comments numElements = 0; numProperties = 0; elements = []; % structure for holding the element data elementCount = []; % number of each type of element in file propertyTypes = []; % corresponding structure recording property types elementNames = {}; % list of element names in the order they are stored in the file propertyNames = []; % structure of lists of property names % iterate over the lines of the file until we find the "end_header" line while true buf = fgetl(fid); % read one line from file tokens = split(buf); % split line into tokens nToks = length(tokens); % count tokens if nToks == 0 continue; end % At the beginning of an element, the first token indicates the nature % of the element switch lower(tokens{1}) case 'format' % read data format (ascii or binary) if nToks >= 2 dataFormat = lower(tokens{2}); if nToks == 3 && ~strcmp(tokens{3},'1.0') fclose(fid); error('Only PLY format version 1.0 supported.'); end end case 'comment' % read file comments numComments = numComments + 1; comments{numComments} = ''; %#ok for i = 2:nToks comments{numComments} = [comments{numComments}, tokens{i}, ' ']; end case 'element' % element name if nToks >= 3 % check element was not already initialized if isfield(elements,tokens{2}) fclose(fid); error(['Duplicate element name, ''',tokens{2},'''.']); end numElements = numElements + 1; numProperties = 0; elements.(tokens{2}) = []; propertyTypes.(tokens{2}) =[]; elementNames{numElements} = tokens{2}; %#ok propertyNames.(tokens{2}) = {}; CurElement = tokens{2}; elementCount(numElements) = str2double(tokens{3}); %#ok if isnan(elementCount(numElements)) fclose(fid); error(['Bad element definition: ', buf]); end else error(['Bad element definition: ', buf]); end case 'property' % element property if ~isempty(CurElement) && nToks >= 3 numProperties = numProperties + 1; if isfield(elements.(CurElement), tokens{nToks}) fclose(fid); error(['Duplicate property name, ''',CurElement,'.',tokens{2},'''.']); end % add property subfield to Elements elements.(CurElement).(tokens{nToks}) = []; % add property subfield to PropertyTypes and save type propertyTypes.(CurElement).(tokens{nToks}) = tokens(2:nToks-1); % record property name order propertyNames.(CurElement){numProperties} = tokens{nToks}; else fclose(fid); if isempty(CurElement) error(['Property definition without element definition: ', buf]); else error(['Bad property definition: ', buf]); end end case 'end_header' % end of header, break infinite loop break; end end %% Set reading for specified data format if isempty(dataFormat) warning('Data format unspecified, assuming ASCII.'); dataFormat = 'ascii'; end switch dataFormat case 'ascii' dataFormat = 0; case 'binary_little_endian' dataFormat = 1; case 'binary_big_endian' dataFormat = 2; otherwise fclose(fid); error('Data format ''%s'' not supported.', dataFormat); end if dataFormat == 0 % read the rest of the file as ASCII data buf = fscanf(fid,'%f'); BufOff = 1; else % reopen the file in read binary mode fclose(fid); if dataFormat == 1 fid = fopen(fileName, 'r', 'ieee-le.l64'); % little endian else fid = fopen(fileName, 'r', 'ieee-be.l64'); % big endian end % find the end of the header again (using ftell on the old handle doesn't give the correct position) BufSize = 8192; buf = [blanks(10),char(fread(fid,BufSize,'uchar')')]; i = []; tmp = -11; while isempty(i) i = strfind(buf,['end_header',13,10]); % look for end_header + CR/LF i = [i,strfind(buf,['end_header',10])]; %#ok % look for end_header + LF if isempty(i) tmp = tmp + BufSize; buf = [buf(BufSize+1:BufSize+10),char(fread(fid,BufSize,'uchar')')]; end end % seek to just after the line feed fseek(fid,i + tmp + 11 + (buf(i + 10) == 13),-1); end %% Read element data % PLY and MATLAB data types (for fread) plyTypeNames = {'char','uchar','short','ushort','int','uint','float','double', ... 'char8','uchar8','short16','ushort16','int32','uint32','float32','double64'}; matlabTypeNames = {'schar','uchar','int16','uint16','int32','uint32','single','double'}; dataTypeSizes = [1,1,2,2,4,4,4,8]; % size in bytes of each type % iterate over element types for i = 1:numElements % get current element property information CurPropertyNames = propertyNames.(elementNames{i}); CurPropertyTypes = propertyTypes.(elementNames{i}); numProperties = size(CurPropertyNames,2); % fprintf('Reading %s...\n',ElementNames{i}); if dataFormat == 0 % read ASCII data type = zeros(1, numProperties); for j = 1:numProperties tokens = CurPropertyTypes.(CurPropertyNames{j}); if strcmpi(tokens{1},'list') type(j) = 1; end end % parse buffer if ~any(type) % no list types rawData = reshape(buf(BufOff:BufOff+elementCount(i)*numProperties-1),numProperties,elementCount(i))'; BufOff = BufOff + elementCount(i)*numProperties; else ListData = cell(numProperties,1); for k = 1:numProperties ListData{k} = cell(elementCount(i),1); end % list type for j = 1:elementCount(i) for k = 1:numProperties if ~type(k) rawData(j,k) = buf(BufOff); BufOff = BufOff + 1; else tmp = buf(BufOff); ListData{k}{j} = buf(BufOff+(1:tmp))'; BufOff = BufOff + tmp + 1; end end end end else % read binary data % translate PLY data type names to MATLAB data type names listFlag = 0; % = 1 if there is a list type sameFlag = 1; % = 1 if all types are the same type = cell(1,numProperties); type2 = type; typeSize = zeros(1,numProperties); typeSize2 = typeSize; for j = 1:numProperties tokens = CurPropertyTypes.(CurPropertyNames{j}); if ~strcmp(tokens{1}, 'list') % non-list type tmp = rem(find(matches(plyTypeNames,tokens{1}))-1,8)+1; if ~isempty(tmp) typeSize(j) = dataTypeSizes(tmp); type{j} = matlabTypeNames{tmp}; typeSize2(j) = 0; type2{j} = ''; sameFlag = sameFlag & strcmp(type{1},type{j}); else fclose(fid); error(['Unknown property data type, ''',tokens{1},''', in ', ... elementNames{i},'.',CurPropertyNames{j},'.']); end else % list type if length(tokens) == 3 listFlag = 1; sameFlag = 0; tmp = rem(find(matches(plyTypeNames,tokens{2}))-1,8)+1; tmp2 = rem(find(matches(plyTypeNames,tokens{3}))-1,8)+1; if ~isempty(tmp) && ~isempty(tmp2) typeSize(j) = dataTypeSizes(tmp); type{j} = matlabTypeNames{tmp}; typeSize2(j) = dataTypeSizes(tmp2); type2{j} = matlabTypeNames{tmp2}; else fclose(fid); error(['Unknown property data type, ''list ',tokens{2},' ',tokens{3},''', in ', ... elementNames{i},'.',CurPropertyNames{j},'.']); end else fclose(fid); error(['Invalid list syntax in ',elementNames{i},'.',CurPropertyNames{j},'.']); end end end % read file if ~listFlag if sameFlag % no list types, all the same type (fast) rawData = fread(fid,[numProperties,elementCount(i)],type{1})'; else % no list types, mixed type rawData = zeros(elementCount(i),numProperties); for j = 1:elementCount(i) for k = 1:numProperties rawData(j,k) = fread(fid,1,type{k}); end end end else ListData = cell(numProperties,1); for k = 1:numProperties ListData{k} = cell(elementCount(i),1); end if numProperties == 1 BufSize = 512; numSkip = 4; j = 0; % list type, one property (fast if lists are usually the same length) while j < elementCount(i) Position = ftell(fid); % read in BufSize count values, assuming all counts = SkipNum [buf,BufSize] = fread(fid,BufSize,type{1},numSkip*typeSize2(1)); miss = find(buf ~= numSkip); % find first count that is not SkipNum fseek(fid,Position + typeSize(1),-1); % seek back to after first count if isempty(miss) % all counts are SkipNum buf = fread(fid,[numSkip,BufSize],[int2str(numSkip),'*',type2{1}],typeSize(1))'; fseek(fid,-typeSize(1),0); % undo last skip for k = 1:BufSize ListData{1}{j+k} = buf(k,:); end j = j + BufSize; BufSize = floor(1.5*BufSize); else if miss(1) > 1 % some counts are numSkip Buf2 = fread(fid,[numSkip,miss(1)-1],[int2str(numSkip),'*',type2{1}],typeSize(1)); Buf2 = Buf2'; for k = 1:miss(1)-1 ListData{1}{j+k} = Buf2(k,:); end j = j + k; end % Alec: check if done and rewind one step if j >= elementCount(i) fseek(fid,-1,0); break; end % read in the list with the missed count numSkip = buf(miss(1)); j = j + 1; ListData{1}{j} = fread(fid,[1,numSkip],type2{1}); BufSize = ceil(0.6*BufSize); end end else % list type(s), multiple properties (slow) rawData = zeros(elementCount(i),numProperties); for j = 1:elementCount(i) for k = 1:numProperties if isempty(type2{k}) rawData(j,k) = fread(fid,1,type{k}); else tmp = fread(fid,1,type{k}); ListData{k}{j} = fread(fid,[1,tmp],type2{k}); end end end end end end % put data into Elements structure for k = 1:numProperties if (~dataFormat && ~type(k)) || (dataFormat && isempty(type2{k})) elements.(elementNames{i}).(CurPropertyNames{k}) = rawData(:,k); else elements.(elementNames{i}).(CurPropertyNames{k}) = ListData{k}; end end end clear rawData ListData; fclose(fid); %% Post-processing % find the index of the element corresponding to face vertex indices possibleFacePropertyNames = ... {'vertex_indices', 'vertex_indexes', 'vertex_index', 'indices', 'indexes'}; facePropertyNameIdx = find(matches(possibleFacePropertyNames, fieldnames(elements.face))); assert(length(facePropertyNameIdx) == 1) % retrieve face vertex data faces = elements.face.(possibleFacePropertyNames{facePropertyNameIdx}); % convert face array from 0-indexing into 1-indexing, % and attempt to convert cell array into numeric array, lengths = cellfun(@length, faces); maxLength = max(lengths); if all(maxLength == lengths) faces = cell2mat(faces)+1; else faces = cellfun(@(x) x+1, faces, 'uni', 0); end % retrieve vertex data vertices = [elements.vertex.x, elements.vertex.y, elements.vertex.z]; % format output arguments varargout = formatMeshOutput(nargout, vertices, faces); if nargout == 1 varargout{1}.comment = comments; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshSilhouette.m0000644000000000000000000000013214576357161020114 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshSilhouette.m0000644000175000017500000001006314576357161021674 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function silhouette = meshSilhouette(v, f, varargin) %MESHSILHOUETTE Compute the 2D outline of a 3D mesh on an arbitrary plane. % % ATTENTION: Very slow brute force approach! Keep the number of faces as % low as possible. % % SILHOUETTE = meshSilhouette(MESH, PLANE) % Calculates the silhouette (2D outline) of the MESH projected on the % PLANE. % % SILHOUETTE = meshSilhouette(MESH) uses the x-y plane. % % SILHOUETTE = meshSilhouette(V, F, ...) % % SILHOUETTE = meshSilhouette(..., 'visu', 1) visualizes the results. % By default the results are not visualized. % % Example: % v = [5, 2, 6, 0, 3; 0, 2, 4, 2, 1; -5, -6, -6, -7, -9]'; % f = [1, 2, 4; 1, 5, 4; 1, 2, 5; 2, 3, 5; 2, 4, 3; 3, 4, 5]; % sil = meshSilhouette(v, f, rand(1,9),'visu',1); % % See also % projPointOnPlane % % Source: % Sean de Wolski - https://www.mathworks.com/matlabcentral/answers/68004 % ------ % Author: oqilipo % E-mail: N/A % Created: 2020-07-29 % Copyright 2020-2023 narginchk(1,5) nargoutchk(0,1) %% Parse inputs % If first argument is a struct if isstruct(v) if nargin > 1 varargin=[{f} varargin{:}]; end mesh = v; [v, f] = parseMeshData(v); else mesh.vertices = v; mesh.faces = f; end p = inputParser; logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); addOptional(p,'plane',[0 0 0 1 0 0 0 1 0],@isPlane) addParameter(p,'visualization',false,logParValidFunc); parse(p, varargin{:}); plane = p.Results.plane; % Transform into the x-y plane TFM = createBasisTransform3d('g', plane); v = transformPoint3d(v,TFM); % Initialize final polygon vectors [px, py] = boundary(polyshape(v(f(1,:),1) ,v(f(1,:),2), 'Simplify',false)); for i = 2:size(f,1) A = polyshape(v(f(i,:),1), v(f(i,:),2), 'Simplify',false); B = polyshape(px, py, 'Simplify',false); [px, py] = boundary(union(A,B)); end % Transform back into the plane silhouette = transformPoint3d([px,py,zeros(size(px))], inv(TFM)); if p.Results.visualization figure('Color','w'); axH = axes(); axis(axH, 'equal', 'tight') drawPolyline3d(axH, silhouette,'Color','r','LineWidth',3) drawPlane3d(axH, plane,'FaceAlpha',0.5) drawMesh(mesh,'FaceAlpha',0.5,'FaceColor','none') axis(axH, 'equal') camTar = nanmean(silhouette); axH.CameraTarget = camTar; axH.CameraPosition = camTar + ... planeNormal(plane)*vectorNorm3d(axH.CameraPosition-axH.CameraTarget); axH.CameraUpVector = plane(4:6); xlabel(axH, 'x'); ylabel(axH, 'y'); zlabel(axH, 'z'); end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/trimeshEdgeFaces.m0000644000000000000000000000013214576357161020314 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/trimeshEdgeFaces.m0000644000175000017500000000746314576357161022106 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edgeFaces = trimeshEdgeFaces(faces, varargin) %TRIMESHEDGEFACES Compute index of faces adjacent to each edge of a triangular mesh. % % EF = trimeshEdgeFaces(FACES) % EF = trimeshEdgeFaces(VERTICES, FACES) % EF = trimeshEdgeFaces(VERTICES, EDGES, FACES) % Compute index array of faces adjacent to each edge of a mesh. % FACES is a NF-by-3 array containing vertex indices of each face. The % result EF is a NE-by-2 array containing the indices of the two faces % incident to each edge. If an edge belongs to only one face, the other % face index is ZERO. % % The list of edges (as array of source and target vertex indices) can be % obtained from the function 'meshEdges'. % % Note: faces are listed in increasing order for each edge, and no % information is kept about relative orientation of edge and face. % % Example % % compute incidence list of each edge of an octahedron. For example, % % first edge is incident to faces 1 and 5. Second edge is incident to % % faces 4 and 8, and so on. % [v, f] = createOctahedron; % ef = trimeshEdgeFaces(v, f) % ef = % 1 5 % 4 8 % 4 1 % 5 8 % 2 6 % 1 2 % 6 5 % 3 7 % 2 3 % 7 6 % 3 4 % 7 8 % % See also % meshes3d, meshEdgeFaces, trimeshMeanBreadth, meshEdges % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-08-19, using Matlab 8.5.0.197613 (R2015a) % Copyright 2015-2023 INRA - Cepia Software Platform if nargin == 2 faces = varargin{1}; elseif nargin == 3 faces = varargin{2}; end % compute vertex indices of each edge (in increasing index order) edges = sort([faces(:,[1 2]) ; faces(:,[2 3]) ; faces(:,[3 1])], 2); % create an array to keep indices of faces "creating" each edge nFaces = size(faces, 1); edgeFaceInds = repmat( (1:nFaces)', 3, 1); % sort edges, keeping indices [edges, ia, ib] = unique(edges, 'rows'); %#ok nEdges = size(edges, 1); % allocate memory for result edgeFaces = zeros(nEdges, 2); % iterate over edges, to identify incident faces for iEdge = 1:nEdges inds = find(ib == iEdge); edgeFaces(iEdge, 1:length(inds)) = edgeFaceInds(inds); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshEdges.m0000644000000000000000000000013214576357161017016 xustar0030 mtime=1710874225.158193326 30 atime=1710874225.158193326 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshEdges.m0000644000175000017500000000641414576357161020603 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges = meshEdges(faces, varargin) %MESHEDGES Computes array of edge vertex indices from face array. % % EDGES = meshEdges(FACES); % % Example % meshEdges % % See also % meshes3d, meshEdgeFaces, meshFaceEdges % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-06-28, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Process input arguments if isstruct(faces) && isfield(faces, 'faces') % if input is a mesh structure, extract the 'faces' field faces = faces.faces; elseif nargin > 1 % if two arguments are given, keep the second one faces = varargin{1}; end if ~iscell(faces) %% Process faces given as numeric array % all faces have same number of vertices nVF = size(faces,2); e = nchoosek(1:nVF,2); A = sparse(faces(:,e(:,1)),faces(:,e(:,2)),1,max(faces(:)),max(faces(:))); [EI,EJ] = find(tril(A+A')); edges = [EJ EI]; else %% faces are given as a cell array % faces may have different number of vertices % number of faces nFaces = length(faces); % compute the number of edges nEdges = 0; for i = nFaces nEdges = nEdges + length(faces{i}); end % allocate memory edges = zeros(nEdges, 2); ind = 0; % fillup edge array for i = 1:nFaces % get vertex indices, ensuring horizontal array f = faces{i}(:)'; nVF = length(f); edges(ind+1:ind+nVF, :) = [f' f([2:end 1])']; ind = ind + nVF; end % keep only unique edges, and return sorted result edges = sortrows(unique(sort(edges, 2), 'rows')); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createCubeOctahedron.m0000644000000000000000000000013214576357161021163 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createCubeOctahedron.m0000644000175000017500000000620414576357161022745 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createCubeOctahedron() %CREATECUBEOCTAHEDRON Create a 3D mesh representing a cube-octahedron. % % [V, E, F] = createCubeOctahedron; % Cubeoctahedron can be seen either as a truncated cube, or as a % truncated octahedron. % V is the 12-by-3 array of vertex coordinates % E is the 27-by-2 array of edge vertex indices % F is the 1-by-14 cell array of face vertex indices % % [V, F] = createCubeOctahedron; % Returns only the vertices and the face vertex indices. % % MESH = createCubeOctahedron; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % Example % [n, e, f] = createCubeOctahedron; % drawMesh(n, f); % % See also % meshes3d, drawMesh, createCube, createOctahedron % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-02-10 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE nodes = [... 0 -1 1;1 0 1;0 1 1;-1 0 1; ... 1 -1 0;1 1 0;-1 1 0;-1 -1 0;... 0 -1 -1;1 0 -1;0 1 -1;-1 0 -1]; edges = [... 1 2; 1 4; 1 5; 1 8; ... 2 3; 2 5; 2 6; ... 3 4; 3 6; 3 7; ... 4 7; 4 8; ... 5 9; 5 10; ... 6 10; 6 11; ... 7 11; 7 12; ... 8 9; 8 12; ... 9 10; 9 12; ... 10 11; 11 12]; faces = {... [1 2 3 4], [1 5 2], [2 6 3], [3 7 4], [4 8 1], ... [5 10 6 2], [3 6 11 7], [4 7 12 8], [1 8 9 5], ... [5 9 10], [6 10 11], [7 11 12], [8 12 9], [9 12 11 10]}; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/cube.ply0000644000000000000000000000013214576357160016377 xustar0030 mtime=1710874224.654193807 30 atime=1710874224.654193807 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/cube.ply0000644000175000017500000000050414576357160020156 0ustar00juanpijuanpi00000000000000ply format ascii 1.0 comment created by platoply element vertex 8 property float32 x property float32 y property float32 z element face 6 property list uint8 int32 vertex_indices end_header -1 -1 -1 1 -1 -1 1 1 -1 -1 1 -1 -1 -1 1 1 -1 1 1 1 1 -1 1 1 4 0 1 2 3 4 5 4 7 6 4 6 2 1 5 4 3 7 4 0 4 7 3 2 6 4 5 1 0 4 matgeom-1.2.4/inst/meshes3d/PaxHeaders/drawFaceNormals.m0000644000000000000000000000013214576357161020162 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/drawFaceNormals.m0000644000175000017500000000532514576357161021747 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawFaceNormals(varargin) %DRAWFACENORMALS Draw normal vector of each face in a mesh. % % drawFaceNormals(V, E, F) % Compute and draw the face normals of the mesh defined by vertices V, % edges E and faces F. See meshes3d for format of each argument. % % H = drawFaceNormals(...) % Return handle array to the created objects. % % Example % % draw face normals of a cube % [v, f] = createCubeOctahedron; % figure; drawMesh(v, f) % axis([-2 2 -2 2 -2 2]); axis equal; hold on; % drawFaceNormals(v, f) % view(3); % % See also % meshes3d, drawMesh, drawVector3d, meshFaceNormals, meshFaceCentroids % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-06, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % extract vertices and faces mesh = parseMeshData(varargin{:}); % compute vector data c = meshFaceCentroids(mesh); n = meshFaceNormals(mesh); % display an arrow for each normal h = quiver3(c(:,1), c(:,2), c(:,3), n(:,1), n(:,2), n(:,3)); % format output if nargout > 0 varargout{1} = h; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/createIcosahedron.m0000644000000000000000000000013214576357161020534 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/createIcosahedron.m0000644000175000017500000000656614576357161022331 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = createIcosahedron() %CREATEICOSAHEDRON Create a 3D mesh representing an Icosahedron. % % MESH = createIcosahedron; % [V, E, F] = createIcosahedron; % Create a solid with 12 vertices, and 20 triangular faces. Faces are % oriented outwards of the mesh. % % [V, F] = createIcosahedron; % Returns only the vertices and the face vertex indices. % % MESH = createIcosahedron; % Returns the data as a mesh structure, with fields 'vertices', 'edges' % and 'faces'. % % Example % [n, e, f] = createIcosahedron; % drawMesh(n, f); % % See also % meshes3d, drawMesh % createCube, createOctahedron, createDodecahedron, createTetrahedron % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-03-21 % Copyright 2005-2023 INRA - TPV URPOI - BIA IMASTE %% Initialisations theta = 2*pi/5; l = 1/sin(theta/2)/2; z1 = sqrt(1-l*l); t1 = (0:2*pi/5:2*pi*(1-1/5))'; x1 = l*cos(t1); y1 = l*sin(t1); t2 = t1 + 2*pi/10; x2 = l*cos(t2); y2 = l*sin(t2); h = sqrt(l*l-.5*.5); z2 = sqrt(3/4 - (l-h)*(l-h)); %% Create mesh data nodes = [0 0 0;... [x1 y1 repmat(z1, [5 1])]; ... [x2 y2 repmat(z1+z2, [5 1])]; ... 0 0 2*z1+z2]; edges = [... 1 2;1 3;1 4;1 5;1 6; ... 2 3;3 4;4 5;5 6;6 2; ... 2 7;7 3;3 8;8 4;4 9;9 5;5 10;10 6;6 11;11 2; ... 7 8;8 9;9 10;10 11;11 7; ... 7 12;8 12;9 12;10 12;11 12]; % faces are ordered to have normals pointing outside of the mesh faces = [... 1 3 2 ; 1 4 3 ; 1 5 4 ; 1 6 5 ; 1 2 6;... 2 3 7 ; 3 4 8 ; 4 5 9 ; 5 6 10 ; 6 2 11;... 7 3 8 ; 8 4 9 ; 9 5 10 ; 10 6 11 ; 11 2 7;... 7 8 12 ; 8 9 12 ; 9 10 12 ; 10 11 12 ; 11 7 12]; % format output varargout = formatMeshOutput(nargout, nodes, edges, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshSurfaceArea.m0000644000000000000000000000013214576357161020150 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshSurfaceArea.m0000644000175000017500000000676114576357161021742 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function area = meshSurfaceArea(varargin) %MESHSURFACEAREA Surface area of a polyhedral mesh. % % S = meshSurfaceArea(V, F) % S = meshSurfaceArea(V, E, F) % Computes the surface area of the mesh specified by vertex array V and % face array F. Vertex array is a NV-by-3 array of coordinates. % Face array can be a NF-by-3 or NF-by-4 numeric array, or a Nf-by-1 cell % array, containing vertex indices of each face. % % This functions iterates on faces, extract vertices of the current face, % and computes the sum of face areas. % % This function assumes faces are coplanar and convex. If faces are all % triangular, the function "trimeshSurfaceArea" should be more efficient. % % % Example % % compute the surface of a unit cube (should be equal to 6) % [v f] = createCube; % meshSurfaceArea(v, f) % ans = % 6 % % See also % meshes3d, trimeshSurfaceArea, meshVolume, meshFaceAreas, % meshFacePolygons, polygonArea3d % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-13, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % parse input arguments [vertices, faces] = parseMeshData(varargin{:}); % pre-compute normals normals = normalizeVector3d(meshFaceNormals(vertices, faces)); % init accumulator area = 0; if isnumeric(faces) % iterate on faces in a numeric array for i = 1:size(faces, 1) poly = vertices(faces(i, :), :); area = area + polyArea3d(poly, normals(i,:)); end else % iterate on faces in a cell array for i = 1:length(faces) poly = vertices(faces{i}, :); area = area + polyArea3d(poly, normals(i,:)); end end function a = polyArea3d(v, normal) nv = size(v, 1); v0 = repmat(v(1,:), nv, 1); products = sum(cross(v-v0, v([2:end 1], :)-v0, 2), 1); a = abs(dot(products, normal, 2))/2; matgeom-1.2.4/inst/meshes3d/PaxHeaders/Contents.m0000644000000000000000000000013214576357161016707 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/Contents.m0000644000175000017500000002673614576357161020505 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. %CONTENTS MESHES3D 3D Surface Meshes. % Version 1.22 06-Jun-2018. % % Creation, visualization, and manipulation of 3D surface meshes or % polyhedra. % % Meshes and Polyhedra are represented by a couple of variables {V, F}: % V: Nv-by-3 array of vertices: [x1 y1 z1; ... ; xn yn zn]; % F: is either a NF-by-3 or NF-by-4 array containing reference for % vertices of each face, or a NF-by-1 cell array, where each cell is an % array containing a variable number of node indices. % For some functions, the array E of edges is needed. It consists in a % NE-by-2 array containing indices of source and target vertices. % % The library provides function to create basic polyhedric meshes (the % five platonic solids, plus few others), as well as functions to perform % basic computations (surface area, normal angles, face centroids...). % The 'MengerSponge' structure is an example of mesh that is not simply % connected (multiple tunnels in the structure). % % The drawMesh function is mainly a wrapper to the Matlab 'patch' % function, allowing passing arguments more quickly. % % Example % % create a soccer ball mesh and display it % [v, e, f] = createSoccerBall; % drawMesh(v, f, 'faceColor', 'g', 'linewidth', 2); % axis equal; view(3); % % % General processing on meshes % smoothMesh - Smooth mesh by replacing each vertex by the average of its neighbors. % subdivideMesh - Subdivides each face of the mesh. % meshVertexClustering - Simplifies a mesh using vertex clustering. % triangulateFaces - Convert face array to an array of triangular faces. % transformMesh - Applies a 3D affine transform to a mesh. % mergeCoplanarFaces - Merge coplanar faces of a polyhedral mesh. % meshFacePolygons - Returns the set of polygons that constitutes a mesh. % meshFaceCentroids - Compute centroids of faces in a mesh. % meshFaceNormals - Compute normal vector of faces in a 3D mesh. % meshVertexNormals - Compute normals to a mesh vertices. % meshComplement - Reverse the normal of each face in the mesh. % averageMesh - Compute average mesh from a list of meshes. % meshSilhouette - Compute the 2D outline of a 3D mesh on an arbitrary plane. % meshVoronoiDiagram - Voronoi Diagram on the surface of a polygonal mesh. % % Intersections and clipping % intersectLineMesh3d - Intersection points of a 3D line with a mesh. % intersectEdgeMesh3d - Intersection points of a 3D edge with a mesh. % intersectPlaneMesh - Compute the polygons resulting from plane-mesh intersection. % polyhedronSlice - Intersect a convex polyhedron with a plane. % clipMeshByPlane - Clip a mesh by a plane. % clipMeshVertices - Clip vertices of a surfacic mesh and remove outer faces. % clipConvexPolyhedronByPlane - Clip a convex polyhedron by a plane. % cutMeshByPlane - Cut a mesh by a plane. % concatenateMeshes - Concatenate multiple meshes. % splitMesh - Return the connected components of a mesh. % % Geometric measures on meshes % meshSurfaceArea - Surface area of a polyhedral mesh. % trimeshSurfaceArea - Surface area of a triangular mesh. % meshFaceAreas - Surface area of each face of a mesh. % meshVolume - (Signed) volume of the space enclosed by a polygonal mesh. % meshCurvatures - Compute principal curvatures on mesh vertices. % meshEdgeLength - Lengths of edges of a polygonal or polyhedral mesh. % meshDihedralAngles - Dihedral at edges of a polyhedal mesh. % polyhedronCentroid - Compute the centroid of a 3D convex polyhedron. % tetrahedronVolume - Signed volume of a tetrahedron. % polyhedronNormalAngle - Compute normal angle at a vertex of a 3D polyhedron. % polyhedronMeanBreadth - Mean breadth of a convex polyhedron. % trimeshMeanBreadth - Mean breadth of a triangular mesh. % isPointInMesh - Check if a point is inside a 3D mesh. % distancePointMesh - Shortest distance between a (3D) point and a triangle mesh. % % Utility functions % meshFace - Return the vertex indices of a face in a mesh. % meshFaceEdges - Computes edge indices of each face. % meshFaceNumber - Returns the number of faces in this mesh. % meshEdges - Computes array of edge vertex indices from face array. % meshEdgeFaces - Compute index of faces adjacent to each edge of a mesh. % trimeshEdgeFaces - Compute index of faces adjacent to each edge of a triangular mesh. % meshFaceAdjacency - Compute adjacency list of face around each face. % meshAdjacencyMatrix - Compute adjacency matrix of a mesh from set of faces. % checkMeshAdjacentFaces - Check if adjacent faces of a mesh have similar orientation. % meshBoundary - Boundary of a mesh as a collection of 3D line strings. % meshBoundaryEdges - Determine the boundary edges of a mesh. % meshBoundaryEdgeIndices - Indices of boundary edges of a mesh. % meshBoundaryVertexIndices - Indices of boundary vertices of a mesh. % smoothMeshFunction - Apply smoothing on a functions defines on mesh vertices. % % Basic edition on meshes % removeMeshVertices - Remove vertices and associated faces from a mesh. % mergeMeshVertices - Merge two vertices and removes eventual degenerated faces. % removeMeshFaces - Remove faces from a mesh by face indices. % % Mesh cleanup % trimMesh - Reduce memory footprint of a polygonal mesh. % isManifoldMesh - Check whether the input mesh may be considered as manifold. % ensureManifoldMesh - Apply several simplification to obtain a manifold mesh. % removeDuplicateFaces - Remove duplicate faces in a face array. % removeDuplicateVertices - Remove duplicate vertices of a mesh. % removeUnreferencedVertices - Remove unreferenced vertices of a mesh. % removeMeshEars - Remove vertices that are connected to only one face. % removeInvalidBorderFaces - Remove faces whose edges are connected to 3, 3, and 1 faces. % collapseEdgesWithManyFaces - Remove mesh edges adjacent to more than two faces. % % Creation and conversion % surfToMesh - Convert surface grids into face-vertex mesh. % triangulateCurvePair - Compute triangulation between a pair of 3D open curves. % triangulatePolygonPair3d - Compute a triangulation between a pair of 3D polygons. % triangulatePolygonPair - Compute triangulation between a pair of 3D closed curves. % circleMesh - Create a mesh defined by a 3D circle. % cylinderMesh - Create a 3D mesh representing a cylinder. % sphereMesh - Create a 3D mesh representing a sphere. % ellipsoidMesh - Convert a 3D ellipsoid to face-vertex mesh representation. % torusMesh - Create a 3D mesh representing a torus. % curveToMesh - Create a mesh surrounding a 3D curve. % boxToMesh - Convert a box into a quad mesh with the same size. % minConvexHull - Return the unique minimal convex hull of a set of 3D points. % % Create meshes representing polyhedra % polyhedra - Index of classical polyhedral meshes. % createCube - Create a 3D mesh representing the unit cube. % createOctahedron - Create a 3D mesh representing an octahedron. % createCubeOctahedron - Create a 3D mesh representing a cube-octahedron. % createIcosahedron - Create a 3D mesh representing an Icosahedron. % createDodecahedron - Create a 3D mesh representing a dodecahedron. % createTetrahedron - Create a 3D mesh representing a tetrahedron. % createRhombododecahedron - Create a 3D mesh representing a rhombododecahedron. % createTetrakaidecahedron - Create a 3D mesh representing a tetrakaidecahedron. % createSoccerBall - Create a 3D mesh representing a soccer ball. % createStellatedMesh - Replaces each face of a mesh by a pyramid. % createDurerPolyhedron - Create a mesh representing Durer's polyhedron . % createMengerSponge - Create a cube with an inside cross removed. % steinerPolytope - Create a steiner polytope from a set of vectors. % % Drawing functions % drawMesh - Draw a 3D mesh defined by vertex and face arrays. % drawPolyhedron - Draw polyhedron defined by vertices and faces. % fillMeshFaces - Fill the faces of a mesh with the specified colors. % drawFaceNormals - Draw normal vector of each face in a mesh. % % I/O functions % readMesh - Read a 3D mesh by inferring format from file name. % writeMesh - Write 3D mesh data by inferring format from file name. % readMesh_off - Read mesh data stored in OFF format. % readMesh_obj - Read mesh data stored in OBJ format. % readMesh_ply - Read mesh data stored in PLY (Stanford triangle) format. % readMesh_stl - Read mesh data stored in STL format. % writeMesh_off - Write a mesh into a text file in OFF format. % writeMesh_ply - Write a mesh into a file in PLY format. % writeMesh_stl - Write mesh data in the STL format. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-07 % Copyright 2005-2023 INRAE help(mfilename); matgeom-1.2.4/inst/meshes3d/PaxHeaders/dodecahedron.ply0000644000000000000000000000013214576357160020100 xustar0030 mtime=1710874224.670193794 30 atime=1710874224.654193807 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/dodecahedron.ply0000644000175000017500000000152614576357160021664 0ustar00juanpijuanpi00000000000000ply format ascii 1.0 comment created by platoply element vertex 20 property float32 x property float32 y property float32 z element face 12 property list uint8 int32 vertex_indices end_header -0.57735 -0.57735 0.57735 0.934172 0.356822 0 0.934172 -0.356822 0 -0.934172 0.356822 0 -0.934172 -0.356822 0 0 0.934172 0.356822 0 0.934172 -0.356822 0.356822 0 -0.934172 -0.356822 0 -0.934172 0 -0.934172 -0.356822 0 -0.934172 0.356822 0.356822 0 0.934172 -0.356822 0 0.934172 0.57735 0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 0.57735 -0.57735 -0.57735 0.57735 0.57735 0.57735 -0.57735 -0.57735 0.57735 -0.57735 0.57735 -0.57735 -0.57735 -0.57735 5 1 2 18 11 14 5 1 13 7 17 2 5 3 4 19 8 15 5 3 16 12 0 4 5 3 15 6 5 16 5 1 14 5 6 13 5 2 17 9 10 18 5 4 0 10 9 19 5 7 8 19 9 17 5 6 15 8 7 13 5 5 14 11 12 16 5 10 0 12 11 18 matgeom-1.2.4/inst/meshes3d/PaxHeaders/removeDuplicateFaces.m0000644000000000000000000000013214576357161021204 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/removeDuplicateFaces.m0000644000175000017500000000466514576357161022777 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function faces2 = removeDuplicateFaces(faces, varargin) %REMOVEDUPLICATEFACES Remove duplicate faces in a face array. % % [V, F] = removeDuplicateFaces(V, F) % % Example % faces = [1 2 3;2 3 4;3 4 5;2 3 4]; % removeDuplicateFaces(faces) % ans = % 1 2 3 % 2 3 4 % 2 3 5 % % See also % ensureManifoldMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-08, using Matlab 8.6.0.267246 (R2015b) % Copyright 2019-2023 INRA - Cepia Software Platform nFaces = size(faces, 1); removeFlag = false(nFaces, 1); for iFace = 1:nFaces if removeFlag(iFace) continue; end face = faces(iFace, :); inds = find(sum(ismember(faces, face), 2) == 3); inds(inds <= iFace) = []; if ~isempty(inds) removeFlag(inds) = true; end end faces2 = faces(~removeFlag, :); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshFace.m0000644000000000000000000000013214576357161016625 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshFace.m0000644000175000017500000000545014576357161020411 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function face = meshFace(faces, index) %MESHFACE Return the vertex indices of a face in a mesh. % % FACE = meshFace(FACES, INDEX) % Return the vertex indices of the i-th face in the face array. This is % mainly an utility function that manages faces stored either as int % array (when all faces have same number of sides) or cell array (when % faces may have different number of edges). % % Example % [v, f] = createCubeOctahedron; % % some faces are squares % meshFace(f, 1) % ans = % 1 2 3 4 % % other are triangles % meshFace(f, 2) % ans = % 1 5 2 % % See also % meshes3d, meshFaceCentroid, meshFaceNormals, meshFaceAreas % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-10-06, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % process mesh given as structure if isstruct(faces) if isfield(faces, 'faces') faces = faces.faces; else error('Mesh structure should contains a field ''faces'''); end end % switch between numeric or cell array if isnumeric(faces) face = faces(index, :); else face = faces{index}; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/trimeshMeanBreadth.m0000644000000000000000000000013214576357161020660 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/trimeshMeanBreadth.m0000644000175000017500000001013614576357161022441 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function mb = trimeshMeanBreadth(vertices, faces) %TRIMESHMEANBREADTH Mean breadth of a triangular mesh. % % MB = trimeshMeanBreadth(VERTICES, FACES) % Computes the mean breadth (proporitonal to the integral of mean % curvature) of a triangular mesh. % % Example % [V, F] = createCube; % F2 = triangulateFaces(F); % MB = trimeshMeanBreadth(V, F2) % MB = % 1.5000 % % See also % meshes3d, trimeshSurfaceArea, trimeshEdgeFaces, polyhedronMeanBreadth % % References % Stoyan D., Kendall W.S., Mecke J. (1995) "Stochastic Geometry and its % Applications", John Wiley and Sons, p. 26 % Ohser, J., Muescklich, F. (2000) "Statistical Analysis of % Microstructures in Materials Sciences", John Wiley and Sons, p.352 % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-08-19, using Matlab 8.5.0.197613 (R2015a) % Copyright 2015-2023 INRA - Cepia Software Platform %% Check input validity if size(faces, 2) ~= 3 error('meshes3d:trimeshMeanBreadth:NonTriangularMesh', ... 'Requires a triangular mesh as input'); end %% Compute edge and edgeFaces arrays % Uses the same code as in trimeshEdgeFaces % compute vertex indices of each edge (in increasing index order) edges = sort([faces(:,[1 2]) ; faces(:,[2 3]) ; faces(:,[3 1])], 2); % create an array to keep indices of faces "creating" each edge nFaces = size(faces, 1); edgeFaceInds = repmat( (1:nFaces)', 3, 1); % sort edges, keeping indices [edges, ia, ib] = unique(edges, 'rows'); %#ok nEdges = size(edges, 1); % allocate memory for result edgeFaces = zeros(nEdges, 2); % iterate over edges, to identify incident faces for iEdge = 1:nEdges inds = find(ib == iEdge); edgeFaces(iEdge, 1:length(inds)) = edgeFaceInds(inds); end %% Compute dihedral angle for each edge % compute normal of each face normals = meshFaceNormals(vertices, faces); % allocate memory for resulting angles alpha = zeros(nEdges, 1); % iterate over edges for iEdge = 1:nEdges % indices of adjacent faces indFace1 = edgeFaces(iEdge, 1); indFace2 = edgeFaces(iEdge, 2); % normal vector of adjacent faces normal1 = normals(indFace1, :); normal2 = normals(indFace2, :); % compute dihedral angle of two vectors alpha(iEdge) = vectorAngle3d(normal1, normal2); end %% Compute mean breadth % integrate the dihedral angles weighted by the length of each edge % compute length of each edge lengths = meshEdgeLength(vertices, edges); % compute product of length by angles mb = sum(alpha .* lengths) / (4*pi); matgeom-1.2.4/inst/meshes3d/PaxHeaders/trimeshSurfaceArea.m0000644000000000000000000000013214576357161020667 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/trimeshSurfaceArea.m0000644000175000017500000000567614576357161022465 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function area = trimeshSurfaceArea(v, e, f) %TRIMESHSURFACEAREA Surface area of a triangular mesh. % % S = trimeshSurfaceArea(V, F) % S = trimeshSurfaceArea(V, E, F) % Computes the surface area of the mesh specified by vertex array V and % face array F. Vertex array is a NV-by-3 array of coordinates. % Face array is a NF-by-3, containing vertex indices of each face. % % Example % % Compute area of an octahedron (equal to 2*sqrt(3)*a*a, with % % a = sqrt(2) in this case) % [v f] = createOctahedron; % trimeshSurfaceArea(v, f) % ans = % 6.9282 % % % triangulate a compute area of a unit cube % [v f] = createCube; % f2 = triangulateFaces(f); % trimeshSurfaceArea(v, f2) % ans = % 6 % % See also % meshes3d, meshSurfaceArea, trimeshMeanBreadth, triangulateFaces % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-08-26, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % check input number if nargin == 2 f = e; end % compute two direction vectors, using first vertex of each face as origin v1 = v(f(:, 2), :) - v(f(:, 1), :); v2 = v(f(:, 3), :) - v(f(:, 1), :); % area of each triangle is half the cross product norm vn = vectorNorm3d(crossProduct3d(v1, v2)); % sum up and normalize area = sum(vn) / 2; matgeom-1.2.4/inst/meshes3d/PaxHeaders/triangulatePolygonPair3d.m0000644000000000000000000000013214576357161022044 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/triangulatePolygonPair3d.m0000644000175000017500000001703114576357161023626 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [tri, weight] = triangulatePolygonPair3d(poly1, poly2, varargin) %TRIANGULATEPOLYGONPAIR3D Compute a triangulation between a pair of 3D polygons. % % TRI = triangulatePolygonPair3d(POLY1, POLY2) % Computes a triangulation between vertices of the two input polygons. % Each triangle refer to one vertex of either POLY1 or POLY2, and two % vertices of the other polygon. Vertex indices correspond to the % concatenation of the two polygons. They range from 1 to NV1+NV2. % This version minimizes the surface area of the reconstructed surface. % % [TRI, WEIGHT] = triangulatePolygonPair3d(POLY1, POLY2) % Also returns the optimal weigth of the reconstruction, corresponding to % the surface area of the triangulation. % % Example % % triangulate a surface patch between two ellipses % % create two sample curves % poly1 = ellipseToPolygon([50 50 40 20 0], 36); % poly2 = ellipseToPolygon([50 50 40 20 60], 36); % poly1 = poly1(1:end-1,:); % poly2 = poly2(1:end-1,:); % % transform to 3D polygons / curves % curve1 = [poly1 10*ones(size(poly1, 1), 1)]; % curve2 = [poly2 20*ones(size(poly2, 1), 1)]; % % draw as 3D curves % figure(1); clf; hold on; % drawPolygon3d(curve1, 'b'); drawPoint3d(curve1, 'bo'); % drawPolygon3d(curve2, 'g'); drawPoint3d(curve2, 'go'); % view(3); axis equal; % tri = triangulatePolygonPair3d(curve1, curve2); % vertices = [curve1 ; curve2]; % % display the resulting mesh % figure(2); clf; hold on; % drawMesh(vertices, tri); % drawPolygon3d(curve1, 'color', 'b', 'linewidth', 2); % drawPolygon3d(curve2, 'color', 'g', 'linewidth', 2); % view(3); axis equal; % % References % Based on the paper: % "Optimal surface reconstruction from planar contours", % Fuchs, H., Kedem, Z. M., Uselton, S.P., 1977, Graphics and Image % Processing, 20(10), 693-702. % % See also % triangulatePolygonPair, triangleArea3d, meshSurfaceArea % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2022-01-14, using Matlab 9.10.0.1739362 (R2021a) Update 5 % Copyright 2022-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Init % number of vertices of each contour nv1 = size(poly1, 1); nv2 = size(poly2, 1); % compute weights for horizontal transitions between graph vertices % corresponding to triangles with two vertices in poly2 weightsH = inf * ones(2*nv1+1, nv2); for iv2 = 1:nv2 v2 = poly2(mod(iv2, nv2)+1, :); for iv1 = 1:nv1 v1 = poly1(iv1, :); weightsH(iv1, iv2) = distancePoints3d(v1, v2); end end weightsH((nv1+1):(2*nv1+1), :) = weightsH([1:nv1 1], :); % compute weights for vertical transitions between graph vertices % corresponding to triangles with two vertices in poly1 weightsV = inf * ones(2*nv1, nv2+1); for iv1 = 1:nv1 v1 = poly1(mod(iv1, nv1)+1, :); for iv2 = 1:nv2 v2 = poly2(iv2, :); weightsV(iv1, iv2) = distancePoints3d(v1, v2); end end weightsV(1:nv1, nv2+1) = weightsV(1:nv1, 1); weightsV(nv1+1:2*nv1, :) = weightsV(1:nv1, :); %% Find minimum-weight path % Note that the original paper proposes an enhanced method that should % reduce the total amount of computation. pathList = cell(1, nv1); weights = zeros(nv1, 1); for i1 = 1:nv1 [pathList{i1}, weights(i1)] = computePath(i1, weightsH, weightsV); end % choose the path [~, ind] = min(weights); path = pathList{ind}; weight = weights(ind); %% Convert path into triangle list % as many triangles as the number of transitions nt = size(path, 1) - 1; tri = zeros(nt, 3); % iterate over triangles for it = 1:nt iv1 = path(it, 1); iv2 = path(it, 2); if path(it + 1, 1) == iv1 % horizontal transition -> use edge from contour 2 iv3 = mod(path(it, 2), nv2) + 1 + nv1; elseif path(it + 1, 2) == iv2 % vertical transition -> use edge from contour 1 iv3 = mod(path(it, 1), nv1) + 1; else error('Successive path positions must share one coordinate'); end % convert grid vertex coords to vertex indices % using one-based indexing modulo iv1 = mod(iv1 - 1, nv1) + 1; iv2 = mod(iv2 - 1, nv2) + 1 + nv1; % also add the vertex count of poly1 tri(it, :) = [iv1 iv2 iv3]; end function [path, pathWeight] = computePath(i10, weightsH, weightsV) %COMPUTEPATH Computes a minimal path within an unfolded toroidal graph. % % PATH = computePath(INITROW, HWEIGHTS, VWEIGHTS); % %% retrieve info % size of the search graph (number of graph vertices along each dimension) ngv1 = size(weightsH, 1); ngv2 = size(weightsV, 2); % compute final index for i1 i1Last = i10 + (ngv1 - 1) / 2; %% Initialize matrix of cumulated weights % create matrix of cumulated weights cumWeights = inf * ones(ngv1, ngv2); % init first row cumWeights(i10, 1) = 0; for i2 = 1:ngv2-1 cumWeights(i10, i2+1) = cumWeights(i10, i2) + weightsH(i10, i2); end % init each subsequent row for i1 = i10+1:i1Last % first vertex in row is initialized from the vertex above cumWeights(i1, 1) = cumWeights(i1-1, 1) + weightsV(i1-1, 1); % other vertices minimize weights from left or top vertices for i2 = 2:ngv2 wH = cumWeights(i1, i2 - 1) + weightsH(i1, i2 - 1); wV = cumWeights(i1 - 1, i2) + weightsV(i1 - 1, i2); cumWeights(i1, i2) = min(wH, wV); end end %% Backpropagate to find path % allocate path array np = (ngv1 - 1) / 2 + ngv2; path = zeros(np, 2); % extreme points path(1, :) = [i10 1]; path(end, :) = [i1Last ngv2]; % index of row and column i1 = i1Last; i2 = ngv2; for iPath = np-1:-1:1 % determine the weights associated to a move in the horizontal or % vertical direction moveLeft = true; if i2 == 1 moveLeft = false; elseif i1 > i10 wH = cumWeights(i1, i2-1); wV = cumWeights(i1-1, i2); moveLeft = wH < wV; end % update position of current grid vertex if moveLeft i2 = i2 - 1; else i1 = i1 - 1; end path(iPath, :) = [i1 i2]; end pathWeight = cumWeights(i1Last, ngv2); matgeom-1.2.4/inst/meshes3d/PaxHeaders/curveToMesh.m0000644000000000000000000000013214576357161017356 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/curveToMesh.m0000644000175000017500000001002314576357161021132 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [vertices, faces] = curveToMesh(curve, varargin) %CURVETOMESH Create a mesh surrounding a 3D curve. % % [V, F] = curveToMesh(CURVE) % Computes the vertices and the faces of the mesh surrounding the % specified 3D curve. % % [V, F] = curveToMesh(CURVE, THICKNESS) % Specifies the thickness of the mesh (distance between mesh vertices and % curve vertices). Default is 0.5. % % [V, F] = curveToMesh(CURVE, THICKNESS, NCORNERS) % Also specifies the number of mesh vertices around each curve vertex. % Default is 8. % % % Example % % Creates a tubular mesh around a trefoil knot curve % t = linspace(0, 2*pi, 200)'; % x = sin(t) + 2 * sin(2 * t); % y = cos(t) - 2 * cos(2 * t); % z = -sin(3 * t); % curve = [x, y, z]; % [v2, f2] = curveToMesh(curve, .5, 16); % figure; % drawMesh(v2, f2); % axis equal; view(3); % axis([-4 4 -4 4 -2 2]); % % See also % meshes3d, torusMesh, surfToMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-01-07, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform radius = .1; if nargin > 1 radius = varargin{1}; end nCorners = 8; if nargin > 2 nCorners = varargin{2}; end nNodes = size(curve, 1); nVerts = nNodes * nCorners; vertices = zeros(nVerts, 3); % create reference corners, that will be rotated and translated t = linspace(0, 2*pi, nCorners + 1)'; t(end) = []; baseCorners = radius * [cos(t) sin(t) zeros(size(t))]; for iNode = 1:nNodes % coordinate of current node node = curve(iNode, :); % compute local tangent vector iNext = mod(iNode, nNodes) + 1; tangentVector = normalizeVector3d(curve(iNext, :) - node); % convert to spherical coordinates [theta, phi, rho] = cart2sph2(tangentVector); %#ok % apply transformation to place corners around current node rotY = createRotationOy(theta); rotZ = createRotationOz(phi); trans = createTranslation3d(node); transformMatrix = trans * rotZ * rotY; corners = transformPoint3d(baseCorners, transformMatrix); % concatenate with other corners vertices( (1:nCorners) + (iNode - 1) * nCorners, :) = corners; end % indices of vertices inds = (1:nVerts)'; add1 = repmat([ones(nCorners-1, 1) ; 1-nCorners], nNodes, 1); % generate faces faces = [inds ... mod(inds + add1 - 1, nVerts) + 1 ... mod(inds + nCorners + add1 - 1, nVerts) + 1 ... mod(inds + nCorners - 1, nVerts) + 1]; matgeom-1.2.4/inst/meshes3d/PaxHeaders/trimMesh.m0000644000000000000000000000013214576357161016702 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/trimMesh.m0000644000175000017500000000762014576357161020467 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = trimMesh(varargin) %TRIMMESH Reduce memory footprint of a polygonal mesh. % % [V2, F2] = trimMesh(V, F) % Unreferenced vertices are removed. % Following functions are implemented only for numeric faces: % Duplicate vertices are removed. % Duplicate faces are removed. % % Example % [V, F] = createIcosahedron; % F(13:20, :) = []; % [V2, F2] = trimMesh(V, F); % figure; drawMesh(V2, F2) % view(3); axis equal; % axis([-1 1 -1 1 0 2]) % % See also % meshes3d, clipMeshVertices % ------ % Author: David Legland, oqilipo % E-mail: david.legland@inrae.fr % Created: 2014-08-01, using Matlab 8.3.0.532 (R2014a) % Copyright 2014-2023 INRA - Cepia Software Platform % parse input data [vertices, faces] = parseMeshData(varargin{:}); if isnumeric(faces) % Process meshes with faces given as Nf-by-3 or Nf-by-4 numeric arrays % Delete duplicate vertices [tempVertices, tempFaces] = removeDuplicateVertices(vertices, faces); % Delete unindexed/unreferenced vertices [tempVertices2, tempFaces2] = removeUnreferencedVertices(tempVertices, tempFaces); % Delete duplicate faces [~, uniqueFaceIdx, ~] = unique(tempFaces2, 'rows'); duplicateFaceIdx = ~ismember(1:size(tempFaces2,1), uniqueFaceIdx); [vertices2, faces2] = removeMeshFaces(tempVertices2, tempFaces2, duplicateFaceIdx); elseif iscell(faces) % Process meshes with faces given as cell array of row vectors nVertices = size(vertices, 1); nFaces = length(faces); % identify vertices referenced by at least one face vertexUsed = false(nVertices, 1); for iFace = 1:nFaces face = faces{iFace}; vertexUsed(face) = true; end vertices2 = vertices(vertexUsed, :); % compute map from old index to new index inds = find(vertexUsed); newInds = zeros(nVertices, 1); for iIndex = 1:length(inds) newInds(inds(iIndex)) = iIndex; end % change labels of vertices referenced by faces faces2 = cell(1, nFaces); for iFace = 1:nFaces faces2{iFace} = newInds(faces{iFace})'; end else error('matGeom:trimMesh', ... 'Unsupported representation for mesh faces'); end % format output arguments varargout = formatMeshOutput(nargout, vertices2, faces2); matgeom-1.2.4/inst/meshes3d/PaxHeaders/ellipsoidMesh.m0000644000000000000000000000013214576357161017713 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/ellipsoidMesh.m0000644000175000017500000001040014576357161021466 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = ellipsoidMesh(elli, varargin) %ELLIPSOIDMESH Convert a 3D ellipsoid to face-vertex mesh representation. % % [V, F] = ellipsoidMesh(ELLI) % ELLI is given by: % [XC YC ZC A B C PHI THETA PSI], % where (XC, YC, ZC) is the ellipsoid center, A, B and C are the half % lengths of the ellipsoid main axes, and PHI THETA PSI are Euler angles % representing ellipsoid orientation, in degrees. % % Example % % compute mesh of an ellongated ellipsoid % elli = [50 50 50 50 30 10 30 20 10]; % [v, f] = ellipsoidMesh(elli); % figure; hold on; axis equal; axis([0 100 0 100 0 100]); view(3); % drawMesh(v, f); % % See also % meshes3d, drawEllipsoid, sphereMesh, equivalentEllipsoid % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform %% Default values % number of meridians nPhi = 32; % number of parallels nTheta = 16; %% Extract input arguments % Parse the input (try to extract center coordinates and radius) if nargin == 0 % no input: assumes ellipsoid with default shape elli = [0 0 0 5 4 3 0 0 0]; end % default set of options for drawing meshes options = {'FaceColor', 'g', 'linestyle', 'none'}; while length(varargin) > 1 switch lower(varargin{1}) case 'nphi' nPhi = varargin{2}; case 'ntheta' nTheta = varargin{2}; otherwise % assumes this is drawing option options = [options varargin(1:2)]; %#ok end varargin(1:2) = []; end %% Parse numerical inputs % Extract ellipsoid parameters xc = elli(:,1); yc = elli(:,2); zc = elli(:,3); a = elli(:,4); b = elli(:,5); c = elli(:,6); k = pi / 180; ellPhi = elli(:,7) * k; ellTheta = elli(:,8) * k; ellPsi = elli(:,9) * k; %% Coordinates computation % convert unit basis to ellipsoid basis sca = createScaling3d(a, b, c); rotZ = createRotationOz(ellPhi); rotY = createRotationOy(ellTheta); rotX = createRotationOx(ellPsi); tra = createTranslation3d([xc yc zc]); % concatenate transforms trans = tra * rotZ * rotY * rotX * sca; %% parametrisation of ellipsoid % spherical coordinates theta = linspace(0, pi, nTheta+1); phi = linspace(0, 2*pi, nPhi+1); % convert to cartesian coordinates sintheta = sin(theta); x = cos(phi') * sintheta; y = sin(phi') * sintheta; z = ones(length(phi),1) * cos(theta); % transform mesh vertices [x, y, z] = transformPoint3d(x, y, z, trans); % convert to FV mesh [vertices, faces] = surfToMesh(x, y, z, 'xPeriodic', false, 'yPeriodic', true); % format output varargout = formatMeshOutput(nargout, vertices, faces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshBoundaryEdges.m0000644000000000000000000000013214576357161020522 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshBoundaryEdges.m0000644000175000017500000000630214576357161022303 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function BE = meshBoundaryEdges(varargin) %MESHBOUNDARYEDGES Determine the boundary edges of a mesh. % % BE = meshBoundaryEdges(V, F) % Determine for each edge of the mesh if it is a boundary edge of the % mesh. % % Example % run createTrefoilKnot.m % f2 = triangulateFaces(f2); % % clip the mesh with a plane % plane = createPlane([0 0 0], [-1 -2 3]); % [v2, f2] = clipMeshVertices(v2, f2, plane, 'shape', 'plane'); % % draw the mesh % figure('color','w'); drawMesh(v2, f2); axis equal; view(3); % % calculate the boundary edges % be2 = meshBoundaryEdges(v2, f2); % % draw boundary edges % drawEdge3d([v2(be2(:,1),:) v2(be2(:,2),:)], 'LineWidth',4,'Color','g') % % See also % meshes3d, meshBoundary, meshBoundaryVertexIndices, meshEdgeFaces, % meshBoundaryEdgeIndices % % Source: % is_boundary_facet.m by Alec Jacobson: % https://github.com/alecjacobson/gptoolbox % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-05-15, using Matlab 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 [V, E, F] = parseMeshData(varargin{:}); % Compute edge-vertex map if not specified if isempty(E) E = meshEdges(V, F); end switch size(F,2) case 3 allE = [F(:,[2 3]);F(:,[3 1]);F(:,[1 2])]; case 4 allE = [ ... F(:,2) F(:,4) F(:,3); ... F(:,1) F(:,3) F(:,4); ... F(:,1) F(:,4) F(:,2); ... F(:,1) F(:,2) F(:,3); ... ]; end [~,~,EMAP] = unique(sort([E;allE],2),'rows'); N = accumarray(EMAP,1); % Look of occurances of 2: one for original and another for boundary B = N(EMAP(1:size(E,1)))==2; BE = E(B,:); matgeom-1.2.4/inst/meshes3d/PaxHeaders/readMesh.m0000644000000000000000000000013214576357161016642 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/readMesh.m0000644000175000017500000000665114576357161020432 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = readMesh(filePath, varargin) %READMESH Read a 3D mesh by inferring format from file name. % % Usage: % [V, F] = readMesh(FILENAME) % Read the data stored in file FILENAME and return the vertex and face % arrays as NV-by-3 array and NF-by-N array respectively, where NV is the % number of vertices and NF is the number of faces. % % MESH = readMesh(FILENAME) % Read the data stored in file FILENAME and return the mesh into a struct % with fields 'vertices' and 'faces'. % The struct also comprises two fields "name" and "fileName": % * "name" corresponds to the base name of the file (without path and % extension) % * "filePath" corresponds to the full (relative) path name of the file. % % Example % mesh = readMesh('apple.ply'); % figure; drawMesh(mesh); % view([180 -70]); axis equal; % % See also % meshes3d, writeMesh, readMesh_off, readMesh_ply, readMesh_stl % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-11-20, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) parser = inputParser; addParameter(parser, 'trimMesh', true, @islogical); parse(parser, varargin{:}); [~, baseName, ext] = fileparts(filePath); switch lower(ext) case '.off' mesh = readMesh_off(filePath); case '.ply' mesh = readMesh_ply(filePath); case '.stl' mesh = readMesh_stl(filePath); case '.obj' mesh = readMesh_obj(filePath); otherwise error('readMesh.m function does not support %s files.', upper(ext(2:end))); end % format output arguments varargout = formatMeshOutput(nargout, mesh.vertices, mesh.faces); % in case of mesh returned as a struct, also include the file name as field if isstruct(varargout{1}) varargout{1}.name = baseName; varargout{1}.filePath = filePath; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/private0000644000000000000000000000013214576357160016330 xustar0030 mtime=1710874224.642193819 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/private/0000755000175000017500000000000014576357160020165 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/meshes3d/private/PaxHeaders/progressbar.m0000644000000000000000000000013214576357161021115 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/private/progressbar.m0000644000175000017500000000451314576357161022700 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function progressbar(n,N,w) %PROGRESSBAR Display a progress bar. % % progressbar(n,N,w); % Displays the progress of n out of N. n should start at 1. w is the % width of the bar (default w=20). % % ------ % Author: Gabriel Peyré % E-mail: gabriel.peyre@ens.fr % Created: 2006 % Copyright 2006-2023 if nargin<3 w = 20; end % progress char cprog = '.'; cprog1 = '*'; % begining char cbeg = '['; % ending char cend = ']'; p = min( floor(n/N*(w+1)), w); global pprev; if isempty(pprev) pprev = -1; end if not(p==pprev) ps = repmat(cprog, [1 w]); ps(1:p) = cprog1; ps = [cbeg ps cend]; if n>1 % clear previous string fprintf( repmat('\b', [1 length(ps)]) ); end fprintf(ps); end pprev = p; if n==N fprintf('\n'); end matgeom-1.2.4/inst/meshes3d/private/PaxHeaders/parseMeshData.m0000644000000000000000000000013214576357161021305 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/private/parseMeshData.m0000644000175000017500000000644214576357161023073 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = parseMeshData(varargin) %PARSEMESHDATA Conversion of data representation for meshes. % % MESH = parseMeshData(VERTICES, FACES) % MESH = parseMeshData(VERTICES, EDGES, FACES) % Returns the mesh info into a single structure with fields "vertices", % "edges" and "faces". % % [VERTICES, FACES] = parseMeshData(MESH) % Returns the mesh info into two output variables containing coordinates % of vertices (as a Nv_by_3 array) and the list of vertex indices for % each face (either as a Nf-by-3 or Nf-by-4 int array, or as a cell % array). % % [VERTICES, EDGES, FACES] = parseMeshData(MESH) % Also returns the vertex indices of each edge, as a Ne-by-2 array of % vertex indices. % % See also % meshes3d, formatMeshOutput % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-12-06, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % initialize edges to empty variable edges = []; % Process input arguments switch nargin case 1 % input is a data structure mesh = varargin{1}; vertices = mesh.vertices; faces = mesh.faces; if isfield(mesh, 'edges') edges = mesh.edges; end case 2 % input are vertices and faces vertices = varargin{1}; faces = varargin{2}; case 3 % input are vertices, edges and faces vertices = varargin{1}; edges = varargin{2}; faces = varargin{3}; otherwise error('Wrong number of arguments'); end % returns either a struct or several variables varargout = formatMeshOutput(nargout, vertices, edges, faces); matgeom-1.2.4/inst/meshes3d/private/PaxHeaders/localToGlobal3d.m0000644000000000000000000000013214576357161021531 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/private/localToGlobal3d.m0000644000175000017500000001041014576357161023305 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function trans = localToGlobal3d(varargin) %LOCALTOGLOBAL3D Transformation matrix from local to global coordinate system. % % TRANS = localToGlobal3d(CENTER, THETA, PHI, PSI) % Compute the transformation matrix from a local (or modelling) % coordinate system to the global (or world) coordinate system. % This is a low-level function, used by several drawing functions. % % The transform is defined by: % - CENTER: the position of the local origin into the World coordinate % system % - THETA: colatitude, defined as the angle with the Oz axis (between 0 % and 180 degrees), positive in the direction of the of Oy axis. % - PHI: azimut, defined as the angle of the normal with the Ox axis, % between 0 and 360 degrees % - PSI: intrinsic rotation, corresponding to the rotation of the object % around the direction vector, between 0 and 360 degrees % % The resulting transform is obtained by applying (in that order): % - Rotation by PSI around he Z-axis % - Rotation by THETA around the Y-axis % - Rotation by PHI around the Z-axis % - Translation by vector CENTER % This corresponds to Euler ZYZ rotation, using angles PHI, THETA and % PSI. % % The 'createEulerAnglesRotation' function may better suit your needs as % it is more 'natural'. % % Example % localToGlobal3d % % See also % transforms3d, createEulerAnglesRotation % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2009-06-19, using Matlab 7.7.0.471 (R2008b) % Copyright 2009-2023 INRA - Cepia Software Platform % extract the components of the transform if nargin == 1 % all components are bundled in the first argument var = varargin{1}; center = var(1:3); theta = var(4); phi = var(5); psi = 0; if length(var) > 5 psi = var(6); end elseif nargin == 4 % arguments = center, then the 3 angles center = varargin{1}; theta = varargin{2}; phi = varargin{3}; psi = varargin{4}; elseif nargin > 4 % center is given in 3 arguments, then 3 angles center = [varargin{1} varargin{2} varargin{3}]; theta = varargin{4}; phi = varargin{5}; psi = 0; if nargin > 5 psi = varargin{6}; end end % conversion from degrees to radians k = pi / 180; % rotation around normal vector axis rot1 = createRotationOz(psi * k); % colatitude rot2 = createRotationOy(theta * k); % longitude rot3 = createRotationOz(phi * k); % shift center tr = createTranslation3d(center); % create final transform by concatenating transforms trans = tr * rot3 * rot2 * rot1; matgeom-1.2.4/inst/meshes3d/private/PaxHeaders/formatMeshOutput.m0000644000000000000000000000013214576357161022112 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/private/formatMeshOutput.m0000644000175000017500000000660414576357161023700 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function res = formatMeshOutput(nbArgs, vertices, edges, faces) %FORMATMESHOUTPUT Format mesh output depending on nargout. % % OUTPUT = formatMeshOutput(NARGOUT, VERTICES, EDGES, FACES) % Utilitary function to convert mesh data . % If NARGOUT is 0 or 1, return a matlab structure with fields vertices, % edges and faces. % If NARGOUT is 2, return a cell array with data VERTICES and FACES. % If NARGOUT is 3, return a cell array with data VERTICES, EDGES and % FACES. % % OUTPUT = formatMeshOutput(NARGOUT, VERTICES, FACES) % Same as before, but do not intialize EDGES in output. NARGOUT can not % be equal to 3. % % Example % % Typical calling sequence (for a very basic mesh of only one face) % v = [0 0; 0 1;1 0;1 1]; % e = [1 2;1 3;2 4;3 4]; % f = [1 2 3 4]; % % varargout = formatMeshOutput(nargout, v, e, f); % % See also % meshes3d, parseMeshData % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-12-06, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform if nargin < 4 faces = edges; edges = []; end switch nbArgs case {0, 1} % output is a data structure with fields vertices, edges and faces mesh.vertices = vertices; if ~isempty(edges) mesh.edges = edges; end mesh.faces = faces; res = {mesh}; case 2 % keep only vertices and faces res = cell(nbArgs, 1); res{1} = vertices; res{2} = faces; case 3 % return vertices, edges and faces as 3 separate outputs res = cell(nbArgs, 1); res{1} = vertices; res{2} = edges; res{3} = faces; otherwise error('Cannot manage more than 3 outputs'); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/meshCurvatures.m0000644000000000000000000000013214576357161020132 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/meshCurvatures.m0000644000175000017500000002211314576357161021711 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [C1, C2, U1, U2, H, K, N] = meshCurvatures(vertices, faces, varargin) %MESHCURVATURES Compute principal curvatures on mesh vertices. % % [C1, C2] = meshCurvatures(VERTICES, FACES) % Computes the principal curvatures C1 and C2 for each vertex of the mesh % defined by VERTICES and FACES. % % [C1, C2] = meshCurvatures(..., PNAME, PVALUE) % Provides additional input arguments based on a list of name-value pairs % of arguments. Parameter names can be: % * 'SmoothingSteps' (integer, default: 3) % Specifies the number of steps for smoothing vertex curvature % tensors. % * 'Verbose' (boolean, default: true) % Displays details about algorithm processing. % * 'ShowProgress' (boolean, default: true) % Displays a text-based progress bar. % % Algorithm % The function is adapted from the "compute_curvature" function, in the % "toolbox_graph" from Gabriel Peyre. % The basic idea is to define a curvature tensor for each edge, by % assigning a minimum curvature equal to zero along the edge, and a % maximum curvature equal to the dihedral angle across the edge. % Averaging around the neighbors of a vertex v yields a summation formula % over the neighbor edges to compute the curvature tensor of a vertex: % 1 % C(v) = ---- Sum \beta(e) || e \cap A(v) || ebar ebar^t % A(v) {e \in A(v)} % where: % * A(v) is the neighborhood region, usually defined as a 'ring' around % the vertex v % * beta(e) is the dihedral angle between the normals of the two faces % incident to edge e % * || e \cap A(v) || is the length of e (more exactly, the length of the % part of e contained within the neighborhood region % * ebar is the normalized edge % % The curvature tensor is then decomposed into C = P D P^-1, with P % containing main direction vectors and normal, and D being a diagonal % matrix with the two main curvatures and zero along the diagonal. % % References % * David Cohen-Steiner and Jean-Marie Morvan (2003). % "Restricted Delaunay triangulations and normal cycle". % In Proc. 19th Annual ACM Symposium on Computational Geometry, % pages 237-246. % * Pierre Alliez, David Cohen-Steiner, Olivier Devillers, Bruno Levy, % and Mathieu Desbrun (2003). "Anisotropic Polygonal Remeshing". % ACM Transactions on Graphics. % (SIGGRAPH '2003 Conference Proceedings) % * Mario Botsch, Leif Kobbelt, M. Pauly, P. Alliez, B. Levy (2010). % "Polygon Mesh Processing", Taylor and Francis Group, New York. % % Example % [v, f] = torusMesh; % f2 = triangulateFaces(f); % [c1, c2] = meshCurvatures(v, f2); % figure; hold on; axis equal; view(3); % drawMesh(v, f2, 'VertexColor', c1 .* c2); % % See also % meshes3d, drawMesh, triangulateFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2021-09-21, using Matlab 9.10.0.1684407 (R2021a) Update 3 % Copyright 2021-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Process input arguments % default values for options nIters = 3; verbose = true; showProgress = true; while length(varargin) > 1 name = varargin{1}; if strcmpi(name, 'SmoothingSteps') nIters = varargin{2}; elseif strcmpi(name, 'Verbose') verbose = varargin{2}; elseif strcmpi(name, 'ShowProgress') showProgress = varargin{2}; else error('Unknown option: %s', name); end varargin(1:2) = []; end % validate vertices if ~isnumeric(vertices) || size(vertices, 2) ~= 3 error('Requires vertices to be a N-by-3 numeric array'); end % ensure faces are triangular if ~isnumeric(faces) || size(faces, 2) > 3 warning('requires triangle mesh, forces triangulation'); faces = triangulateFaces(faces); end %% Retrieve adjacency relationships if verbose disp('compute adjacencies'); end % number of elements of each type nv = size(vertices, 1); nf = size(faces, 1); % ev1 and ev2 are indices of source and target vertex of each edge % (recomputed later) ev1 = [faces(:,1); faces(:,2); faces(:,3)]; ev2 = [faces(:,2); faces(:,3); faces(:,1)]; % Compute sparse matrix representing edge-to-face adjacency s = [1:nf 1:nf 1:nf]'; A = sparse(ev1, ev2, s, nv, nv); % converts sparse matrix to indices of adjacent vertices and faces [~, ~, ef1] = find(A); % index of 'right' face [ev1, ev2, ef2] = find(A'); % index of 'left' face, and of vertices % edges are consdered twice (one for each vertex) % keep only the edge with lower source index inds = find(ev1 < ev2); ef1 = ef1(inds); ef2 = ef2(inds); ev1 = ev1(inds); ev2 = ev2(inds); % number of edges ne = length(ev1); %% Compute geometry features % compute edge direction vectors edgeVectors = vertices(ev2,:) - vertices(ev1,:); % normalize edge direction vecotrs d = sqrt(sum(edgeVectors.^2, 2)); edgeVectors = bsxfun(@rdivide, edgeVectors, d); % avoid too large numerics d = d ./ mean(d); % normals to faces normals = meshFaceNormals(vertices, faces); % ensure normals point outward the mesh if meshVolume(vertices, faces) < 0 normals = -normals; end % inner product of normals dp = sum(normals(ef1, :) .* normals(ef2, :), 2); % compute the (unsigned) dihedral angle between the normals of the two % faces incident to each edge beta = acos(min(max(dp, -1), 1)); % relatice orientation of face normals cross product and edge orientation cp = crossProduct3d(normals(ef1, :), normals(ef2, :)); si = sign(sum(cp .* edgeVectors, 2)); % compute signed dihedral angle beta = beta .* si; %% Compute tensors if verbose disp('compute edge tensors'); end % curvature tensor of each edge T = zeros(3, 3, ne); for i = 1:3 for j = 1:i T(i, j, :) = reshape(edgeVectors(:,i) .* edgeVectors(:,j), 1, 1, ne); T(j, i, :) = T(i, j, :); end end T = bsxfun(@times, T, reshape(d .* beta, [1 1 ne])); % curvature tensor of each vertex by pooling edge tensors Tv = zeros(3, 3, nv); w = zeros(1, 1, nv); for k = 1:ne if showProgress progressbar(k, ne); end Tv(:,:,ev1(k)) = Tv(:,:,ev1(k)) + T(:,:,k); Tv(:,:,ev2(k)) = Tv(:,:,ev2(k)) + T(:,:,k); w(:,:,ev1(k)) = w(:,:,ev1(k)) + 1; w(:,:,ev2(k)) = w(:,:,ev2(k)) + 1; end w(w < eps) = 1; Tv = Tv ./ repmat(w, [3 3 1]); if verbose disp('average vertex tensors'); end % apply smoothing on the tensor field for i = 1:3 for j = 1:3 a = Tv(i, j, :); a = smoothMeshFunction(vertices, faces, a(:), nIters); Tv(i, j, :) = reshape(a, [1 1 nv]); end end %% Retrieve curvatures and eigen vectors from tensors if verbose disp('retrieve curvatures'); end % allocate memory U = zeros(3, 3, nv); D = zeros(3, nv); % iterate over vertices for k = 1:nv % display progress if showProgress progressbar(k,nv); end % extract eigenvectors and eigenvalues for current vertex [u, d] = eig(Tv(:,:,k)); d = real(diag(d)); % sort acording to [normal, min curv, max curv] [~, I] = sort(abs(d)); D(:, k) = d(I); U(:, :, k) = real(u(:,I)); end % retrieve main curvatures and associated directions C1 = D(2,:)'; C2 = D(3,:)'; U1 = squeeze(U(:,3,:))'; U2 = squeeze(U(:,2,:))'; % enforce C1 < C2 inds = find(C1 > C2); C1tmp = C1; U1tmp = U1; C1(inds) = C2(inds); C2(inds) = C1tmp(inds); U1(inds,:) = U2(inds,:); U2(inds,:) = U1tmp(inds,:); % compute optional output arguments if nargout > 4 % average and gaussian curvatures H = (C1 + C2) / 2; K = C1 .* C2; if nargout > 6 % normal vector for each vertex N = squeeze(U(:,1,:))'; end end matgeom-1.2.4/inst/meshes3d/PaxHeaders/isManifoldMesh.m0000644000000000000000000000013214576357161020014 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/isManifoldMesh.m0000644000175000017500000000661014576357161021577 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [b1, b2] = isManifoldMesh(varargin) %ISMANIFOLDMESH Check whether the input mesh may be considered as manifold. % % B = isManifoldMesh(V, F) % B = isManifoldMesh(V, E, F) % Checks if the specified mesh is a manifold. When mesh is a manifold, % all edges are connected to either 2 or 1 faces. % % [B, HASBORDER] = isManifoldMesh(V, E, F) % Also checks whether the mesh contains border faces. Border faces % contains at least one edge which is ajacent to only one face. % % Example % [V, F] = createOctahedron; % isManifoldMesh(V, F) % ans = % logical % 1 % % See also % meshes3d, ensureManifoldMesh, trimMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2019-01-31, using Matlab 9.5.0.944444 (R2018b) % Copyright 2019-2023 INRA - Cepia Software Platform vertices = varargin{1}; faces = varargin{2}; % compute edge to vertex array if nargin == 3 edges = faces; faces = varargin{3}; else % compute edge to vertex array edges = meshEdges(faces); end % compute face to edge indices array % as a nFaces-by-3 array (each face connected to exactly three edges) faceEdgeInds = meshFaceEdges(vertices, edges, faces); % compute number of faces incident each edge edgeFaces = trimeshEdgeFaces(faces); edgeFaceDegrees = sum(edgeFaces > 0, 2); % for each face, concatenate the face degree of each edge faceEdgeDegrees = zeros(size(faces, 1), 3); for iFace = 1:size(faces, 1) edgeInds = faceEdgeInds{iFace}; faceEdgeDegrees(iFace, :) = edgeFaceDegrees(edgeInds); end regFaces = sum(ismember(faceEdgeDegrees, [1 2]), 2) == 3; innerFaces = sum(faceEdgeDegrees == 2, 2) == 3; borderFaces = regFaces & ~innerFaces; % check if mesh is manifold: all faces are either regular or border b1 = all(regFaces); % check if some faces are border b2 = any(borderFaces); matgeom-1.2.4/inst/meshes3d/PaxHeaders/README.md0000644000000000000000000000013214576357160016212 xustar0030 mtime=1710874224.670193794 30 atime=1710874224.670193794 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/README.md0000644000175000017500000000630314576357160017774 0ustar00juanpijuanpi00000000000000# matGeom/meshes3d Creation, visualization, and manipulation of 3D surface meshes or polyhedra. Meshes and polyhedra are represented by the variables V, F: * V: NV-by-3 array of vertices: [x1 y1 z1; ... ; xn yn zn]. * F: is either a NF-by-3 or NF-by-4 array containing reference for vertices of each face, or a NF-by-1 cell array, where each cell is an array containing a variable number of node indices. * [E: NE-by-2 array of edges is needed only for some functions. It contains indices of source and target vertices of the edges. The function [meshEdges](https://github.com/mattools/matGeom/blob/master/matGeom/meshes3d/meshEdges.m) can be used to create the edge array.] Some functions are implemented only for triangular surface meshes (V: NV-by-3, F: NF-by-3). The function [triangulateFaces](https://github.com/mattools/matGeom/blob/master/matGeom/meshes3d/triangulateFaces.m) can be used to convert other representation into a triangular mesh. Alternatively, the mesh can be passed to most of the functions as struct with the fields 'vertices' and 'faces' (and 'edges', if necessary) and the processed mesh is also returned as struct if only one output argument is called. The library provides function to create basic polyhedric meshes (the five platonic solids, plus few others), as well as functions to perform basic computations (surface area, normal angles, face centroids, ...). The [MengerSponge](https://github.com/mattools/matGeom/blob/master/matGeom/meshes3d/createMengerSponge.m) structure is an example of mesh that is not simply connected (multiple tunnels in the structure). The drawMesh function is mainly a wrapper to the Matlab 'patch' function, allowing passing arguments more quickly. Simple example: ```matlab:Code(Display) % Create a soccer ball mesh and display it mesh = createSoccerBall; figure('color','w') drawMesh(mesh, 'faceColor', 'g', 'linewidth', 2); axis equal; view(3); ``` ![grafik](https://github.com/mattools/matGeom/assets/15254908/79c759e2-ea85-435e-8a6c-9b6961329437) Some functions require lines, planes, spheres or boxes from [geom3d](https://github.com/mattools/matGeom/tree/master/matGeom/geom3d) as additional input in combination with the mesh. ```matlab:Code(Display) nPoints = 200; % Number of vertices of trefoil curve thickness = .5; % Thickness of the 3D mesh nCorners = 16; % Number of corners around each curve vertex t = linspace(0, 2*pi, nPoints + 1); % parameterization variable t(end) = []; % Trefoil curve coordinates curve(:,1) = sin(t) + 2 * sin(2 * t); curve(:,2) = cos(t) - 2 * cos(2 * t); curve(:,3) = -sin(3 * t); % Create surrounding mesh [v2, f2] = curveToMesh(curve, thickness, nCorners); f2 = triangulateFaces(f2); % Clip the mesh by a plane plane = createPlane([0 0 0], [0.5 0.5 1]); [v2, f2, bE] = clipMeshByPlane(v2, f2, plane, 'part','above'); % Display results figure('color','w'); drawPolygon3d(curve, 'LineWidth', 4, 'color', 'b'); axis equal; view(3); drawMesh(v2, f2, 'FaceAlpha', 0.5); drawPlane3d(plane) drawEdge3d([v2(bE(:,1),:),v2(bE(:,2),:)],'Color','g','LineWidth',4) ``` ![grafik](https://github.com/mattools/matGeom/assets/15254908/e4a11e3e-53c6-4080-b243-b15a55c4534d)matgeom-1.2.4/inst/meshes3d/PaxHeaders/clipMeshByPlane.m0000644000000000000000000000013214576357161020131 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/clipMeshByPlane.m0000644000175000017500000001252114576357161021712 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [v2, f2, bE] = clipMeshByPlane(v, f, plane, varargin) %CLIPMESHBYPLANE Clip a mesh by a plane. % % [V2, F2] = clipMeshByPlane(V, F, PLANE) % Clip a mesh defined by the vertices V and faces F by a PLANE and return % the part of the mesh (V2, F2) above the plane. % % [V2, F2, ENEW] = clipMeshByPlane(V, F, PLANE) % Additonally returns the new boundary edges created by the clipping of % the mesh. % % [...] = clipMeshByPlane(V, F, PLANE, 'part', 'below') % Gives the part of the mesh below the plane. The options are: % 'part','above': Mesh above the plane [default] % 'part','below': Mesh below the plane % % Example % % Create trefoil curve % nPoints = 200; % Number of vertices of trefoil curve % thickness = .5; % Thickness of the 3D mesh % nCorners = 16; % Number of corners around each curve vertex % t = linspace(0, 2*pi, nPoints + 1); % parameterisation variable % t(end) = []; % % Trefoil curve coordinates % curve(:,1) = sin(t) + 2 * sin(2 * t); % curve(:,2) = cos(t) - 2 * cos(2 * t); % curve(:,3) = -sin(3 * t); % % Create surrounding mesh % [v2, f2] = curveToMesh(curve, thickness, nCorners); % f2 = triangulateFaces(f2); % % Clip the mesh by a plane % plane = createPlane([0 0 0], [0.5 0.5 1]); % [v2, f2, bE] = clipMeshByPlane(v2, f2, plane, 'part','above'); % % Display results % figure('color','w'); % drawPolygon3d(curve, 'LineWidth', 4, 'color', 'b'); % axis equal; view(3); % drawMesh(v2, f2, 'FaceAlpha', 0.5); % drawPlane3d(plane) % drawEdge3d([v2(bE(:,1),:),v2(bE(:,2),:)],'Color','g','LineWidth',4) % % See also % cutMeshByPlane, intersectPlaneMesh % % Source % half_space_intersect.m by Alec Jacobson: % https://github.com/alecjacobson/gptoolbox % ------ % Author: oqilipo % E-mail: N/A % Created: 2023-05-18, using Matlab 9.13.0.2080170 (R2022b) Update 1 % Copyright 2023 %% Parse input if isstruct(v) if nargin > 2 varargin = [plane, varargin]; end plane = f; f = v.faces; v = v.vertices; end p = inputParser; addRequired(p,'plane',@isPlane) validStrings = {'above','below'}; addParameter(p,'part','above',@(x) any(validatestring(x, validStrings))) parse(p, plane, varargin{:}); part=p.Results.part; p = plane(1:3); switch part case 'above' n = planeNormal(plane); case 'below' n = planeNormal(reversePlane(plane)); end % Homogeneous coordinates IV = sum(bsxfun(@times, [v(:,1:3) ones(size(v,1), 1)], [n(:)' -dot(p,n)]), 2); IF = IV(f); IF = reshape(IF, size(f)); I13 = sum(IF<0, 2) == 1; [VV1, E13, ~, F13above, ~] = one_below(v, f(I13,:), IF(I13,:)); I31 = sum(IF>0, 2) == 1; [VV2, E31, F31below, ~, ~] = one_below(VV1, f(I31,:), -IF(I31,:)); above = all(IF>=0, 2); FF2 = [f(above,:); F13above; F31below]; % birth = [find(above); repmat(find(I13),2,1); find(I31)]; EE2 = [E13; E31]; % Remove duplicate vertices bbd = norm(max(v)-min(v)); [vIdx, fIdx] = removeDuplicateVertices(VV2, FF2, 1e-14*bbd, 'IndexOutput',1); VV3 = VV2(vIdx,:); FF3 = fIdx(FF2); EE3 = fIdx(EE2); % Remove unreferenced/unindexed vertices [vIdx, fIdx] = removeUnreferencedVertices(VV3, FF3, 'IndexOutput',1); v2 = VV3(vIdx,:); f2 = fIdx(FF3); bE = fIdx(EE3); end function [U, E, Fbelow, Fabove, BC] = one_below(V, F, IF) [~, J] = min(IF, [], 2); I = sub2ind(size(F), repmat(1:size(F,1), size(F,2),1)', mod([J J+1 J+2]-1, 3)+1); lambda = IF(I(:,2:3))./bsxfun(@minus,IF(I(:,2:3)),IF(I(:,1))); BC = sparse( ... repmat((1:size(F,1)*2)', 1, 2), ... [repmat(F(I(:,1)),2,1) reshape(F(I(:,2:3)), size(F,1)*2,1)], ... [lambda(:) 1-lambda(:)], ... size(F,1)*2, size(V,1)); E = size(V, 1) + bsxfun(@plus, 1:size(F,1), [0;1]*size(F,1))'; U = [V; BC*V]; Fbelow = [F(I(:,1)) E]; Fabove = [F(I(:,2)) fliplr(E); F(I(:,2:3)) E(:,2)]; end matgeom-1.2.4/inst/meshes3d/PaxHeaders/teapot.obj0000644000000000000000000000013214576357160016723 xustar0030 mtime=1710874224.682193781 30 atime=1710874224.682193781 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/teapot.obj0000644000175000017500000014444514576357160020517 0ustar00juanpijuanpi00000000000000# OBJ file created by ply_to_obj.c # g Object001 v 40.6266 28.3457 -1.10804 v 40.0714 30.4443 -1.10804 v 40.7155 31.1438 -1.10804 v 42.0257 30.4443 -1.10804 v 43.4692 28.3457 -1.10804 v 37.5425 28.3457 14.5117 v 37.0303 30.4443 14.2938 v 37.6244 31.1438 14.5466 v 38.8331 30.4443 15.0609 v 40.1647 28.3457 15.6274 v 29.0859 28.3457 27.1468 v 28.6917 30.4443 26.7527 v 29.149 31.1438 27.2099 v 30.0792 30.4443 28.1402 v 31.1041 28.3457 29.165 v 16.4508 28.3457 35.6034 v 16.2329 30.4443 35.0912 v 16.4857 31.1438 35.6853 v 16.9999 30.4443 36.894 v 17.5665 28.3457 38.2256 v 0.831025 28.3457 38.6876 v 0.831025 30.4443 38.1324 v 0.831025 31.1438 38.7764 v 0.831025 30.4443 40.0866 v 0.831025 28.3457 41.5301 v -15.868 28.3457 35.6034 v -15.0262 30.4443 35.0912 v -14.9585 31.1438 35.6853 v -15.3547 30.4443 36.894 v -15.9044 28.3457 38.2256 v -28.3832 28.3457 27.1468 v -27.4344 30.4443 26.7527 v -27.6068 31.1438 27.2099 v -28.4322 30.4443 28.1402 v -29.4421 28.3457 29.165 v -36.2402 28.3457 14.5117 v -35.52 30.4443 14.2938 v -36.0073 31.1438 14.5466 v -37.1767 30.4443 15.0609 v -38.5027 28.3457 15.6274 v -38.9646 28.3457 -1.10804 v -38.4094 30.4443 -1.10804 v -39.0534 31.1438 -1.10804 v -40.3636 30.4443 -1.10804 v -41.8071 28.3457 -1.10804 v -35.8804 28.3457 -16.7278 v -35.3683 30.4443 -16.5099 v -35.9624 31.1438 -16.7627 v -37.1711 30.4443 -17.2769 v -38.5027 28.3457 -17.8435 v -27.4238 28.3457 -29.3629 v -27.0297 30.4443 -28.9687 v -27.4869 31.1438 -29.426 v -28.4172 30.4443 -30.3562 v -29.4421 28.3457 -31.3811 v -14.7887 28.3457 -37.8195 v -14.5708 30.4443 -37.3073 v -14.8236 31.1438 -37.9014 v -15.3379 30.4443 -39.1101 v -15.9044 28.3457 -40.4417 v 0.831025 28.3457 -40.9036 v 0.831025 30.4443 -40.3484 v 0.831025 31.1438 -40.9925 v 0.831025 30.4443 -42.3027 v 0.831025 28.3457 -43.7462 v 16.4508 28.3457 -37.8195 v 16.2329 30.4443 -37.3073 v 16.4857 31.1438 -37.9014 v 16.9999 30.4443 -39.1101 v 17.5665 28.3457 -40.4417 v 29.0859 28.3457 -29.3629 v 28.6917 30.4443 -28.9687 v 29.149 31.1438 -29.426 v 30.0792 30.4443 -30.3562 v 31.1041 28.3457 -31.3811 v 37.5425 28.3457 -16.7278 v 37.0303 30.4443 -16.5099 v 37.6244 31.1438 -16.7627 v 38.8331 30.4443 -17.2769 v 40.1647 28.3457 -17.8435 v 48.6879 17.1865 -1.10804 v 53.2404 6.22714 -1.10804 v 56.4605 -4.33246 -1.10804 v 57.6819 -14.2925 -1.10804 v 44.979 17.1865 17.6758 v 49.1787 6.22714 19.4626 v 52.1492 -4.33246 20.7265 v 53.2759 -14.2925 21.2059 v 34.8094 17.1865 32.8703 v 38.0417 6.22714 36.1026 v 40.3279 -4.33246 38.3889 v 41.1951 -14.2925 39.2561 v 19.6148 17.1865 43.0399 v 21.4017 6.22714 47.2396 v 22.6656 -4.33246 50.2101 v 23.145 -14.2925 51.3369 v 0.831025 17.1865 46.7488 v 0.831025 6.22714 51.3013 v 0.831025 -4.33246 54.5214 v 0.831025 -14.2925 55.7428 v -17.9528 17.1865 43.0399 v -19.7397 6.22714 47.2396 v -21.0035 -4.33246 50.2101 v -21.4829 -14.2925 51.3369 v -33.1474 17.1865 32.8703 v -36.3796 6.22714 36.1026 v -38.6659 -4.33246 38.3889 v -39.5331 -14.2925 39.2561 v -43.3169 17.1865 17.6758 v -47.5166 6.22714 19.4626 v -50.4871 -4.33246 20.7265 v -51.6139 -14.2925 21.2059 v -47.0258 17.1865 -1.10804 v -51.5784 6.22714 -1.10804 v -54.7984 -4.33246 -1.10804 v -56.0198 -14.2925 -1.10804 v -43.3169 17.1865 -19.8919 v -47.5166 6.22714 -21.6787 v -50.4871 -4.33246 -22.9426 v -51.6139 -14.2925 -23.422 v -33.1474 17.1865 -35.0864 v -36.3796 6.22714 -38.3187 v -38.6659 -4.33246 -40.6049 v -39.5331 -14.2925 -41.4721 v -17.9528 17.1865 -45.256 v -19.7397 6.22714 -49.4557 v -21.0035 -4.33246 -52.4262 v -21.4829 -14.2925 -53.5529 v 0.831025 17.1865 -48.9649 v 0.831025 6.22714 -53.5174 v 0.831025 -4.33246 -56.7375 v 0.831025 -14.2925 -57.9589 v 19.6148 17.1865 -45.256 v 21.4017 6.22714 -49.4557 v 22.6656 -4.33246 -52.4262 v 23.145 -14.2925 -53.5529 v 34.8094 17.1865 -35.0864 v 38.0417 6.22714 -38.3187 v 40.3279 -4.33246 -40.6049 v 41.1951 -14.2925 -41.4721 v 44.979 17.1865 -19.8919 v 49.1787 6.22714 -21.6787 v 52.1492 -4.33246 -22.9426 v 53.2759 -14.2925 -23.422 v 55.4611 -22.7202 -1.10804 v 50.5755 -28.9493 -1.10804 v 45.6899 -33.1798 -1.10804 v 43.4692 -35.6115 -1.10804 v 51.2273 -22.7202 20.3343 v 46.7203 -28.9493 18.4167 v 42.2133 -33.1798 16.4991 v 40.1647 -35.6115 15.6274 v 39.6184 -22.7202 37.6793 v 36.1496 -28.9493 34.2106 v 32.6808 -33.1798 30.7418 v 31.1041 -35.6115 29.165 v 22.2733 -22.7202 49.2882 v 20.3557 -28.9493 44.7813 v 18.4381 -33.1798 40.2743 v 17.5665 -35.6115 38.2256 v 0.831025 -22.7202 53.5221 v 0.831025 -28.9493 48.6365 v 0.831025 -33.1798 43.7508 v 0.831025 -35.6115 41.5301 v -20.6113 -22.7202 49.2882 v -18.6937 -28.9493 44.7813 v -16.7761 -33.1798 40.2743 v -15.9044 -35.6115 38.2256 v -37.9564 -22.7202 37.6793 v -34.4876 -28.9493 34.2106 v -31.0188 -33.1798 30.7418 v -29.4421 -35.6115 29.165 v -49.5653 -22.7202 20.3343 v -45.0583 -28.9493 18.4167 v -40.5513 -33.1798 16.4991 v -38.5027 -35.6115 15.6274 v -53.7991 -22.7202 -1.10804 v -48.9135 -28.9493 -1.10804 v -44.0279 -33.1798 -1.10804 v -41.8071 -35.6115 -1.10804 v -49.5653 -22.7202 -22.5504 v -45.0583 -28.9493 -20.6327 v -40.5513 -33.1798 -18.7151 v -38.5027 -35.6115 -17.8435 v -37.9564 -22.7202 -39.8954 v -34.4876 -28.9493 -36.4266 v -31.0188 -33.1798 -32.9578 v -29.4421 -35.6115 -31.3811 v -20.6113 -22.7202 -51.5043 v -18.6937 -28.9493 -46.9973 v -16.7761 -33.1798 -42.4903 v -15.9044 -35.6115 -40.4417 v 0.831025 -22.7202 -55.7382 v 0.831025 -28.9493 -50.8525 v 0.831025 -33.1798 -45.9669 v 0.831025 -35.6115 -43.7462 v 22.2733 -22.7202 -51.5043 v 20.3557 -28.9493 -46.9973 v 18.4381 -33.1798 -42.4903 v 17.5665 -35.6115 -40.4417 v 39.6184 -22.7202 -39.8954 v 36.1496 -28.9493 -36.4266 v 32.6808 -33.1798 -32.9578 v 31.1041 -35.6115 -31.3811 v 51.2273 -22.7202 -22.5504 v 46.7203 -28.9493 -20.6327 v 42.2133 -33.1798 -18.7151 v 40.1647 -35.6115 -17.8435 v 42.5031 -37.1772 -1.10804 v 37.3399 -38.5429 -1.10804 v 24.5818 -39.5089 -1.10804 v 0.831025 -39.8754 -1.10804 v 39.2736 -37.1772 15.2483 v 34.5105 -38.5429 13.2217 v 22.7411 -39.5089 8.21414 v 30.4182 -37.1772 28.4792 v 26.7523 -38.5429 24.8133 v 17.6941 -39.5089 15.755 v 17.1873 -37.1772 37.3345 v 15.1608 -38.5429 32.5714 v 10.1532 -39.5089 20.8021 v 0.831025 -37.1772 40.5641 v 0.831025 -38.5429 35.4009 v 0.831025 -39.5089 22.6427 v -15.5253 -37.1772 37.3345 v -13.4987 -38.5429 32.5714 v -8.49115 -39.5089 20.8021 v -28.7562 -37.1772 28.4792 v -25.0903 -38.5429 24.8133 v -16.032 -39.5089 15.755 v -37.6115 -37.1772 15.2483 v -32.8484 -38.5429 13.2217 v -21.0791 -39.5089 8.21414 v -40.8411 -37.1772 -1.10804 v -35.6779 -38.5429 -1.10804 v -22.9198 -39.5089 -1.10804 v -37.6115 -37.1772 -17.4643 v -32.8484 -38.5429 -15.4378 v -21.0791 -39.5089 -10.4302 v -28.7562 -37.1772 -30.6952 v -25.0903 -38.5429 -27.0294 v -16.032 -39.5089 -17.9711 v -15.5253 -37.1772 -39.5506 v -13.4987 -38.5429 -34.7875 v -8.49115 -39.5089 -23.0181 v 0.831025 -37.1772 -42.7802 v 0.831025 -38.5429 -37.6169 v 0.831025 -39.5089 -24.8588 v 17.1873 -37.1772 -39.5506 v 15.1608 -38.5429 -34.7875 v 10.1532 -39.5089 -23.0181 v 30.4182 -37.1772 -30.6952 v 26.7523 -38.5429 -27.0294 v 17.6941 -39.5089 -17.9711 v 39.2736 -37.1772 -17.4643 v 34.5105 -38.5429 -15.4378 v 22.7411 -39.5089 -10.4302 v -44.6497 17.6861 -1.10804 v -57.9297 17.5862 -1.10804 v -67.7453 16.8867 -1.10804 v -73.8301 14.9879 -1.10804 v -75.9176 11.2904 -1.10804 v -44.2055 18.6855 3.68876 v -58.3252 18.5699 3.68876 v -68.6891 17.7611 3.68876 v -75.0724 15.5657 3.68876 v -77.2501 11.2904 3.68876 v -43.2284 20.884 5.28769 v -59.1955 20.7341 5.28769 v -70.7655 19.6848 5.28769 v -77.8053 16.8367 5.28769 v -80.1814 11.2904 5.28769 v -42.2513 23.0825 3.68876 v -60.0657 22.8983 3.68876 v -72.8419 21.6085 3.68876 v -80.5381 18.1077 3.68876 v -83.1128 11.2904 3.68876 v -41.8071 24.0819 -1.10804 v -60.4613 23.882 -1.10804 v -73.7857 22.4829 -1.10804 v -81.7804 18.6855 -1.10804 v -84.4453 11.2904 -1.10804 v -42.2513 23.0825 -5.90483 v -60.0657 22.8983 -5.90483 v -72.8419 21.6085 -5.90483 v -80.5381 18.1077 -5.90483 v -83.1128 11.2904 -5.90483 v -43.2284 20.884 -7.50376 v -59.1955 20.7341 -7.50376 v -70.7655 19.6848 -7.50376 v -77.8053 16.8367 -7.50376 v -80.1814 11.2904 -7.50376 v -44.2055 18.6855 -5.90483 v -58.3252 18.5699 -5.90483 v -68.6891 17.7611 -5.90483 v -75.0724 15.5657 -5.90483 v -77.2501 11.2904 -5.90483 v -74.8073 5.4943 -1.10804 v -71.2985 -1.50103 -1.10804 v -65.1248 -8.49634 -1.10804 v -56.0198 -14.2925 -1.10804 v -76.0183 4.93477 3.68876 v -72.159 -2.35462 3.68876 v -65.4267 -9.55033 3.68876 v -55.5757 -15.6249 3.68876 v -78.6824 3.70383 5.28769 v -74.0522 -4.23253 5.28769 v -66.0909 -11.8691 5.28769 v -54.5986 -18.5563 5.28769 v -81.3466 2.47288 3.68876 v -75.9454 -6.11044 3.68876 v -66.755 -14.1878 3.68876 v -53.6214 -21.4877 3.68876 v -82.5576 1.91336 -1.10804 v -76.8059 -6.96404 -1.10804 v -67.0569 -15.2418 -1.10804 v -53.1773 -22.8201 -1.10804 v -81.3466 2.47288 -5.90483 v -75.9454 -6.11044 -5.90483 v -66.755 -14.1878 -5.90483 v -53.6214 -21.4877 -5.90483 v -78.6824 3.70383 -7.50376 v -74.0522 -4.23253 -7.50376 v -66.0909 -11.8691 -7.50376 v -54.5986 -18.5563 -7.50376 v -76.0183 4.93477 -5.90483 v -72.159 -2.35462 -5.90483 v -65.4267 -9.55033 -5.90483 v -55.5757 -15.6249 -5.90483 v 49.1543 0.630882 -1.10804 v 62.7896 3.76212 -1.10804 v 68.6967 11.2904 -1.10804 v 71.939 20.4176 -1.10804 v 77.5797 28.3457 -1.10804 v 49.1543 -3.03333 9.4449 v 63.8305 1.04519 8.42059 v 70.0292 9.70814 6.1671 v 73.5629 19.8451 3.91361 v 80.2446 28.3457 2.88929 v 49.1543 -11.0946 12.9626 v 66.1207 -4.93206 11.5968 v 72.9605 6.22714 8.59214 v 77.1355 18.5855 5.58749 v 86.1073 28.3457 4.22173 v 49.1543 -19.1559 9.4449 v 68.4108 -10.9093 8.42059 v 75.8919 2.74614 6.1671 v 80.7081 17.326 3.91361 v 91.97 28.3457 2.88929 v 49.1543 -22.8201 -1.10804 v 69.4518 -13.6262 -1.10804 v 77.2244 1.16386 -1.10804 v 82.3321 16.7534 -1.10804 v 94.6349 28.3457 -1.10804 v 49.1543 -19.1559 -11.661 v 68.4108 -10.9093 -10.6367 v 75.8919 2.74614 -8.38317 v 80.7081 17.326 -6.12968 v 91.97 28.3457 -5.10536 v 49.1543 -11.0946 -15.1786 v 66.1207 -4.93206 -13.8129 v 72.9605 6.22714 -10.8082 v 77.1355 18.5855 -7.80356 v 86.1073 28.3457 -6.4378 v 49.1543 -3.03333 -11.661 v 63.8305 1.04519 -10.6367 v 70.0292 9.70814 -8.38317 v 73.5629 19.8451 -6.12968 v 80.2446 28.3457 -5.10536 v 79.6227 29.5449 -1.10804 v 81.1329 29.9446 -1.10804 v 81.577 29.5449 -1.10804 v 80.4222 28.3457 -1.10804 v 82.4767 29.6034 2.63946 v 83.8116 30.0383 2.08983 v 83.8515 29.6268 1.54019 v 82.1988 28.3457 1.29036 v 88.7555 29.7322 3.88862 v 89.7049 30.2444 3.15578 v 88.8555 29.8072 2.42294 v 86.1073 28.3457 2.08983 v 95.0343 29.8611 2.63946 v 95.5982 30.4505 2.08983 v 93.8594 29.9875 1.54019 v 90.0158 28.3457 1.29036 v 97.8883 29.9196 -1.10804 v 98.2769 30.5442 -1.10804 v 96.1339 30.0695 -1.10804 v 91.7924 28.3457 -1.10804 v 95.0343 29.8611 -4.85553 v 95.5982 30.4505 -4.3059 v 93.8594 29.9875 -3.75626 v 90.0158 28.3457 -3.50643 v 88.7555 29.7322 -6.10469 v 89.7049 30.2444 -5.37185 v 88.8555 29.8072 -4.63901 v 86.1073 28.3457 -4.3059 v 82.4767 29.6034 -4.85553 v 83.8116 30.0383 -4.3059 v 83.8515 29.6268 -3.75626 v 82.1988 28.3457 -3.50643 v 0.831025 49.6647 -1.10804 v 10.5134 48.2657 -1.10804 v 10.0693 44.868 -1.10804 v 6.42728 40.6708 -1.10804 v 6.51611 36.8733 -1.10804 v 9.76642 48.2657 2.70243 v 9.35632 44.868 2.52698 v 5.9947 40.6708 1.09187 v 6.07552 36.8733 1.12336 v 7.71453 48.2657 5.77547 v 7.39819 44.868 5.45913 v 4.80736 40.6708 2.8683 v 4.86744 36.8733 2.92838 v 4.64149 48.2657 7.82736 v 4.46604 44.868 7.41726 v 3.03093 40.6708 4.05564 v 3.06242 36.8733 4.13646 v 0.831025 48.2657 8.57438 v 0.831025 44.868 8.13023 v 0.831025 40.6708 4.48822 v 0.831025 36.8733 4.57705 v -2.97944 48.2657 7.82736 v -2.80399 44.868 7.41726 v -1.36888 40.6708 4.05564 v -1.40037 36.8733 4.13646 v -6.05248 48.2657 5.77547 v -5.73614 44.868 5.45913 v -3.14531 40.6708 2.8683 v -3.20539 36.8733 2.92838 v -8.10437 48.2657 2.70243 v -7.69427 44.868 2.52698 v -4.33265 40.6708 1.09187 v -4.41347 36.8733 1.12336 v -8.85139 48.2657 -1.10804 v -8.40724 44.868 -1.10804 v -4.76523 40.6708 -1.10804 v -4.85406 36.8733 -1.10804 v -8.10437 48.2657 -4.9185 v -7.69427 44.868 -4.74305 v -4.33265 40.6708 -3.30794 v -4.41347 36.8733 -3.33943 v -6.05248 48.2657 -7.99154 v -5.73614 44.868 -7.6752 v -3.14531 40.6708 -5.08437 v -3.20539 36.8733 -5.14445 v -2.97944 48.2657 -10.0434 v -2.80399 44.868 -9.63333 v -1.36888 40.6708 -6.27171 v -1.40037 36.8733 -6.35253 v 0.831025 48.2657 -10.7904 v 0.831025 44.868 -10.3463 v 0.831025 40.6708 -6.70429 v 0.831025 36.8733 -6.79312 v 4.64149 48.2657 -10.0434 v 4.46604 44.868 -9.63333 v 3.03093 40.6708 -6.27171 v 3.06242 36.8733 -6.35253 v 7.71453 48.2657 -7.99154 v 7.39819 44.868 -7.6752 v 4.80736 40.6708 -5.08437 v 4.86744 36.8733 -5.14445 v 9.76642 48.2657 -4.9185 v 9.35632 44.868 -4.74305 v 5.9947 40.6708 -3.30794 v 6.07552 36.8733 -3.33943 v 13.8001 34.3417 -1.10804 v 24.282 32.6095 -1.10804 v 33.6979 30.8773 -1.10804 v 37.7841 28.3457 -1.10804 v 12.795 34.3417 3.98234 v 22.4646 32.6095 8.09647 v 31.1507 30.8773 11.7922 v 34.9202 28.3457 13.396 v 10.0391 34.3417 8.10003 v 17.4812 32.6095 15.5422 v 24.1665 30.8773 22.2275 v 27.0677 28.3457 25.1286 v 5.9214 34.3417 10.856 v 10.0355 32.6095 20.5255 v 13.7313 30.8773 29.2117 v 15.3351 28.3457 32.9812 v 0.831025 34.3417 11.8611 v 0.831025 32.6095 22.3429 v 0.831025 30.8773 31.7589 v 0.831025 28.3457 35.845 v -4.25935 34.3417 10.856 v -8.37348 32.6095 20.5255 v -12.0692 30.8773 29.2117 v -13.673 28.3457 32.9812 v -8.37704 34.3417 8.10003 v -15.8192 32.6095 15.5422 v -22.5045 30.8773 22.2275 v -25.4056 28.3457 25.1286 v -11.133 34.3417 3.98234 v -20.8025 32.6095 8.09647 v -29.4887 30.8773 11.7922 v -33.2582 28.3457 13.396 v -12.1381 34.3417 -1.10804 v -22.62 32.6095 -1.10804 v -32.0359 30.8773 -1.10804 v -36.122 28.3457 -1.10804 v -11.133 34.3417 -6.19841 v -20.8025 32.6095 -10.3125 v -29.4887 30.8773 -14.0083 v -33.2582 28.3457 -15.6121 v -8.37704 34.3417 -10.3161 v -15.8192 32.6095 -17.7582 v -22.5045 30.8773 -24.4435 v -25.4056 28.3457 -27.3447 v -4.25935 34.3417 -13.072 v -8.37348 32.6095 -22.7416 v -12.0692 30.8773 -31.4277 v -13.673 28.3457 -35.1972 v 0.831025 34.3417 -14.0771 v 0.831025 32.6095 -24.559 v 0.831025 30.8773 -33.9749 v 0.831025 28.3457 -38.0611 v 5.9214 34.3417 -13.072 v 10.0355 32.6095 -22.7416 v 13.7313 30.8773 -31.4277 v 15.3351 28.3457 -35.1972 v 10.0391 34.3417 -10.3161 v 17.4812 32.6095 -17.7582 v 24.1665 30.8773 -24.4435 v 27.0677 28.3457 -27.3447 v 12.795 34.3417 -6.19841 v 22.4646 32.6095 -10.3125 v 31.1507 30.8773 -14.0083 v 34.9202 28.3457 -15.6121 vn -0.966742 -0.255752 9.97231e-09 vn -0.966824 0.255443 3.11149e-08 vn -0.092052 0.995754 4.45989e-08 vn 0.68205 0.731305 0 vn 0.870301 0.492521 -4.87195e-09 vn -0.893014 -0.256345 -0.369882 vn -0.893437 0.255997 -0.369102 vn -0.0838771 0.995843 -0.0355068 vn 0.629724 0.73186 0.260439 vn 0.803725 0.49337 0.332584 vn -0.683407 -0.256729 -0.683407 vn -0.683531 0.256067 -0.683531 vn -0.0649249 0.995776 -0.0649248 vn 0.481398 0.732469 0.481398 vn 0.614804 0.493997 0.614804 vn -0.369882 -0.256345 -0.893014 vn -0.369102 0.255997 -0.893437 vn -0.0355067 0.995843 -0.0838772 vn 0.260439 0.73186 0.629724 vn 0.332584 0.49337 0.803725 vn -0.00284834 -0.257863 -0.966177 vn -0.00192311 0.254736 -0.967009 vn -0.000266114 0.995734 -0.0922702 vn 2.39288e-05 0.731295 0.682061 vn 2.43342e-09 0.492521 0.870301 vn 0.379058 -0.3593 -0.852771 vn 0.37711 0.149086 -0.914091 vn 0.0275022 0.992081 -0.122551 vn -0.26101 0.726762 0.635367 vn -0.332485 0.492546 0.804271 vn 0.663548 -0.410791 -0.625264 vn 0.712664 0.0737216 -0.697621 vn 0.0997268 0.987509 -0.121984 vn -0.48732 0.723754 0.488568 vn -0.615242 0.492602 0.615484 vn 0.880028 -0.332908 -0.338709 vn 0.917276 0.167113 -0.361493 vn 0.113584 0.992365 -0.0480695 vn -0.63415 0.727508 0.261889 vn -0.804126 0.492634 0.332705 vn 0.96669 -0.255738 0.0104537 vn 0.967442 0.252962 0.00810329 vn 0.0934365 0.995624 0.00128063 vn -0.682167 0.731196 -0.00034353 vn -0.870322 0.492483 -5.42436e-05 vn 0.893014 -0.256345 0.369882 vn 0.893437 0.255997 0.369102 vn 0.0838768 0.995843 0.0355066 vn -0.629724 0.73186 -0.260439 vn -0.803725 0.49337 -0.332584 vn 0.683407 -0.256729 0.683407 vn 0.683531 0.256067 0.683531 vn 0.0649249 0.995776 0.0649249 vn -0.481398 0.732469 -0.481398 vn -0.614804 0.493997 -0.614804 vn 0.369882 -0.256345 0.893014 vn 0.369102 0.255997 0.893437 vn 0.0355067 0.995843 0.083877 vn -0.260439 0.73186 -0.629724 vn -0.332584 0.49337 -0.803725 vn 3.83985e-09 -0.255752 0.966742 vn 2.59359e-09 0.255443 0.966824 vn 3.99081e-08 0.995754 0.092052 vn 1.03862e-08 0.731305 -0.68205 vn -2.43342e-09 0.492521 -0.870301 vn -0.369882 -0.256345 0.893014 vn -0.369102 0.255996 0.893437 vn -0.0355068 0.995843 0.0838771 vn 0.260439 0.73186 -0.629724 vn 0.332584 0.49337 -0.803725 vn -0.683407 -0.256729 0.683407 vn -0.683531 0.256067 0.683531 vn -0.0649249 0.995776 0.064925 vn 0.481398 0.732469 -0.481398 vn 0.614804 0.493997 -0.614804 vn -0.893014 -0.256345 0.369882 vn -0.893437 0.255997 0.369102 vn -0.0838767 0.995843 0.0355066 vn 0.629724 0.73186 -0.260439 vn 0.803725 0.49337 -0.332584 vn 0.915321 0.402725 4.83311e-09 vn 0.941808 0.336151 -4.85769e-09 vn 0.97869 0.205342 4.90003e-09 vn 0.997804 -0.0662397 1.0073e-08 vn 0.845438 0.403546 0.349835 vn 0.869996 0.336859 0.360047 vn 0.904193 0.205791 0.37428 vn 0.921879 -0.0663697 0.381752 vn 0.646802 0.404096 0.646802 vn 0.665655 0.337351 0.665655 vn 0.691923 0.20612 0.691923 vn 0.705542 -0.0664796 0.705543 vn 0.349835 0.403546 0.845438 vn 0.360047 0.336859 0.869996 vn 0.37428 0.205791 0.904193 vn 0.381752 -0.0663697 0.921879 vn -1.31462e-09 0.402725 0.915321 vn 9.76689e-10 0.336151 0.941808 vn -1.9304e-08 0.205342 0.97869 vn -2.15056e-08 -0.0662397 0.997804 vn -0.349835 0.403546 0.845438 vn -0.360047 0.336859 0.869996 vn -0.37428 0.205791 0.904193 vn -0.381752 -0.0663697 0.921879 vn -0.646802 0.404096 0.646802 vn -0.665655 0.337351 0.665655 vn -0.691923 0.20612 0.691923 vn -0.705543 -0.0664796 0.705543 vn -0.845438 0.403546 0.349835 vn -0.869996 0.336859 0.360047 vn -0.904193 0.205791 0.37428 vn -0.921879 -0.0663697 0.381752 vn -0.915321 0.402725 -2.41655e-09 vn -0.941808 0.336151 -1.21442e-08 vn -0.97869 0.205342 -3.18502e-08 vn -0.997804 -0.0662397 -2.26643e-08 vn -0.845438 0.403546 -0.349835 vn -0.869996 0.336859 -0.360047 vn -0.904193 0.205791 -0.37428 vn -0.921879 -0.0663697 -0.381752 vn -0.646802 0.404096 -0.646802 vn -0.665655 0.337351 -0.665655 vn -0.691923 0.20612 -0.691923 vn -0.705542 -0.0664796 -0.705543 vn -0.349835 0.403546 -0.845438 vn -0.360047 0.336859 -0.869996 vn -0.37428 0.205791 -0.904193 vn -0.381752 -0.0663697 -0.921879 vn 1.31462e-09 0.402725 -0.915321 vn -9.76689e-10 0.336151 -0.941808 vn 1.9304e-08 0.205342 -0.97869 vn 2.15056e-08 -0.0662397 -0.997804 vn 0.349835 0.403546 -0.845438 vn 0.360047 0.336859 -0.869996 vn 0.37428 0.205791 -0.904193 vn 0.381752 -0.0663697 -0.921879 vn 0.646802 0.404096 -0.646802 vn 0.665655 0.337351 -0.665655 vn 0.691923 0.20612 -0.691923 vn 0.705543 -0.0664796 -0.705542 vn 0.845438 0.403546 -0.349835 vn 0.869996 0.336859 -0.360047 vn 0.904193 0.205791 -0.37428 vn 0.921879 -0.0663697 -0.381752 vn 0.900182 -0.435513 -1.50883e-08 vn 0.729611 -0.683863 -9.71212e-09 vn 0.693951 -0.720022 -9.54282e-09 vn 0.79395 -0.607984 2.6277e-08 vn 0.831437 -0.43618 0.344179 vn 0.673512 -0.684665 0.278594 vn 0.640399 -0.720924 0.264874 vn 0.732949 -0.608996 0.303166 vn 0.636092 -0.436777 0.636092 vn 0.514965 -0.685289 0.514965 vn 0.489651 -0.721446 0.489651 vn 0.560555 -0.609554 0.560555 vn 0.344179 -0.43618 0.831437 vn 0.278594 -0.684665 0.673512 vn 0.264874 -0.720924 0.640399 vn 0.303166 -0.608996 0.732949 vn 1.18057e-08 -0.435513 0.900182 vn -4.75784e-09 -0.683863 0.729611 vn 9.10217e-09 -0.720022 0.693951 vn -2.68996e-08 -0.607984 0.79395 vn -0.344179 -0.43618 0.831437 vn -0.278594 -0.684665 0.673512 vn -0.264874 -0.720924 0.640399 vn -0.303166 -0.608996 0.732949 vn -0.636092 -0.436777 0.636092 vn -0.514965 -0.685289 0.514965 vn -0.489651 -0.721446 0.489651 vn -0.560555 -0.609554 0.560555 vn -0.831437 -0.43618 0.344179 vn -0.673512 -0.684665 0.278595 vn -0.640399 -0.720924 0.264874 vn -0.732949 -0.608996 0.303166 vn -0.900182 -0.435513 -7.54414e-09 vn -0.729611 -0.683863 -7.28409e-09 vn -0.693951 -0.720022 4.77141e-09 vn -0.79395 -0.607983 -2.6277e-08 vn -0.831437 -0.43618 -0.344179 vn -0.673512 -0.684665 -0.278594 vn -0.640399 -0.720924 -0.264874 vn -0.732949 -0.608996 -0.303166 vn -0.636092 -0.436777 -0.636092 vn -0.514965 -0.685289 -0.514965 vn -0.489651 -0.721446 -0.489651 vn -0.560555 -0.609554 -0.560555 vn -0.344179 -0.43618 -0.831437 vn -0.278594 -0.684665 -0.673512 vn -0.264874 -0.720924 -0.640399 vn -0.303166 -0.608996 -0.732949 vn -1.18057e-08 -0.435513 -0.900182 vn 4.75784e-09 -0.683863 -0.729611 vn -9.10217e-09 -0.720022 -0.693951 vn 2.68996e-08 -0.607984 -0.79395 vn 0.344179 -0.43618 -0.831437 vn 0.278594 -0.684665 -0.673512 vn 0.264874 -0.720924 -0.640399 vn 0.303167 -0.608996 -0.732949 vn 0.636092 -0.436777 -0.636092 vn 0.514965 -0.685289 -0.514965 vn 0.489651 -0.721446 -0.489651 vn 0.560555 -0.609554 -0.560555 vn 0.831437 -0.43618 -0.344179 vn 0.673512 -0.684665 -0.278595 vn 0.640399 -0.720924 -0.264874 vn 0.732949 -0.608996 -0.303166 vn 0.62386 -0.781536 3.04248e-08 vn 0.177291 -0.984159 -3.28321e-09 vn 0.0492072 -0.998789 1.48326e-09 vn 1.94668e-11 -1 -7.78368e-10 vn 0.576229 -0.781801 0.238217 vn 0.163629 -0.984208 0.0675273 vn 0.0454217 -0.998792 0.0187357 vn 0.440416 -0.782348 0.440416 vn 0.124903 -0.984276 0.124903 vn 0.0346621 -0.998798 0.0346621 vn 0.238217 -0.781801 0.576229 vn 0.0675273 -0.984208 0.163629 vn 0.0187357 -0.998792 0.0454217 vn -3.18434e-08 -0.781536 0.62386 vn 3.33958e-09 -0.984159 0.177291 vn -1.80438e-09 -0.998789 0.0492072 vn -0.238216 -0.781801 0.576229 vn -0.0675273 -0.984208 0.163629 vn -0.0187357 -0.998792 0.0454217 vn -0.440416 -0.782348 0.440416 vn -0.124903 -0.984276 0.124903 vn -0.0346621 -0.998798 0.0346621 vn -0.576229 -0.781801 0.238217 vn -0.163629 -0.984208 0.0675273 vn -0.0454217 -0.998792 0.0187357 vn -0.62386 -0.781536 -3.17476e-08 vn -0.177291 -0.984159 3.13397e-09 vn -0.0492072 -0.998789 -1.33493e-09 vn -0.576229 -0.781801 -0.238217 vn -0.163629 -0.984208 -0.0675273 vn -0.0454217 -0.998792 -0.0187357 vn -0.440416 -0.782348 -0.440416 vn -0.124903 -0.984276 -0.124903 vn -0.0346621 -0.998798 -0.0346621 vn -0.238217 -0.781801 -0.576229 vn -0.0675273 -0.984208 -0.163629 vn -0.0187357 -0.998792 -0.0454217 vn 3.18434e-08 -0.781536 -0.62386 vn -3.28168e-09 -0.984159 -0.177291 vn 1.46144e-09 -0.998789 -0.0492072 vn 0.238217 -0.781801 -0.576229 vn 0.0675273 -0.984208 -0.163629 vn 0.0187357 -0.998792 -0.0454217 vn 0.440416 -0.782348 -0.440416 vn 0.124903 -0.984276 -0.124903 vn 0.0346621 -0.998798 -0.0346621 vn 0.576229 -0.781801 -0.238217 vn 0.163629 -0.984208 -0.0675273 vn 0.0454217 -0.998792 -0.0187357 vn 0.00778619 -0.99997 -0.000215809 vn 0.0391385 -0.999233 -0.000988567 vn 0.179511 -0.983746 -0.00436856 vn 0.6123 -0.790556 -0.0104598 vn 0.986152 -0.165707 -0.00666949 vn 0.00703893 -0.812495 0.582926 vn 0.0361273 -0.837257 0.545614 vn 0.161845 -0.810421 0.563048 vn 0.482365 -0.595148 0.642746 vn 0.73872 -0.114593 0.664199 vn -0.00190867 0.162121 0.986769 vn 0.0027616 0.0171073 0.99985 vn 0.0105326 0.0733989 0.997247 vn -0.0660406 0.130069 0.989303 vn -0.0944272 0.0165946 0.995393 vn -0.009203 0.871509 0.490293 vn -0.0486064 0.840609 0.539457 vn -0.223298 0.802881 0.552739 vn -0.596365 0.559971 0.575135 vn -0.803337 0.0682361 0.591602 vn -0.0105609 0.999944 0.000103364 vn -0.0587986 0.99827 0.000709759 vn -0.28071 0.959787 0.00326876 vn -0.749723 0.661738 0.0042684 vn -0.997351 0.0727144 0.00205923 vn -0.00879197 0.871493 -0.49033 vn -0.0464937 0.841178 -0.538756 vn -0.217909 0.806807 -0.549161 vn -0.597291 0.560026 -0.574121 vn -0.804 0.0629127 -0.591291 vn -0.00180555 0.161691 -0.98684 vn 0.00203087 0.014555 -0.999892 vn 0.00921499 0.0600698 -0.998152 vn -0.0593333 0.113865 -0.991723 vn -0.0868992 0.0122903 -0.996141 vn 0.00641779 -0.812379 -0.583094 vn 0.0337833 -0.837512 -0.545373 vn 0.157112 -0.811947 -0.56219 vn 0.484407 -0.589365 -0.646528 vn 0.73887 -0.10132 -0.666187 vn 0.946512 0.32265 -0.0033571 vn 0.82583 0.56387 -0.00745213 vn 0.650011 0.759893 -0.00693681 vn 0.532429 0.846458 -0.00524544 vn 0.725608 0.259351 0.637362 vn 0.645945 0.461988 0.607719 vn 0.531614 0.63666 0.558615 vn 0.424964 0.681717 0.59554 vn -0.0495616 -0.019755 0.998576 vn -0.0378162 -0.0356243 0.99865 vn -0.0379139 -0.0365122 0.998614 vn -0.168854 -0.297946 0.93953 vn -0.742342 -0.299166 0.599523 vn -0.619602 -0.529406 0.579503 vn -0.483708 -0.685761 0.543837 vn -0.445293 -0.794355 0.413176 vn -0.926513 -0.376257 0.00199587 vn -0.75392 -0.656952 0.00431723 vn -0.566224 -0.824244 0.00346105 vn -0.481804 -0.876277 0.00185047 vn -0.744675 -0.294424 -0.598977 vn -0.621949 -0.528114 -0.578165 vn -0.481171 -0.68834 -0.542828 vn -0.438055 -0.797035 -0.415744 vn -0.0443368 -0.0170558 -0.998871 vn -0.0261761 -0.0281665 -0.99926 vn -0.0252939 -0.0283323 -0.999278 vn -0.157482 -0.289392 -0.944167 vn 0.728244 0.25241 -0.637142 vn 0.647055 0.459725 -0.608254 vn 0.522994 0.640657 -0.562171 vn 0.409978 0.682857 -0.604669 vn -0.230787 0.972982 -0.00652338 vn -0.548936 0.835863 -0.00151111 vn -0.875671 0.482807 0.00989278 vn -0.877554 0.479097 0.0190923 vn -0.69619 0.717439 0.024497 vn -0.152878 0.687211 0.71019 vn -0.316721 0.63775 0.702113 vn -0.601067 0.471452 0.64533 vn -0.635889 0.44609 0.6298 vn -0.435746 0.601008 0.670011 vn 0.111112 -0.0850694 0.99016 vn 0.22331 0.00654036 0.974726 vn 0.190097 0.154964 0.969458 vn 0.00527077 0.189482 0.98187 vn -0.0117518 0.246688 0.969024 vn 0.343906 -0.722796 0.599412 vn 0.572489 -0.567656 0.591627 vn 0.787436 -0.256459 0.560512 vn 0.647097 -0.306374 0.698141 vn 0.427528 -0.499343 0.753576 vn 0.410926 -0.911668 0.00128446 vn 0.67152 -0.740986 -0.000899122 vn 0.922026 -0.38706 -0.00725269 vn 0.84691 -0.531556 -0.0138542 vn 0.535925 -0.8442 -0.0105045 vn 0.341188 -0.722822 -0.600931 vn 0.578664 -0.561139 -0.591838 vn 0.784869 -0.25102 -0.566542 vn 0.642681 -0.302257 -0.70399 vn 0.418589 -0.500042 -0.758117 vn 0.115806 -0.0791394 -0.990114 vn 0.232811 0.0125652 -0.972441 vn 0.206662 0.153601 -0.96628 vn 0.0244996 0.161443 -0.986578 vn 0.00338193 0.211115 -0.977455 vn -0.134912 0.687491 -0.713551 vn -0.31954 0.633073 -0.705062 vn -0.603902 0.461442 -0.649903 vn -0.631816 0.437169 -0.640072 vn -0.424306 0.612706 -0.66675 vn -0.4258 0.904753 0.0108049 vn 0.0220472 0.999756 0.00162273 vn 0.999599 0.0258705 0.0115556 vn 0.709585 -0.704553 0.00967183 vn -0.259858 0.791936 0.552549 vn 0.00953916 0.99972 -0.0216718 vn 0.410156 0.332912 -0.849083 vn 0.541523 -0.54862 -0.637 vn 0.0463104 0.455224 0.889172 vn -0.0106883 0.988794 0.148901 vn -0.0443756 0.682947 -0.729118 vn 0.122825 0.00923214 -0.992385 vn 0.481839 -0.180439 0.85748 vn 0.455272 0.736752 0.499925 vn -0.220542 0.907193 -0.358276 vn -0.23592 0.657249 -0.715797 vn 0.728092 -0.685302 -0.0155853 vn 0.888739 0.45811 -0.0166791 vn -0.260097 0.965582 0.000800195 vn -0.371612 0.928378 -0.00441745 vn 0.480166 -0.17836 -0.858853 vn 0.488103 0.716801 -0.497947 vn -0.222004 0.905399 0.361893 vn -0.235405 0.66318 0.710477 vn 0.0587203 0.437704 -0.8972 vn 0.00132612 0.986459 -0.164003 vn -0.0441901 0.681677 0.730317 vn 0.138801 -0.0341896 0.98973 vn -0.25889 0.797206 -0.54538 vn 0.0122703 0.999739 0.0192865 vn 0.39863 0.35489 0.845663 vn 0.537564 -0.5814 0.610737 vn -7.79193e-10 1 6.50944e-09 vn 0.82454 0.565804 1.72913e-05 vn 0.917701 -0.397272 3.35502e-05 vn 0.935269 -0.353939 0.000112842 vn 0.780712 0.624891 7.51916e-05 vn 0.762641 0.565035 0.314825 vn 0.847982 -0.397998 0.350034 vn 0.864141 -0.355261 0.356441 vn 0.720991 0.625625 0.297933 vn 0.583357 0.565165 0.583338 vn 0.648485 -0.398726 0.648448 vn 0.660872 -0.355894 0.660748 vn 0.551862 0.62529 0.55178 vn 0.314824 0.565051 0.762629 vn 0.350045 -0.397976 0.847988 vn 0.356474 -0.3552 0.864153 vn 0.297983 0.625515 0.721067 vn -1.7299e-05 0.565804 0.82454 vn -3.35448e-05 -0.397272 0.917701 vn -0.000112839 -0.353939 0.935269 vn -7.51869e-05 0.624891 0.780712 vn -0.314825 0.565035 0.762641 vn -0.350034 -0.397998 0.847982 vn -0.356441 -0.355261 0.864141 vn -0.297933 0.625625 0.720991 vn -0.583338 0.565165 0.583357 vn -0.648448 -0.398726 0.648485 vn -0.660748 -0.355894 0.660872 vn -0.55178 0.62529 0.551862 vn -0.762629 0.565051 0.314824 vn -0.847988 -0.397976 0.350045 vn -0.864153 -0.3552 0.356474 vn -0.721067 0.625515 0.297983 vn -0.82454 0.565804 -1.72877e-05 vn -0.917701 -0.397272 -3.35262e-05 vn -0.935269 -0.353939 -0.000112839 vn -0.780712 0.624891 -7.51882e-05 vn -0.76264 0.565035 -0.314825 vn -0.847982 -0.397998 -0.350034 vn -0.864141 -0.355261 -0.356441 vn -0.720991 0.625625 -0.297933 vn -0.583357 0.565165 -0.583338 vn -0.648485 -0.398726 -0.648448 vn -0.660872 -0.355894 -0.660748 vn -0.551862 0.62529 -0.55178 vn -0.314824 0.565051 -0.762629 vn -0.350045 -0.397976 -0.847988 vn -0.356474 -0.3552 -0.864153 vn -0.297983 0.625515 -0.721067 vn 1.72918e-05 0.565804 -0.82454 vn 3.35344e-05 -0.397272 -0.917701 vn 0.000112839 -0.353939 -0.935269 vn 7.51869e-05 0.624891 -0.780712 vn 0.314825 0.565035 -0.762641 vn 0.350034 -0.397998 -0.847982 vn 0.356441 -0.355261 -0.864141 vn 0.297933 0.625625 -0.720991 vn 0.583338 0.565165 -0.583357 vn 0.648448 -0.398726 -0.648485 vn 0.660748 -0.355894 -0.660872 vn 0.55178 0.62529 -0.551862 vn 0.762629 0.565051 -0.314824 vn 0.847988 -0.397976 -0.350045 vn 0.864153 -0.3552 -0.356474 vn 0.721067 0.625515 -0.297983 vn 0.236584 0.971611 8.31862e-09 vn 0.173084 0.984907 -1.18677e-09 vn 0.379703 0.925108 2.44118e-09 vn 0.526673 0.850068 2.66504e-09 vn 0.217978 0.971775 0.0902162 vn 0.15959 0.984977 0.0659615 vn 0.350498 0.925312 0.14474 vn 0.48559 0.850653 0.201474 vn 0.166631 0.971838 0.166631 vn 0.121908 0.985026 0.121908 vn 0.267668 0.925585 0.267668 vn 0.371315 0.851029 0.371315 vn 0.0902162 0.971775 0.217978 vn 0.0659615 0.984977 0.15959 vn 0.14474 0.925312 0.350498 vn 0.201474 0.850653 0.48559 vn -8.2649e-09 0.971611 0.236584 vn 1.37744e-09 0.984907 0.173084 vn 2.79781e-10 0.925108 0.379703 vn 2.55497e-09 0.850068 0.526673 vn -0.0902162 0.971775 0.217978 vn -0.0659615 0.984977 0.15959 vn -0.14474 0.925312 0.350498 vn -0.201474 0.850653 0.48559 vn -0.166631 0.971838 0.166631 vn -0.121908 0.985026 0.121908 vn -0.267668 0.925585 0.267668 vn -0.371315 0.851029 0.371315 vn -0.217978 0.971775 0.0902162 vn -0.15959 0.984977 0.0659615 vn -0.350498 0.925312 0.14474 vn -0.48559 0.850653 0.201474 vn -0.236583 0.971611 -6.23897e-09 vn -0.173084 0.984907 2.37354e-09 vn -0.379703 0.925108 -2.44118e-09 vn -0.526673 0.850068 0 vn -0.217978 0.971775 -0.0902162 vn -0.15959 0.984977 -0.0659615 vn -0.350498 0.925312 -0.14474 vn -0.48559 0.850653 -0.201474 vn -0.166631 0.971838 -0.166631 vn -0.121908 0.985026 -0.121908 vn -0.267668 0.925585 -0.267668 vn -0.371315 0.851029 -0.371315 vn -0.0902162 0.971775 -0.217978 vn -0.0659615 0.984977 -0.15959 vn -0.14474 0.925312 -0.350498 vn -0.201474 0.850653 -0.485589 vn 6.16189e-09 0.971611 -0.236584 vn -1.37744e-09 0.984907 -0.173084 vn -2.79781e-10 0.925108 -0.379703 vn -2.55497e-09 0.850068 -0.526673 vn 0.0902162 0.971775 -0.217978 vn 0.0659615 0.984977 -0.15959 vn 0.14474 0.925312 -0.350498 vn 0.201474 0.850653 -0.48559 vn 0.166631 0.971838 -0.166631 vn 0.121908 0.985026 -0.121908 vn 0.267668 0.925585 -0.267668 vn 0.371315 0.851029 -0.371315 vn 0.217978 0.971775 -0.0902162 vn 0.15959 0.984977 -0.0659615 vn 0.350498 0.925312 -0.14474 vn 0.48559 0.850653 -0.201474 f 7 6 1 f 1 2 7 f 8 7 2 f 2 3 8 f 9 8 3 f 3 4 9 f 10 9 4 f 4 5 10 f 12 11 6 f 6 7 12 f 13 12 7 f 7 8 13 f 14 13 8 f 8 9 14 f 15 14 9 f 9 10 15 f 17 16 11 f 11 12 17 f 18 17 12 f 12 13 18 f 19 18 13 f 13 14 19 f 20 19 14 f 14 15 20 f 22 21 16 f 16 17 22 f 23 22 17 f 17 18 23 f 24 23 18 f 18 19 24 f 25 24 19 f 19 20 25 f 27 26 21 f 21 22 27 f 28 27 22 f 22 23 28 f 29 28 23 f 23 24 29 f 30 29 24 f 24 25 30 f 32 31 26 f 26 27 32 f 33 32 27 f 27 28 33 f 34 33 28 f 28 29 34 f 35 34 29 f 29 30 35 f 37 36 31 f 31 32 37 f 38 37 32 f 32 33 38 f 39 38 33 f 33 34 39 f 40 39 34 f 34 35 40 f 42 41 36 f 36 37 42 f 43 42 37 f 37 38 43 f 44 43 38 f 38 39 44 f 45 44 39 f 39 40 45 f 47 46 41 f 41 42 47 f 48 47 42 f 42 43 48 f 49 48 43 f 43 44 49 f 50 49 44 f 44 45 50 f 52 51 46 f 46 47 52 f 53 52 47 f 47 48 53 f 54 53 48 f 48 49 54 f 55 54 49 f 49 50 55 f 57 56 51 f 51 52 57 f 58 57 52 f 52 53 58 f 59 58 53 f 53 54 59 f 60 59 54 f 54 55 60 f 62 61 56 f 56 57 62 f 63 62 57 f 57 58 63 f 64 63 58 f 58 59 64 f 65 64 59 f 59 60 65 f 67 66 61 f 61 62 67 f 68 67 62 f 62 63 68 f 69 68 63 f 63 64 69 f 70 69 64 f 64 65 70 f 72 71 66 f 66 67 72 f 73 72 67 f 67 68 73 f 74 73 68 f 68 69 74 f 75 74 69 f 69 70 75 f 77 76 71 f 71 72 77 f 78 77 72 f 72 73 78 f 79 78 73 f 73 74 79 f 80 79 74 f 74 75 80 f 2 1 76 f 76 77 2 f 3 2 77 f 77 78 3 f 4 3 78 f 78 79 4 f 5 4 79 f 79 80 5 f 85 10 5 f 5 81 85 f 86 85 81 f 81 82 86 f 87 86 82 f 82 83 87 f 88 87 83 f 83 84 88 f 89 15 10 f 10 85 89 f 90 89 85 f 85 86 90 f 91 90 86 f 86 87 91 f 92 91 87 f 87 88 92 f 93 20 15 f 15 89 93 f 94 93 89 f 89 90 94 f 95 94 90 f 90 91 95 f 96 95 91 f 91 92 96 f 97 25 20 f 20 93 97 f 98 97 93 f 93 94 98 f 99 98 94 f 94 95 99 f 100 99 95 f 95 96 100 f 101 30 25 f 25 97 101 f 102 101 97 f 97 98 102 f 103 102 98 f 98 99 103 f 104 103 99 f 99 100 104 f 105 35 30 f 30 101 105 f 106 105 101 f 101 102 106 f 107 106 102 f 102 103 107 f 108 107 103 f 103 104 108 f 109 40 35 f 35 105 109 f 110 109 105 f 105 106 110 f 111 110 106 f 106 107 111 f 112 111 107 f 107 108 112 f 113 45 40 f 40 109 113 f 114 113 109 f 109 110 114 f 115 114 110 f 110 111 115 f 116 115 111 f 111 112 116 f 117 50 45 f 45 113 117 f 118 117 113 f 113 114 118 f 119 118 114 f 114 115 119 f 120 119 115 f 115 116 120 f 121 55 50 f 50 117 121 f 122 121 117 f 117 118 122 f 123 122 118 f 118 119 123 f 124 123 119 f 119 120 124 f 125 60 55 f 55 121 125 f 126 125 121 f 121 122 126 f 127 126 122 f 122 123 127 f 128 127 123 f 123 124 128 f 129 65 60 f 60 125 129 f 130 129 125 f 125 126 130 f 131 130 126 f 126 127 131 f 132 131 127 f 127 128 132 f 133 70 65 f 65 129 133 f 134 133 129 f 129 130 134 f 135 134 130 f 130 131 135 f 136 135 131 f 131 132 136 f 137 75 70 f 70 133 137 f 138 137 133 f 133 134 138 f 139 138 134 f 134 135 139 f 140 139 135 f 135 136 140 f 141 80 75 f 75 137 141 f 142 141 137 f 137 138 142 f 143 142 138 f 138 139 143 f 144 143 139 f 139 140 144 f 81 5 80 f 80 141 81 f 82 81 141 f 141 142 82 f 83 82 142 f 142 143 83 f 84 83 143 f 143 144 84 f 149 88 84 f 84 145 149 f 150 149 145 f 145 146 150 f 151 150 146 f 146 147 151 f 152 151 147 f 147 148 152 f 153 92 88 f 88 149 153 f 154 153 149 f 149 150 154 f 155 154 150 f 150 151 155 f 156 155 151 f 151 152 156 f 157 96 92 f 92 153 157 f 158 157 153 f 153 154 158 f 159 158 154 f 154 155 159 f 160 159 155 f 155 156 160 f 161 100 96 f 96 157 161 f 162 161 157 f 157 158 162 f 163 162 158 f 158 159 163 f 164 163 159 f 159 160 164 f 165 104 100 f 100 161 165 f 166 165 161 f 161 162 166 f 167 166 162 f 162 163 167 f 168 167 163 f 163 164 168 f 169 108 104 f 104 165 169 f 170 169 165 f 165 166 170 f 171 170 166 f 166 167 171 f 172 171 167 f 167 168 172 f 173 112 108 f 108 169 173 f 174 173 169 f 169 170 174 f 175 174 170 f 170 171 175 f 176 175 171 f 171 172 176 f 177 116 112 f 112 173 177 f 178 177 173 f 173 174 178 f 179 178 174 f 174 175 179 f 180 179 175 f 175 176 180 f 181 120 116 f 116 177 181 f 182 181 177 f 177 178 182 f 183 182 178 f 178 179 183 f 184 183 179 f 179 180 184 f 185 124 120 f 120 181 185 f 186 185 181 f 181 182 186 f 187 186 182 f 182 183 187 f 188 187 183 f 183 184 188 f 189 128 124 f 124 185 189 f 190 189 185 f 185 186 190 f 191 190 186 f 186 187 191 f 192 191 187 f 187 188 192 f 193 132 128 f 128 189 193 f 194 193 189 f 189 190 194 f 195 194 190 f 190 191 195 f 196 195 191 f 191 192 196 f 197 136 132 f 132 193 197 f 198 197 193 f 193 194 198 f 199 198 194 f 194 195 199 f 200 199 195 f 195 196 200 f 201 140 136 f 136 197 201 f 202 201 197 f 197 198 202 f 203 202 198 f 198 199 203 f 204 203 199 f 199 200 204 f 205 144 140 f 140 201 205 f 206 205 201 f 201 202 206 f 207 206 202 f 202 203 207 f 208 207 203 f 203 204 208 f 145 84 144 f 144 205 145 f 146 145 205 f 205 206 146 f 147 146 206 f 206 207 147 f 148 147 207 f 207 208 148 f 213 152 148 f 148 209 213 f 214 213 209 f 209 210 214 f 215 214 210 f 210 211 215 f 212 215 211 f 211 212 212 f 216 156 152 f 152 213 216 f 217 216 213 f 213 214 217 f 218 217 214 f 214 215 218 f 212 218 215 f 215 212 212 f 219 160 156 f 156 216 219 f 220 219 216 f 216 217 220 f 221 220 217 f 217 218 221 f 212 221 218 f 218 212 212 f 222 164 160 f 160 219 222 f 223 222 219 f 219 220 223 f 224 223 220 f 220 221 224 f 212 224 221 f 221 212 212 f 225 168 164 f 164 222 225 f 226 225 222 f 222 223 226 f 227 226 223 f 223 224 227 f 212 227 224 f 224 212 212 f 228 172 168 f 168 225 228 f 229 228 225 f 225 226 229 f 230 229 226 f 226 227 230 f 212 230 227 f 227 212 212 f 231 176 172 f 172 228 231 f 232 231 228 f 228 229 232 f 233 232 229 f 229 230 233 f 212 233 230 f 230 212 212 f 234 180 176 f 176 231 234 f 235 234 231 f 231 232 235 f 236 235 232 f 232 233 236 f 212 236 233 f 233 212 212 f 237 184 180 f 180 234 237 f 238 237 234 f 234 235 238 f 239 238 235 f 235 236 239 f 212 239 236 f 236 212 212 f 240 188 184 f 184 237 240 f 241 240 237 f 237 238 241 f 242 241 238 f 238 239 242 f 212 242 239 f 239 212 212 f 243 192 188 f 188 240 243 f 244 243 240 f 240 241 244 f 245 244 241 f 241 242 245 f 212 245 242 f 242 212 212 f 246 196 192 f 192 243 246 f 247 246 243 f 243 244 247 f 248 247 244 f 244 245 248 f 212 248 245 f 245 212 212 f 249 200 196 f 196 246 249 f 250 249 246 f 246 247 250 f 251 250 247 f 247 248 251 f 212 251 248 f 248 212 212 f 252 204 200 f 200 249 252 f 253 252 249 f 249 250 253 f 254 253 250 f 250 251 254 f 212 254 251 f 251 212 212 f 255 208 204 f 204 252 255 f 256 255 252 f 252 253 256 f 257 256 253 f 253 254 257 f 212 257 254 f 254 212 212 f 209 148 208 f 208 255 209 f 210 209 255 f 255 256 210 f 211 210 256 f 256 257 211 f 212 211 257 f 257 212 212 f 264 263 258 f 258 259 264 f 265 264 259 f 259 260 265 f 266 265 260 f 260 261 266 f 267 266 261 f 261 262 267 f 269 268 263 f 263 264 269 f 270 269 264 f 264 265 270 f 271 270 265 f 265 266 271 f 272 271 266 f 266 267 272 f 274 273 268 f 268 269 274 f 275 274 269 f 269 270 275 f 276 275 270 f 270 271 276 f 277 276 271 f 271 272 277 f 279 278 273 f 273 274 279 f 280 279 274 f 274 275 280 f 281 280 275 f 275 276 281 f 282 281 276 f 276 277 282 f 284 283 278 f 278 279 284 f 285 284 279 f 279 280 285 f 286 285 280 f 280 281 286 f 287 286 281 f 281 282 287 f 289 288 283 f 283 284 289 f 290 289 284 f 284 285 290 f 291 290 285 f 285 286 291 f 292 291 286 f 286 287 292 f 294 293 288 f 288 289 294 f 295 294 289 f 289 290 295 f 296 295 290 f 290 291 296 f 297 296 291 f 291 292 297 f 259 258 293 f 293 294 259 f 260 259 294 f 294 295 260 f 261 260 295 f 295 296 261 f 262 261 296 f 296 297 262 f 302 267 262 f 262 298 302 f 303 302 298 f 298 299 303 f 304 303 299 f 299 300 304 f 305 304 300 f 300 301 305 f 306 272 267 f 267 302 306 f 307 306 302 f 302 303 307 f 308 307 303 f 303 304 308 f 309 308 304 f 304 305 309 f 310 277 272 f 272 306 310 f 311 310 306 f 306 307 311 f 312 311 307 f 307 308 312 f 313 312 308 f 308 309 313 f 314 282 277 f 277 310 314 f 315 314 310 f 310 311 315 f 316 315 311 f 311 312 316 f 317 316 312 f 312 313 317 f 318 287 282 f 282 314 318 f 319 318 314 f 314 315 319 f 320 319 315 f 315 316 320 f 321 320 316 f 316 317 321 f 322 292 287 f 287 318 322 f 323 322 318 f 318 319 323 f 324 323 319 f 319 320 324 f 325 324 320 f 320 321 325 f 326 297 292 f 292 322 326 f 327 326 322 f 322 323 327 f 328 327 323 f 323 324 328 f 329 328 324 f 324 325 329 f 298 262 297 f 297 326 298 f 299 298 326 f 326 327 299 f 300 299 327 f 327 328 300 f 301 300 328 f 328 329 301 f 336 335 330 f 330 331 336 f 337 336 331 f 331 332 337 f 338 337 332 f 332 333 338 f 339 338 333 f 333 334 339 f 341 340 335 f 335 336 341 f 342 341 336 f 336 337 342 f 343 342 337 f 337 338 343 f 344 343 338 f 338 339 344 f 346 345 340 f 340 341 346 f 347 346 341 f 341 342 347 f 348 347 342 f 342 343 348 f 349 348 343 f 343 344 349 f 351 350 345 f 345 346 351 f 352 351 346 f 346 347 352 f 353 352 347 f 347 348 353 f 354 353 348 f 348 349 354 f 356 355 350 f 350 351 356 f 357 356 351 f 351 352 357 f 358 357 352 f 352 353 358 f 359 358 353 f 353 354 359 f 361 360 355 f 355 356 361 f 362 361 356 f 356 357 362 f 363 362 357 f 357 358 363 f 364 363 358 f 358 359 364 f 366 365 360 f 360 361 366 f 367 366 361 f 361 362 367 f 368 367 362 f 362 363 368 f 369 368 363 f 363 364 369 f 331 330 365 f 365 366 331 f 332 331 366 f 366 367 332 f 333 332 367 f 367 368 333 f 334 333 368 f 368 369 334 f 374 339 334 f 334 370 374 f 375 374 370 f 370 371 375 f 376 375 371 f 371 372 376 f 377 376 372 f 372 373 377 f 378 344 339 f 339 374 378 f 379 378 374 f 374 375 379 f 380 379 375 f 375 376 380 f 381 380 376 f 376 377 381 f 382 349 344 f 344 378 382 f 383 382 378 f 378 379 383 f 384 383 379 f 379 380 384 f 385 384 380 f 380 381 385 f 386 354 349 f 349 382 386 f 387 386 382 f 382 383 387 f 388 387 383 f 383 384 388 f 389 388 384 f 384 385 389 f 390 359 354 f 354 386 390 f 391 390 386 f 386 387 391 f 392 391 387 f 387 388 392 f 393 392 388 f 388 389 393 f 394 364 359 f 359 390 394 f 395 394 390 f 390 391 395 f 396 395 391 f 391 392 396 f 397 396 392 f 392 393 397 f 398 369 364 f 364 394 398 f 399 398 394 f 394 395 399 f 400 399 395 f 395 396 400 f 401 400 396 f 396 397 401 f 370 334 369 f 369 398 370 f 371 370 398 f 398 399 371 f 372 371 399 f 399 400 372 f 373 372 400 f 400 401 373 f 407 402 402 f 402 403 407 f 408 407 403 f 403 404 408 f 409 408 404 f 404 405 409 f 410 409 405 f 405 406 410 f 411 402 402 f 402 407 411 f 412 411 407 f 407 408 412 f 413 412 408 f 408 409 413 f 414 413 409 f 409 410 414 f 415 402 402 f 402 411 415 f 416 415 411 f 411 412 416 f 417 416 412 f 412 413 417 f 418 417 413 f 413 414 418 f 419 402 402 f 402 415 419 f 420 419 415 f 415 416 420 f 421 420 416 f 416 417 421 f 422 421 417 f 417 418 422 f 423 402 402 f 402 419 423 f 424 423 419 f 419 420 424 f 425 424 420 f 420 421 425 f 426 425 421 f 421 422 426 f 427 402 402 f 402 423 427 f 428 427 423 f 423 424 428 f 429 428 424 f 424 425 429 f 430 429 425 f 425 426 430 f 431 402 402 f 402 427 431 f 432 431 427 f 427 428 432 f 433 432 428 f 428 429 433 f 434 433 429 f 429 430 434 f 435 402 402 f 402 431 435 f 436 435 431 f 431 432 436 f 437 436 432 f 432 433 437 f 438 437 433 f 433 434 438 f 439 402 402 f 402 435 439 f 440 439 435 f 435 436 440 f 441 440 436 f 436 437 441 f 442 441 437 f 437 438 442 f 443 402 402 f 402 439 443 f 444 443 439 f 439 440 444 f 445 444 440 f 440 441 445 f 446 445 441 f 441 442 446 f 447 402 402 f 402 443 447 f 448 447 443 f 443 444 448 f 449 448 444 f 444 445 449 f 450 449 445 f 445 446 450 f 451 402 402 f 402 447 451 f 452 451 447 f 447 448 452 f 453 452 448 f 448 449 453 f 454 453 449 f 449 450 454 f 455 402 402 f 402 451 455 f 456 455 451 f 451 452 456 f 457 456 452 f 452 453 457 f 458 457 453 f 453 454 458 f 459 402 402 f 402 455 459 f 460 459 455 f 455 456 460 f 461 460 456 f 456 457 461 f 462 461 457 f 457 458 462 f 463 402 402 f 402 459 463 f 464 463 459 f 459 460 464 f 465 464 460 f 460 461 465 f 466 465 461 f 461 462 466 f 403 402 402 f 402 463 403 f 404 403 463 f 463 464 404 f 405 404 464 f 464 465 405 f 406 405 465 f 465 466 406 f 471 410 406 f 406 467 471 f 472 471 467 f 467 468 472 f 473 472 468 f 468 469 473 f 474 473 469 f 469 470 474 f 475 414 410 f 410 471 475 f 476 475 471 f 471 472 476 f 477 476 472 f 472 473 477 f 478 477 473 f 473 474 478 f 479 418 414 f 414 475 479 f 480 479 475 f 475 476 480 f 481 480 476 f 476 477 481 f 482 481 477 f 477 478 482 f 483 422 418 f 418 479 483 f 484 483 479 f 479 480 484 f 485 484 480 f 480 481 485 f 486 485 481 f 481 482 486 f 487 426 422 f 422 483 487 f 488 487 483 f 483 484 488 f 489 488 484 f 484 485 489 f 490 489 485 f 485 486 490 f 491 430 426 f 426 487 491 f 492 491 487 f 487 488 492 f 493 492 488 f 488 489 493 f 494 493 489 f 489 490 494 f 495 434 430 f 430 491 495 f 496 495 491 f 491 492 496 f 497 496 492 f 492 493 497 f 498 497 493 f 493 494 498 f 499 438 434 f 434 495 499 f 500 499 495 f 495 496 500 f 501 500 496 f 496 497 501 f 502 501 497 f 497 498 502 f 503 442 438 f 438 499 503 f 504 503 499 f 499 500 504 f 505 504 500 f 500 501 505 f 506 505 501 f 501 502 506 f 507 446 442 f 442 503 507 f 508 507 503 f 503 504 508 f 509 508 504 f 504 505 509 f 510 509 505 f 505 506 510 f 511 450 446 f 446 507 511 f 512 511 507 f 507 508 512 f 513 512 508 f 508 509 513 f 514 513 509 f 509 510 514 f 515 454 450 f 450 511 515 f 516 515 511 f 511 512 516 f 517 516 512 f 512 513 517 f 518 517 513 f 513 514 518 f 519 458 454 f 454 515 519 f 520 519 515 f 515 516 520 f 521 520 516 f 516 517 521 f 522 521 517 f 517 518 522 f 523 462 458 f 458 519 523 f 524 523 519 f 519 520 524 f 525 524 520 f 520 521 525 f 526 525 521 f 521 522 526 f 527 466 462 f 462 523 527 f 528 527 523 f 523 524 528 f 529 528 524 f 524 525 529 f 530 529 525 f 525 526 530 f 467 406 466 f 466 527 467 f 468 467 527 f 527 528 468 f 469 468 528 f 528 529 469 f 470 469 529 f 529 530 470 matgeom-1.2.4/inst/meshes3d/PaxHeaders/writeMesh.m0000644000000000000000000000013214576357161017061 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/writeMesh.m0000644000175000017500000000527314576357161020650 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function writeMesh(fileName, vertices, faces, varargin) %WRITEMESH Write 3D mesh data by inferring format from file name. % % writeMesh(FNAME, V, F) % % writeMesh(FNAME, MESH) % % Example % writeMesh % % See also % meshes3d, readMesh, writeMesh_off, writeMesh_ply, writeMesh_stl % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-11-20, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % check inputs if ~ischar(fileName) error('First argument must contain the name of the file'); end % optionaly parses data if isstruct(vertices) if nargin > 2 varargin = [{faces} varargin{:}]; end faces = vertices.faces; vertices = vertices.vertices; end [~, ~, ext] = fileparts(fileName); switch lower(ext) case '.off' writeMesh_off(fileName, vertices, faces); case '.ply' writeMesh_ply(fileName, vertices, faces, varargin{:}); case '.stl' writeMesh_stl(fileName, vertices, faces, varargin{:}); otherwise error('Unrecognized file format for rezading mesh: %s', ext); end matgeom-1.2.4/inst/meshes3d/PaxHeaders/fillMeshFaces.m0000644000000000000000000000013214576357161017617 xustar0030 mtime=1710874225.162193323 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/meshes3d/fillMeshFaces.m0000644000175000017500000000762614576357161021412 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = fillMeshFaces(varargin) %FILLMESHFACES Fill the faces of a mesh with the specified colors. % % fillMeshFaces(V, F, VERTEXCOLORS) % Colorizes a mesh by filling faces with an array of values. The colors % can be a NV-by-1 array of values, or a NV-by-3 array of values. % Face filling uses 'interp' coloring mode. % % fillMeshFaces(V, F, FACECOLORS) % Colorizes the mesh by specifying the value or the color associated to % each face. Face filling uses 'flat' coloring mode. % % fillMeshFaces(..., PNAME, PVALUE) % Specifies additional parameters that will be passed to the 'patch' % function. % % Example % % Colorize mesh based on z-coordinate of vertices. % [v, f] = createIcosahedron; % values = v(:,3); % figure; axis equal; view(3); % fillMeshFaces(v, f, values); % % % Colorize mesh using specific color for each face % [v, f] = createIcosahedron; % colors = jet(20); % figure; axis equal; view(3); % fillMeshFaces(v, f, colors); % % See also % drawMesh % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-04-16, using Matlab 9.7.0.1247435 (R2019b) Update 2 % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) %% Parse input arguments % extract first argument var1 = varargin{1}; varargin(1) = []; % Check if first input argument is an axes handle if isAxisHandle(var1) ax = var1; var1 = varargin{1}; varargin(1) = []; else ax = gca; end % Check if the input is a mesh structure if isstruct(var1) % extract data to display vertices = var1.vertices; faces = var1.faces; else % assumes input is given with vertices+faces arrays vertices = var1; faces = varargin{1}; varargin(1) = []; end % next argument is face color colors = varargin{1}; varargin(1) = []; % adapt the face color key value depending on the size of the "color" input % argument faceColorMode = 'interp'; if size(colors, 1) == size(faces, 1) faceColorMode = 'flat'; end % array FACES is a NF-by-NV indices array, with NV number of vertices of % each face, and NF number of faces h = patch('Parent', ax, ... 'vertices', vertices, 'faces', faces, 'FaceVertexCData', colors, ... 'FaceColor', faceColorMode, varargin{:}); %% Process output arguments % format output parameters if nargout > 0 varargout = {h}; end matgeom-1.2.4/inst/PaxHeaders/graphs0000644000000000000000000000013214576357161014430 xustar0030 mtime=1710874225.018193459 30 atime=1710874225.226193261 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/0000755000175000017500000000000014576357161016265 5ustar00juanpijuanpi00000000000000matgeom-1.2.4/inst/graphs/PaxHeaders/centroidalVoronoi2d.m0000644000000000000000000000013214576357161020611 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.162193323 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/centroidalVoronoi2d.m0000644000175000017500000001415514576357161022377 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [germs, germPaths] = centroidalVoronoi2d(germs, poly, varargin) %CENTROIDALVORONOI2D Centroidal Voronoi tesselation within a polygon. % % PTS = centroidalVoronoi2d(NPTS, POLY) % Generate points in a polygon based on centroidal voronoi tesselation. % Centroidal germs can be computed by using the Llyod's algorithm: % 1) initial germs are chosen at random within polygon % 2) voronoi polygon of the germs is computed % 3) the centroids of each domain are computed, and used as germs of the % next iteration % % [PTS, PATHLIST] = centroidalVoronoi2d(NPTS, POLY) % Also returns the path of each germs at each iteration. The result % PATHLIST is a cell array with as many cells as the number of germs, % containing in each cell the successive positions of the germ. % % PTS = centroidalVoronoi2d(.., PARAM, VALUE) % Specify one or several optional arguments. PARAM can be one of: % * 'nIter' specifies the number of iterations of the algorithm % (default is 50) % * 'verbose' display iteration number. Default is false. % % Example % poly = ellipseToPolygon([50 50 40 30 20], 200); % nGerms = 100; % germs = centroidalVoronoi2d(nGerms, poly); % figure; hold on; % drawPolygon(poly, 'k'); % drawPoint(germs, 'bo'); % axis equal; axis([0 100 10 90]); % % extract regions of the CVD % box = polygonBounds(poly); % [n, e] = boundedVoronoi2d(box, germs); % [n2, e2] = clipGraphPolygon(n, e, poly); % drawGraphEdges(n2, e2, 'b'); % % See also % graphs, boundedVoronoi2d, centroidalVoronoi2d_MC % % Rewritten from programs found in % http://people.scs.fsu.edu/~burkardt/m_src/cvt/cvt.html % % Reference: % Qiang Du, Vance Faber, and Max Gunzburger, % Centroidal Voronoi Tessellations: Applications and Algorithms, % SIAM Review, Volume 41, 1999, pages 637-676. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform %% Parse input arguments % Number of germs if isscalar(germs) nGerms = germs; germs = []; else nGerms = size(germs, 1); end % Number of iterations nIter = 50; verbose = false; keepPaths = nargout > 1; while length(varargin) > 1 paramName = varargin{1}; switch lower(paramName) case 'verbose' verbose = varargin{2}; case 'niter' nIter = varargin{2}; otherwise error(['Unknown parameter name: ' paramName]); end varargin(1:2) = []; end %% Initialisations % bounding box of polygon bbox = polygonBounds(poly); % init germs if needed if isempty(germs) germs = generatePointsInPoly(nGerms); end germIters = cell(nIter, 1); %% Iteration of the Lloyd algorithm for i = 1:nIter if verbose disp(sprintf('Iteration: %d/%d', i, nIter)); %#ok end if keepPaths germIters{i} = germs; end % Compute Clipped Voronoi diagram of germs if verbose disp(' compute Voronoi Diagram'); end [n, e, f] = boundedVoronoi2d(bbox, germs); [n2, e2, f2] = clipMesh2dPolygon(n, e, f, poly); %#ok % update the position of each germ if verbose disp(' compute centroids'); end for iGerm = 1:nGerms polygon = n2(f2{iGerm}, :); germs(iGerm,:) = polygonCentroid(polygon); end end %% Evenutally compute germs trajectories if nargout > 1 % init germPaths = cell(nGerms, 1); path = zeros(nIter+1, 2); % Iteration on germs for i = 1:nGerms % create path corresponding to germ for j = 1:nIter pts = germIters{j}; path(j,:) = pts(i,:); end path(nIter+1, :) = germs(i,:); germPaths{i} = path; end end function pts = generatePointsInPoly(nPts) % extreme coordinates xmin = bbox(1); xmax = bbox(2); ymin = bbox(3); ymax = bbox(4); % compute size of box dx = xmax - xmin; dy = ymax - ymin; % allocate memory for result pts = zeros(nPts, 2); % iterate until all points have been sampled within the polygon ind = (1:nPts)'; while ~isempty(ind) NI = length(ind); x = rand(NI, 1) * dx + xmin; y = rand(NI, 1) * dy + ymin; pts(ind, :) = [x y]; ind = ind(~polygonContains(poly, pts(ind, :))); end end end matgeom-1.2.4/inst/graphs/PaxHeaders/boundaryGraph.m0000644000000000000000000000013214576357161017470 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/boundaryGraph.m0000644000175000017500000001233014576357161021247 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = boundaryGraph(img) %BOUNDARYGRAPH Get boundary of image as a graph. % % deprecated: use imageBoundaryGraph instead % % [NODES, EDGES] = boundaryGraph(IMG) (2D) % [NODES, EDGES, FACES] = boundaryGraph(IMG) (3D) % Create a graph on the boundary of binary image IMG. Each pixel is % considered as a unit square (or cube), centered on integer coordinates. % Boundary of the shape is selected as a graph. % % Result is a set of nodes with (x,y) or (x,y,z) coordinates, a set of % edges linking two neighbour nodes, and in 3D also a set of square % faces, containing reference to each 4-tuple of nodes. % % The resulting shell is open if the binary structure touches edges of % image. % % See als: % imageBoundaryGraph % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-28 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE dim = size(img); nd = length(dim); if nd==2 && (dim(1)==1 || dim(2)==1) nd=1; end nodes = zeros([0 nd]); % coordinates of vertices edges = zeros([0 2]); % first node and second nodes faces = zeros([0 4]); % indices of 4 corners of each square face if nd == 1 img = img(:)>0; D1 = size(img,1); nodes = find(img(1:D1-1)~=img(2:D1))+.5; if nargout==1 varargout{1} = nodes; end return elseif nd == 2 D1 = size(img, 1); D2 = size(img, 2); px = []; py = []; ind = find(img(1:D1-1, :)~=img(2:D1, :)); [x, y] = ind2sub([D1-1 D2], ind); px = [px; reshape([x+.5 x+.5]', length(x)*2,1)]; py = [py; reshape([y-.5 y+.5]', length(x)*2,1)]; ind = find(img(:, 1:D2-1)~=img(:, 2:D2)); [x, y] = ind2sub([D1 D2-1], ind); px = [px; reshape([x-.5 x+.5]', length(x)*2,1)]; py = [py; reshape([y+.5 y+.5]', length(x)*2,1)]; [nodes, i, j] = unique([py px], 'rows'); %#ok ne = floor(size(px, 1)/2); edges = repmat(1:2, [ne 1]) + repmat((0:2:2*ne-1)', [1 2]); for i=1:length(edges(:)) edges(i) = j(edges(i)); end edges = unique(sort(edges, 2), 'rows'); elseif nd==3 D1 = size(img, 1); D2 = size(img, 2); D3 = size(img, 3); px = []; py = []; pz = []; ind = find(img(1:D1-1, :, :)~=img(2:D1, :, :)); [x, y, z] = ind2sub([D1-1 D2 D3], ind); px = [px; reshape([x+.5 x+.5 x+.5 x+.5]', length(x)*4,1)]; py = [py; reshape([y-.5 y+.5 y+.5 y-.5]', length(x)*4,1)]; pz = [pz; reshape([z-.5 z-.5 z+.5 z+.5]', length(x)*4,1)]; ind = find(img(:, 1:D2-1, :)~=img(:, 2:D2, :)); [x, y, z] = ind2sub([D1 D2-1 D3], ind); px = [px; reshape([x-.5 x-.5 x+.5 x+.5]', length(x)*4,1)]; py = [py; reshape([y+.5 y+.5 y+.5 y+.5]', length(x)*4,1)]; pz = [pz; reshape([z-.5 z+.5 z+.5 z-.5]', length(x)*4,1)]; ind = find(img(:, :, 1:D3-1)~=img(:, :, 2:D3)); [x, y, z] = ind2sub([D1 D2 D3-1], ind); px = [px; reshape([x-.5 x+.5 x+.5 x-.5]', length(x)*4,1)]; py = [py; reshape([y-.5 y-.5 y+.5 y+.5]', length(x)*4,1)]; pz = [pz; reshape([z+.5 z+.5 z+.5 z+.5]', length(x)*4,1)]; [nodes, i, j] = unique([py px pz], 'rows'); %#ok nf = floor(size(px, 1)/4); faces = repmat(1:4, [nf 1]) + repmat((0:4:4*nf-1)', [1 4]); for i=1:length(faces(:)) faces(i) = j(faces(i)); end edges = [edges ; [faces(:,1) faces(:,2)]]; edges = [edges ; [faces(:,2) faces(:,3)]]; edges = [edges ; [faces(:,3) faces(:,4)]]; edges = [edges ; [faces(:,4) faces(:,1)]]; edges = unique(sort(edges, 2), 'rows'); end % format output arguments if nargout==3 varargout{1} = nodes; varargout{2} = edges; varargout{3} = faces; elseif nargout==2 varargout{1} = nodes; varargout{2} = edges; elseif nargout==1 graph.nodes = nodes; graph.edges = edges; graph.faces = faces; varargout{1} = graph; end matgeom-1.2.4/inst/graphs/PaxHeaders/fillGraphFaces.m0000644000000000000000000000013214576357161017535 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/fillGraphFaces.m0000644000175000017500000001144414576357161021321 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = fillGraphFaces(varargin) %FILLGRAPHFACES Fill faces of a graph with specified color. % % fillGraphFaces(NODES, FACES) % draw the faces of a graph / mesh defined by a sef of vertices and a set % of faces. The array NODES is a NV-by-2 or NV-by-3 array containing % vertex coordinates. The array FACES is either a NF-by-3 or NF-by-4 % array of integers, or a 1-by-Nf array of cells, and contains indices of % each face vertices. % % fillGraphFaces(NODES, EDGES, FACES) % also specifies the edges ofthe graph. % % fillGraphFaces(GRAPH) % passes argument in a srtucture with at least 3 fields named 'nodes', % 'edges', and 'faces', corresponding to previously described parameters. % GRAPH can also be a cell array, whose first element is node array, % second element is edges array, and third element, if present, is faces % array. % % fillGraphFaces(..., SFACES) % specifes the draw mode for each element, as in the classical 'plot' % function. To not display some elements, uses 'none'. % % H = fillGraphFaces(...) % return handle to the set of faces. % % See also % graphs, drawGraph, drawGraphEdges % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-24 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) %% Initialisations % drawing style for filling faces. Default is cyan. faceColor = 'c'; %% Process input arguments % if called without argument, display usage if nargin == 0 help fillGraphFaces; return; end % Extract the structure of the graph var = varargin{1}; if iscell(var) % graph is stored as a cell array : first cell is nodes, second one is % edges, and third one is faces n = var{1}; if length(var) > 2 f = var{3}; end varargin(1) = []; elseif isstruct(var) % graph is stored as a structure, with fields 'nodes', 'edges', and % eventually 'faces'. n = var.nodes; if isfield(var, 'faces') f = var.faces; end varargin(1) = []; else % graph is stored as set of variables: nodes, edges, and eventually % faces n = varargin{1}; % extract faces input argument if length(varargin) > 2 && ~ischar(varargin{3}) f = varargin{3}; varargin(1:3) = []; else f = varargin{2}; varargin(1:2) = []; end end % extract drawing style if ~isempty(varargin) faceColor = varargin{1}; end % process special case of 'none' option, that can be used in a call from % the drawGraph function if strcmp(faceColor, 'none') return; end %% Main drawing processing % setup hold to display several faces hold on; if size(n, 2) == 3 % use a zbuffer to avoid display pbms. set(gcf, 'renderer', 'zbuffer'); end if iscell(f) % each face is contained in a cell. for fi = 1:length(f) hf(fi) = patch('Faces', f{fi}, 'Vertices', n, 'FaceColor', faceColor, 'EdgeColor', 'none'); %#ok end else % process faces as a NF-by-P array. NF i the number of faces, % and all faces have the same number P of vertices (nodes). hf = patch('Faces', f, 'Vertices', n, 'FaceColor', faceColor, 'EdgeColor', 'none'); end %% format output arguments if nargout == 1 varargout{1} = hf; end matgeom-1.2.4/inst/graphs/PaxHeaders/prim_mst.m0000644000000000000000000000013214576357161016515 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/prim_mst.m0000644000175000017500000000731714576357161020305 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = prim_mst(edges, vals) %PRIM_MST Minimal spanning tree by Prim's algorithm. % % EDGES2 = prim_mst(EDGES, WEIGHTS) % Compute the minimal spanning tree (MST) of the graph with edges given % by EDGES, and using the specified edge weights. % The nodes of the resulting tree are the same as the nodes of the % original graph. Therefore, the function requires only to specify edges. % % Example % pts = load('sedgewick_points.txt'); % [nodes, edges] = delaunayGraph(pts); % figure; drawGraphEdges(nodes, edges, 'color', 'k'); % axis equal; axis([10 27 10 27]); hold on; % weights = grEdgeLengths(nodes, edges); % edges2 = prim_mst(edges, weights); % drawGraphEdges(nodes, edges2, 'linewidth', 2, 'color', 'b'); % % See also % euclideanMST, grEdgeLengths % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-07-27, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % isolate vertices index nodes = unique(edges(:)); N = length(nodes); % initialize memory nodes2 = zeros(N, 1); edges2 = zeros(N-1, 2); vals2 = zeros(N-1, 1); % initialize with a first node nodes2(1) = nodes(1); nodes = nodes(2:end); % iterate on edges for i = 1:N-1 % find all edges from nodes2 to nodes ind = unique(find(... (ismember(edges(:,1), nodes2(1:i)) & ismember(edges(:,2), nodes)) | ... (ismember(edges(:,1), nodes) & ismember(edges(:,2), nodes2(1:i))) )); % choose edge with lowest value [tmp, ind2] = min(vals(ind)); %#ok ind = ind(ind2(1)); vals2(i) = vals(ind); % index of other vertex edge = edges(ind, :); neigh = edge(~ismember(edge, nodes2)); % add to list of nodes and list of edges nodes2(i+1) = neigh; edges2(i,:) = edge; % remove current node from list of old nodes nodes = nodes(~ismember(nodes, neigh)); end % process output arguments if nargout == 1 varargout{1} = edges2; elseif nargout==2 varargout{1} = edges2; varargout{2} = vals2; end matgeom-1.2.4/inst/graphs/PaxHeaders/grDilate.m0000644000000000000000000000013214576357161016416 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grDilate.m0000644000175000017500000000470214576357161020201 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grDilate(varargin) %GRDILATE Morphological dilation on graph. % % LBL2 = grDilate(EDGES, LBL1) % Each label of the graph is assigned the highest label of its % neighbours, or it keeps the same label this one is bigger. % % Example % grDilate % % See also % grErode, grOpen, grClose % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin) == 2 edges = varargin{1}; lbl = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; lbl = varargin{3}; else error('Wrong number of arguments in "grDilate"'); end lbl2 = zeros(size(lbl)); uni = unique(edges(:)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); lbl2(uni(n)) = max(lbl([uni(n); neigh])); end varargout{1} = lbl2; matgeom-1.2.4/inst/graphs/PaxHeaders/voronoi2d.m0000644000000000000000000000013214576357161016604 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/voronoi2d.m0000644000175000017500000000533714576357161020374 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges, faces] = voronoi2d(germs) %VORONOI2D Compute a voronoi diagram as a graph structure. % % [NODES, EDGES, FACES] = voronoi2d(GERMS) % GERMS an array of points with dimension 2 % NODES, EDGES, FACES: usual graph representation, FACES as cell array % % Example % [n e f] = voronoi2d(rand(100, 2)*100); % drawGraph(n, e); % % See also % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-01-12 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % compute generic Voronoi diagram [V, C] = voronoin(germs); % declaration of array for storing results nodes = V(2:end, :); edges = zeros(0, 2); faces = {}; % iterate on voronoi 'cells' for i = 1:length(C) % get node indices of current polygonal domain cell = C{i}; % do not process unbounded domains if ismember(1, cell) continue; end % fix indexing of nodes cell = cell - 1; % compute indices of edge and domain nodes edges = [edges; sort([cell' cell([2:end 1])'], 2)]; %#ok faces{length(faces)+1} = cell; %#ok end % remove duplicate edges edges = unique(edges, 'rows'); matgeom-1.2.4/inst/graphs/PaxHeaders/clipMesh2dPolygon.m0000644000000000000000000000013214576357161020225 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/clipMesh2dPolygon.m0000644000175000017500000002645714576357161022023 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2, faces2] = clipMesh2dPolygon(nodes, edges, faces, poly) %CLIPMESH2DPOLYGON Clip a planar mesh with a polygon. % % [NODES2, EDGES2, FACES2] = clipMesh2dPolygon(NODES, EDGES, FACES, POLY) % Clips the graph defined by nodes NODES and edges EDGES with the polygon % given in POLY. POLY is a N-by-2 array of vertices. % The result is a new graph containing nodes inside the polygon, as well % as nodes created by the intersection of edges with the polygon. % % Important: it is assumed that no edge crosses the polygon twice. This % is the case if the polygon is convex (or nearly convex) and if the % edges are small compared to the polygon. % % Example % elli = [50 50 40 20 30]; % figure; hold on; % drawEllipse(elli, 'k'); % poly = ellipseToPolygon(elli, 200); % box = polygonBounds(poly); % germs = randomPointInPolygon(poly, 100); % drawPoint(germs, 'b.'); % [n, e, f] = boundedVoronoi2d(box, germs); % [n2, e2, f2] = clipMesh2dPolygon(n, e, f, poly); % drawGraphEdges(n2, e2); % fillGraphFaces(n2, f2); % % See also % graphs, drawGraph, clipGraph % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-24, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % Algorithm summary: % * For each edge not outside do: % * clip edge with poly % * if no inter % * add current edge (same vertex indices) % * continue % * end % * add intersections to list, compute their indices % * create the new edge(s) %% Pre-processing % number of nodes, edges and faces nNodes = size(nodes, 1); nEdges = size(edges, 1); nFaces = meshFaceNumber(nodes, faces); % associate each face to the list of its incident edge faceEdgeInds = meshFaceEdges(nodes, edges, faces); %% Clip the nodes % find index of nodes inside clipping window nodeInside = isPointInPolygon(nodes, poly); innerNodeInds = find(nodeInside); % create correspondance between original nodes and inside nodes nodeIndsMap = zeros(nNodes, 1); for i = 1:length(innerNodeInds) nodeIndsMap(innerNodeInds(i)) = i; end % select clipped nodes nodes2 = nodes(innerNodeInds, :); %% Prepare edge clipping % Need to compute with edges will be kept. This includes (1) edges totally % inside the original polygon and (2) edges clipped by the polygon. % array of boolean flag for each end vertex of each edge insideEnds = nodeInside(edges); % find index of edges totally inside polygon % (do not test intersections with polygon edges) edgeInsideFlag = sum(insideEnds, 2) == 2; innerEdgeInds = find(edgeInsideFlag); % Create correspondance map between original edges and new edges. innerEdgeIndsMap = zeros(nEdges, 1); for i = 1:length(innerEdgeInds) innerEdgeIndsMap(innerEdgeInds(i)) = i; end % create correspondance map between old edges and new edges % Use a cell array, as each edge may be clip into several edges. % The map is initialized with inner edges indices, but may contain indices % of clipped edges in later processing edgeIndsMap = cell(nEdges, 1); for i = 1:length(innerEdgeInds) edgeIndsMap{innerEdgeInds(i)} = i; end % find edges either totally inside polygon, or with one intersection with % the polygon keepEdgeFlag = sum(insideEnds, 2) > 0; % allocate memory for edges to keep (with at least one vertex inside) nEdges2 = sum(keepEdgeFlag); edges2 = zeros(nEdges2, 2); % create correspondance map between new edges and original edge(s) % Use a cell array, as each edge may be clip into several edges. % The map is initialized with inner edges indices, but may contain indices % of clipped edges in later processing edgeIndsMap2 = cell(nEdges2, 1); %% Determine clipped edges % index of next edge % index of next edge to add to the list % iEdge2 = 1; iEdge2 = length(innerEdgeInds) + 1; % index of next vertex iNode2 = size(nodes2, 1) + 1; % iterate over all edges for iEdge = 1:nEdges % index of edge vertices v1 = edges(iEdge, 1); v2 = edges(iEdge, 2); % compute intersection(s) of current edge with polygon boundary edge0 = [nodes(v1,:) nodes(v2,:)]; intersects = intersectEdgePolygon(edge0, poly); % If current edge do not cross polygon boundary, it is either totally % inside or totally outside if isempty(intersects) % check if edge is totally inside the polygon if nodeInside(v1) && nodeInside(v2) % create new edge by converting node indices newEdge = nodeIndsMap([v1 v2])'; % add the new edge to the list of new edges ind = innerEdgeIndsMap(iEdge); edges2(ind,:) = newEdge; % keep index correspondance new->old edgeIndsMap2{ind} = iEdge; end continue; end % add intersection(s) to the vertex array nInters = size(intersects, 1); intersectInds = iNode2:iNode2+nInters-1; nodes2(intersectInds,:) = intersects; iNode2 = iNode2 + nInters; % concatenate vertex indices with indices of extremities inside poly if nodeInside(v1) intersectInds = [nodeIndsMap(v1) intersectInds]; %#ok end if nodeInside(v2) intersectInds = [intersectInds nodeIndsMap(v2)]; %#ok end % determine the number of edges corresponding to the clipped edge % (usually only one) nNewEdges = (nInters + 1) / 2; if nNewEdges ~= round(nNewEdges) warning('matGeom:graphs:AlgorithmicError', ... 'edge %d has odd number of intersects', iEdge); end % compute list of indices of the new edges newEdgeInds = (1:nNewEdges) + iEdge2 - 1; % associate new edge indices to the current edge edgeIndsMap{iEdge} = newEdgeInds; % create a new edge for each pair of contiguous intersections while length(intersectInds) > 1 edges2(iEdge2, :) = intersectInds(1:2); edgeIndsMap2{iEdge2} = iEdge; intersectInds(1:2) = []; iEdge2 = iEdge2 + 1; end if ~isempty(intersectInds) warning('matGeom:graphs:AlgorithmicError', ... 'edge %d has odd number of intersects', iEdge); end end %% Clip faces % initialize new array of faces faces2 = cell(0, 0); iFace2 = 1; for iFace = 1:nFaces % get edge indices of current face edgeInds = faceEdgeInds{iFace}; nodeInds = unique(edges(edgeInds, :)); % check which edges of current face are inside insideFlags = nodeInside(nodeInds); % do not consider faces whose all vertices are outside polygon % (for the moment) if all(~insideFlags) continue; end % check if face is totally within the polygon or if we need to clip the % face with the polygon boundary if all(insideFlags) % convert edge indices edgeInds2 = []; for iEdge = 1:length(edgeInds) edgeInds2 = [edgeInds2 edgeIndsMap{edgeInds(iEdge)}]; %#ok end % convert edge indices to list of vertices faceEdges = edges2(edgeInds2, :); newFace = faceEdges(1, :); nextInd = newFace(2); faceEdges(1,:) = []; while size(faceEdges, 1) > 1 ind = find(sum(faceEdges == nextInd, 2)); nodeInds = faceEdges(ind, :); nextInd = nodeInds(nodeInds ~= nextInd); newFace = [newFace nextInd]; %#ok faceEdges(ind, :) = []; end else % process case of clipped faces % get indices of clipped edges keepFlags = keepEdgeFlag(edgeInds); edgeInds = edgeInds(keepFlags); % convert edge indices edgeInds2 = []; for iEdge = 1:length(edgeInds) edgeInds2 = [edgeInds2 edgeIndsMap{edgeInds(iEdge)}]; %#ok end % convert edge indices to list of vertices faceEdges = edges2(edgeInds2, :); % find a vertex existing only once indices = unique(faceEdges(:)); for i = 1:length(indices) if sum(faceEdges(:) == indices(i)) == 1 ind0 = indices(i); break; end end % initialize new face from single vertex nextInd = ind0; newFace = nextInd; % iterate over edges until other single vertex while size(faceEdges, 1) > 0 ind = find(sum(faceEdges == nextInd, 2)); nodeInds = faceEdges(ind, :); nextInd = nodeInds(nodeInds ~= nextInd); newFace = [newFace nextInd]; %#ok faceEdges(ind, :) = []; end % crop the clipping polygon into two polylines node0 = nodes2(ind0, :); pos0 = projPointOnPolygon(node0, poly); pos1 = projPointOnPolygon(nodes2(nextInd, :), poly); sub1 = polygonSubcurve(poly, pos0, pos1); sub2 = polygonSubcurve(poly, pos1, pos0); % keep only the smallest polyline if polylineLength(sub1) < polylineLength(sub2) sub = sub1; else sub = sub2; end % eventually add polygon vertices contained within subcurve extremities dists = distancePoints(sub([1 end],:), node0); if dists(1) < dists(2) newNodes = sub(end-1:-1:2, :); else newNodes = sub(2:end-1, :); end newNodeInds = (1:size(newNodes, 1)) + size(nodes2, 1); nodes2 = [nodes2; newNodes]; %#ok newFace = [newFace newNodeInds]; %#ok % add new edges newEdges = [[nextInd newNodeInds]' [newNodeInds ind0]']; edges2 = [edges2 ; newEdges]; %#ok end % ensure new face is CCW-oriented if polygonArea(nodes2(newFace, :)) < 0 newFace = newFace([1 end:-1:2]); end % add the new face to the set of new faces faces2{iFace2} = newFace; iFace2 = iFace2 + 1; end matgeom-1.2.4/inst/graphs/PaxHeaders/grRemoveMultiplePoints.m0000644000000000000000000000013214576357161021362 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grRemoveMultiplePoints.m0000644000175000017500000000553114576357161023146 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grRemoveMultiplePoints(nodes, edges) %GRREMOVEMULTIPLEPOINTS Remove groups of close nodes in a graph. % % grRemoveMultiplePoints(nodes, edges) % Detects groups of nodes that belongs to the same global node. % This function is intended to be used as filter after a binary image % skeletonization and vectorization. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE n = 1; while n <= length(nodes) x = nodes(n, 1); y = nodes(n, 2); p1 = findPoint([x-1, y], nodes); p2 = findPoint([x+1, y], nodes); p3 = findPoint([x, y-1], nodes); p4 = findPoint([x, y+1], nodes); p = [p1 p2 p3 p4]; p = p(p ~= 0); if length(p) > 1 [nodes, edges] = grMergeNodes(nodes, edges, [n p]); end n = n+1; end % renumerate edges b = unique(edges(:)); for i = 1:length(b) edges(edges == b(i)) = i; end % remove extra nodes nodes = nodes(b, :); % process output depending on how many arguments are needed if nargout == 1 out{1} = nodes; out{2} = edges; varargout{1} = out; end if nargout == 2 varargout{1} = nodes; varargout{2} = edges; end matgeom-1.2.4/inst/graphs/PaxHeaders/grErode.m0000644000000000000000000000013214576357161016252 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grErode.m0000644000175000017500000000467414576357161020045 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grErode(varargin) %GRERODE Morphological erosion on graph. % % LBL2 = grErode(EDGES, LBL1) % Each label of the graph is assigned the smallest label of its % neighbours, or it keeps the same label this one is smaller. % % Example % grErode % % See also % grDilate, grOpen, grClose % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin) == 2 edges = varargin{1}; lbl = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; lbl = varargin{3}; else error('Wrong number of arguments in "grErode"'); end lbl2 = zeros(size(lbl)); uni = unique(edges(:)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); lbl2(uni(n)) = min(lbl([uni(n); neigh])); end varargout{1} = lbl2; matgeom-1.2.4/inst/graphs/PaxHeaders/boundedCentroidalVoronoi2d.m0000644000000000000000000000013214576357161022112 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/boundedCentroidalVoronoi2d.m0000644000175000017500000000721414576357161023676 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = boundedCentroidalVoronoi2d(germs, box, varargin) %BOUNDEDCENTROIDALVORONOI2D Create a 2D Centroidal Voronoi Tesselation in a box. % % [N, E, F] = boundedCentroidalVoronoi2d(GERMS, BOX) % GERMS are N-by-2 point array, BOX is given as [xmin xmax ymin ymax]. % Algorithm is an iteration of voronoi diagram computations, using at % each steps the centroids of previous diagram as germs for the new % diagram. % % [N, E, F] = boundedCentroidalVoronoi2d(GERMS, BOX, NITER) % Specifies the number of iterations. Default is 10. % % [N, E, F, G] = boundedCentroidalVoronoi2d(...) % also returns the positions of germs/centroids for each face. If the % number of iteration was sufficient, location of germs should correspond % to centroids of faces 'fc' computed using: % fc(i,:) = polygonCentroid(n(f{i}, :)); % % Example % [n, e, f] = boundedCentroidalVoronoi2d(rand(20, 2)*100, [0 100 0 100]); % drawGraph(n, e, f); % % See also % graphs, boundedVoronoi2d, centroidalVoronoi2d, clipGraph % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-01-12 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % number of iteration nIter = 10; if ~isempty(varargin) nIter = varargin{1}; end % limits and size of the box x0 = box(1); x1 = box(2); y0 = box(3); y1 = box(4); dx = x1 - x0; dy = y1 - y0; % far points to bound the voronoi diagram farPoints = [... x1 + 10 * dx, y1 + 10 * dy;... x0 - 10 * dx, y1 + 10 * dy;... x0 - 10 * dx, y0 - 10 * dy;... x1 + 10 * dx, y0 - 10 * dy]; % iterate bounded voronoi tesselation for i = 1:nIter % generate Voronoi diagram, and clip with the box [n, e, f] = voronoi2d([germs ; farPoints]); [n, e, f] = clipGraph(n, e, f, box); % centroid of each face will be used as germs for next iteration for j = 1:length(f) face = n(f{j}, :); germs(j, 1:2) = polygonCentroid(face); end end % result is given in n, e, and f, eventually germs varargout{1} = n; varargout{2} = e; varargout{3} = f; if nargout > 3 varargout{4} = germs; end matgeom-1.2.4/inst/graphs/PaxHeaders/gcontour2d.m0000644000000000000000000000013214576357161016751 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/gcontour2d.m0000644000175000017500000000661614576357161020542 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges] = gcontour2d(img) %GCONTOUR2D Creates contour graph of a 2D binary image. % % deprecated: use imageBoundaryGraph instead % % See also % imageBoundaryGraph % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-25 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE nodes = zeros([0 2]); edges = zeros([0 2]); D1 = size(img, 1); D2 = size(img, 2); % first direction for image for i = 1:D1 % find transitions between the two phases ind = find(img(i, 1:D2-1)~=img(i, 2:D2)); % process each transition in direction 1 for i2 = 1:length(ind) n1 = [i-.5 ind(i2)+.5]; n2 = [i+.5 ind(i2)+.5]; ind1 = find(ismember(nodes, n1, 'rows')); ind2 = find(ismember(nodes, n2, 'rows')); if isempty(ind1) nodes = [nodes; n1]; %#ok ind1 = size(nodes, 1); end if isempty(ind2) nodes = [nodes; n2]; %#ok ind2 = size(nodes, 1); end edges(size(edges, 1)+1, 1:2) = [ind1(1) ind2(1)]; end end % second direction for image for i=1:D2 % find transitions between the two phases ind = find(img(1:D1-1, i)~=img(2:D1, i)); % process each transition in direction 1 for i2 = 1:length(ind) n1 = [ind(i2)+.5 i-.5]; n2 = [ind(i2)+.5 i+.5]; ind1 = find(ismember(nodes, n1, 'rows')); ind2 = find(ismember(nodes, n2, 'rows')); if isempty(ind1) nodes = [nodes; n1]; %#ok ind1 = size(nodes, 1); end if isempty(ind2) nodes = [nodes; n2]; %#ok ind2 = size(nodes, 1); end edges(size(edges, 1)+1, 1:2) = [ind1(1) ind2(1)]; end end matgeom-1.2.4/inst/graphs/PaxHeaders/graphRadius.m0000644000000000000000000000013214576357161017134 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/graphRadius.m0000644000175000017500000000523514576357161020721 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function r = graphRadius(v, e, l) %GRAPHRADIUS Radius of a graph. % % R = graphRadius(V, E) % Computes the radius of the graph given by V and E. The radius of the % graph is the smallest eccentricity over all vertices in the graph. % % R = graphRadius(V, E, L) % Specifies the weight of each edge for computing the distances. Default % is to consider a weight of 1 for each edge. % % Example % nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; % edges = [1 2;2 3;2 4;4 6;5 6;6 7]; % figure; drawGraph(nodes, edges); % axis([0 100 0 100]); axis equal; hold on % R = graphRadius(nodes, edges) % R = % 2 % % See also % grPropagateDistance, grVertexEccentricity % graphCenter, graphDiameter, graphPeripheralVertices % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % ensure there is a valid length array if nargin<3 l = ones(size(e,1), 1); end g = grVertexEccentricity(v, e, l); r = min(g); matgeom-1.2.4/inst/graphs/PaxHeaders/clipGraph.m0000644000000000000000000000013214576357161016574 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/clipGraph.m0000644000175000017500000001660114576357161020360 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = clipGraph(nodes, edges, varargin) %CLIPGRAPH Clip a graph with a rectangular area. % % [N2, E2] = clipGraph(N, E, BOX); % [N2, E2, F2] = clipGraph(N, E, F, BOX); % N is an array ov vertices, E an array of edges, containing indices of % first ans second vertices, and F (optional) is either a matrice or a % cell array containing indices of vertices for each face. % BOX is either a box given as a matrix: [XMIN XMAX;YMIN YMAX], or a row % vector following matlab axis format: [XMIN XMAX YMIN YMAX]. % % Example % % create a simple graph structure % n = [0 60; 40 100; 40 60; 60 40; 100 40; 60 0]; % e = [1 3; 2 3; 3 4; 4 5; 4 6; 5 6]; % figure(1); clf; hold on; % drawGraph(n, e); % axis equal; axis([-10 110 -10 110]); % % clip with a box % box = [10 90 10 90]; % drawBox(box, 'k'); % [n2, e2] = clipGraph(n, e, box); % drawGraphEdges(n2, e2, 'color', 'b', 'linewidth', 2); % % See also % graphs, drawGraph, clipGraphPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-01-18 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas %% Format inputs % extract input arguments faces = []; if length(varargin)==1 box = varargin{1}; elseif length(varargin)==2 faces = varargin{1}; box = varargin{2}; else error('Wrong number of arguments in clipGraph'); end % uniformization of input for box. box = box'; box = box(:); % accuracy of numeric computations ACC = 1e-14; %% Get bounding lines % get bounds of the box xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % create box corners corners = [ ... xmin ymin; ... xmin ymax; ... xmax ymin; ... xmax ymax]; ... %% Clip the nodes % find nodes inside clipping window insideNodes = ... nodes(:,1)-xmin>ACC & nodes(:,1)-xmaxACC & nodes(:,2)-ymax no clip if in1 && in2 edges2 = [edges2; hashNodes(edges(e, :))']; %#ok hashEdges(e) = size(edges2, 1); continue; end % check that edge is not totally clipped -> no edge if edge(1)-xminACC && edge(3)-xmax>ACC, continue; end if edge(2)-yminACC && edge(4)-ymax>ACC, continue; end % otherwise, we have to clip the edge ! edge = clipEdge(edge, [box(1) box(2); box(3) box(4)]); % display debug info % disp(sprintf('clip edge n°%2d, from %2d to %2d', e, edges(e,1), edges(e,2))); % Node for first vertex if ~in1 nodes2 = [nodes2; edge([1 2])]; %#ok indN1 = size(nodes2, 1); else indN1 = hashNodes(edges(e, 1)); end % Node for second vertex if ~in2 nodes2 = [nodes2; edge([3 4])]; %#ok indN2 = size(nodes2, 1); else indN2 = hashNodes(edges(e, 2)); end % add clipped edge to the list edges2 = [edges2; indN1 indN2]; %#ok hashEdges(e) = size(edges2, 1); end %% Clip the faces faces2 = {}; for f = 1:length(faces) % indices of vertices of current face face = faces{f}; % if the face is not clipped, use directly new indices of nodes face2 = hashNodes(face)'; if ~ismember(0, face2) faces2 = [faces2, {face2}]; %#ok continue; end % At least one vertex is clipped. Here is some more special processing % edges of current face faceEdges = sort([face' face([2:end 1])'], 2); % indices of face edges in edges array indEdges = ismember(edges, faceEdges, 'rows'); % convert to indices of edges in clipped edges array. indEdges with % value=0 correspond to totally clipped edges, and can be removed. indEdges = hashEdges(indEdges); indEdges = indEdges(indEdges~=0); % case of face totally clipped: break and continuue with next face if isempty(indEdges) continue; end % extract indices of vertices of the clipped face face2 = edges2(indEdges, :); face2 = unique(face2(:)); % Test whether one should add one of the corner of the box. poly = [nodes(face, 1) nodes(face, 2)]; ind = inpolygon(corners(:,1), corners(:,2), poly(:,1), poly(:,2)); if sum(ind)>0 nodes2 = [nodes2; corners(ind, :)]; %#ok face2 = [face2; size(nodes2, 1)]; %#ok end % vertices of the face, as points faceNodes = nodes2(face2, :); % sort vertices according to their angle around the centroid [faceNodes, I] = angleSort(faceNodes, centroid(faceNodes)); %#ok % add current face to list of faces faces2 = [faces2, {face2(I)'}]; %#ok end %% Format output arguments % clean up nodes to ensure coord correspond to clipping box. nodes2(:,1) = min(max(nodes2(:,1), box(1)), box(2)); nodes2(:,2) = min(max(nodes2(:,2), box(3)), box(4)); if nargout==2 varargout{1} = nodes2; varargout{2} = edges2; elseif nargout==3 varargout{1} = nodes2; varargout{2} = edges2; varargout{3} = faces2; end matgeom-1.2.4/inst/graphs/PaxHeaders/grRemoveNode.m0000644000000000000000000000013214576357161017257 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grRemoveNode.m0000644000175000017500000000517114576357161021043 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2] = grRemoveNode(nodes, edges, node) %GRREMOVENODE Remove a node in a graph. % % usage: % [NODES2 EDGES2] = grRemoveNode(NODES, EDGES, NODE2REMOVE) % remove the node with index NODE2REMOVE from array NODES, and also % remove edges containing the node NODE2REMOVE. % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % remove all edges connected to the node neighbours = grAdjacentEdges(edges, node); [nodes2, edges2] = grRemoveEdges(nodes, edges, neighbours); %#ok % change edges information, due to the node index shift for i = 1:length(edges2) if edges2(i,1) > node edges2(i,1) = edges2(i,1) - 1; end if edges2(i,2) > node edges2(i,2) = edges2(i,2) - 1; end end % allocate memory dim = size(nodes); nodes2 = zeros(dim(1)-1, 2); % copy nodes information, except the undesired node nodes2(1:node-1, :) = nodes(1:node-1, :); nodes2(node:dim(1)-1, :) = nodes(node+1:dim(1), :); matgeom-1.2.4/inst/graphs/PaxHeaders/gabrielGraph.m0000644000000000000000000000013214576357161017252 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/gabrielGraph.m0000644000175000017500000000663614576357161021045 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = gabrielGraph(pts) %GABRIELGRAPH Gabriel Graph of a set of points. % % EDGES = gabrielGraph(PTS) % Computes the Gabriel graph of the input set of points PTS. The Gabriel % graph is based on the euclidean Delaunay triangulation, and keeps only % edges whose circumcircle does not contain any other input point than % the edge extremities. % % [NODES, EDGES] = gabrielGraph(PTS) % Also returns the initial set of points; % % Example % pts = rand(100, 2); % edges = gabrielGraph(pts); % figure; drawPoint(pts); % hold on; axis([0 1 0 1]); axis equal; % drawGraph(pts, edges); % % See also % graphs, drawGraph, delaunayGraph % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-01-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % compute Delaunay triangulation if verLessThan('matlab', '8.1') % Code for versions before R2013a dt = DelaunayTri(pts); %#ok else % Code for versions R2013a and later dt = delaunayTriangulation(pts); end % extract edges (N-by-2 array) eds = dt.edges(); % radius of the circle circumscribed to each edge rads = edgeLength([pts(eds(:,1), :) pts(eds(:,2), :)]) / 2; % extract middle point of each edge midPts = midPoint(pts(eds(:,1), :), pts(eds(:,2), :)); % distance between midpoints and all points % closest points should be edge vertices dists = minDistancePoints(midPts, pts); % geometric tolerance (adapted to point set extent) tol = max(max(pts) - min(pts)) * eps; % keep only edges whose circumcircle does not contain any other point keep = dists >= rads - tol; edges = eds(keep, :); % format output depending on number of output arguments if nargout < 2 varargout = {edges}; else varargout = {pts, edges}; end matgeom-1.2.4/inst/graphs/PaxHeaders/grFaceToPolygon.m0000644000000000000000000000013214576357161017725 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grFaceToPolygon.m0000644000175000017500000000702014576357161021504 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function pts2 = grFaceToPolygon(varargin) %GRFACETOPOLYGON Compute the polygon corresponding to a graph face. % % PTS2 = grFaceToPolygon(NODES, EDGES, FACES, INDF) % PTS2 = grFaceToPolygon(NODES, FACES, INDF) % Where NODES, EDGES, and FACES are internal data of graph, and INDF is % the index of the face to extract. The result is the (ordered) set of % points composing the face. % % % PTS2 = grFaceToPolygon(GRAPH, INDF) % use structure representation for graph. The structure GRAPH must % contain data for fields 'nodes' and 'faces'. % % If several indices face indices are specified, result is a cell array % of polygons. % % The number of columns of PTS2 is the same as for NODES. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-30 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin)==2 % argument is a graph structure graph = varargin{1}; nodes = graph.nodes; faces = graph.faces; indf = varargin{2}; elseif length(varargin)==3 % arguments are nodes, faces and indices nodes = varargin{1}; faces = varargin{2}; indf = varargin{3}; elseif length(varargin)==4 % arguments are nodes, edges, faces and indices, we forget edges nodes = varargin{1}; faces = varargin{3}; indf = varargin{4}; end if iscell(faces) % faces is a cell array if length(indf)==1 face = faces{indf}; pts2 = nodes(face, :); else pts2 = cell(length(indf), 1); for i=1:length(indf) face = faces{indf(i)}; pts2{i} = nodes(face, :); end end else % faces is an indices array: all faces have same number of vertices if length(indf)==1 face = faces(indf, :); pts2 = nodes(face, :); else pts2 = cell(length(indf), 1); for i=1:length(indf) face = faces(indf(i), :); pts2{i} = nodes(face, :); end end end matgeom-1.2.4/inst/graphs/PaxHeaders/grEdgeLengths.m0000644000000000000000000000013214576357161017405 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grEdgeLengths.m0000644000175000017500000000513014576357161021164 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function lengths = grEdgeLengths(nodes, edges, varargin) %GREDGELENGTHS Compute length of edges in a geometric graph. % % LENGTHS = grEdgeLengths(NODES, EDGES) % % Example % % create a basic graph and display it % nodes = [10 10;20 10;10 20;20 20;27 15]; % edges = [1 2;1 3;2 4;2 5;3 4;4 5]; % figure; drawGraph(nodes, edges); % hold on; drawNodeLabels(nodes, 1:5) % axis equal; axis([0 40 0 30]); % % compute list of nodes adjacent to node with index 2 % grEdgeLengths(nodes, edges)' % ans = % 10.0000 10.0000 10.0000 8.6023 10.0000 8.6023 % % See also % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2014-01-13, using Matlab 7.9.0.529 (R2009b) % Copyright 2014-2023 INRA - Cepia Software Platform nEdges = size(edges, 1); lengths = zeros(nEdges, 1); for iEdge = 1:nEdges ed = edges(iEdge, :); node1 = nodes(ed(1),:); node2 = nodes(ed(2),:); lengths(iEdge) = sqrt(sum((node1 - node2).^2)); end matgeom-1.2.4/inst/graphs/PaxHeaders/grRemoveEdge.m0000644000000000000000000000013214576357161017236 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grRemoveEdge.m0000644000175000017500000000417614576357161021026 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges2] = grRemoveEdge(nodes, edges, edge) %GRREMOVEEDGE Remove an edge in a graph. % % [NODES2 EDGES2] = grRemoveEdge(NODES, EDGES, EDGE2REMOVE) % Remove an edge in the edges list, and return the modified graph. % The NODES array is not modified. % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE dim = size(edges); edges2 = zeros(dim(1)-1, 2); edges2(1:edge-1, :) = edges(1:edge-1, :); edges2(edge:dim(1)-1, :) = edges(edge+1:dim(1), :); matgeom-1.2.4/inst/graphs/PaxHeaders/graphPeripheralVertices.m0000644000000000000000000000013214576357161021505 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/graphPeripheralVertices.m0000644000175000017500000000534314576357161023272 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function inds = graphPeripheralVertices(v, e, l) %GRAPHPERIPHERALVERTICES Peripheral vertices of a graph. % % INDS = graphPeripheralVertices(V, E) % Return indices of peripheral vertices, that is, vertices whose % eccentricity is maximal and equal to the diameter of the graph. % % INDS = graphPeripheralVertices(V, E, L) % Specify length of each edge. Default is 1 for each edge. % % % Example % nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; % edges = [1 2;2 3;2 4;4 6;5 6;6 7]; % figure; drawGraph(nodes, edges); % axis([0 100 0 100]); axis equal; hold on % INDP = graphPeripheralVertices(nodes, edges); % INDP = % 1 % 3 % 5 % 7 % % % See also % grPropagateDistance, grVertexEccentricity % graphCenter, graphDiameter, graphRadius % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % ensure there is a valid length array if nargin<3 l = ones(size(e,1), 1); end g = grVertexEccentricity(v, e, l); inds = find(g==max(g)); matgeom-1.2.4/inst/graphs/PaxHeaders/boundedVoronoi2d.m0000644000000000000000000000013214576357161020105 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/boundedVoronoi2d.m0000644000175000017500000000653514576357161021676 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges, faces] = boundedVoronoi2d(box, germs) %BOUNDEDVORONOI2D Computes a bounded voronoi diagram as a graph structure. % % [NODES, EDGES, FACES] = boundedVoronoi2d(BOX, GERMS) % GERMS an array of points with dimension 2 % NODES, EDGES, FACES: usual graph representation, FACES as cell array % % Example % % clip a graph with % box = [0 100 0 100]; % [n, e, f] = boundedVoronoi2d(box, rand(100, 2)*100); % [n, e, f] = clipGraph(n, e, f, box); % drawGraph(n, e); % % See also % graphs, boundedCentroidalVoronoi2d, clipGraph, clipGraphPolygon % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-01-12 % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % uniformize input for box. box = box'; box = box(:); % add points far enough boxSizeX = box(2) - box(1); boxSizeY = box(4) - box(3); farPoints = [... box(2)+2*boxSizeX box(4)+3*boxSizeY;... box(1)-3*boxSizeX box(4)+2*boxSizeY;... box(1)-2*boxSizeX box(3)-3*boxSizeY;... box(2)+3*boxSizeX box(3)-2*boxSizeY;... ]; % extract voronoi vertices and face structure [V, C] = voronoin([germs ; farPoints]); % initialize graph structure, without edges and without faces nodes = V(2:end, :); edges = zeros(0, 2); faces = cell(1, size(germs, 1)); % for each cell associated to a germ, we retrieve the nodes of the Voronoi % diagram, remove 1 because first vertex at infinity is removed, keep the % list of vertices that constitute the face, and generate the set of edges % around face. for i = 1:size(germs, 1) face = C{i}; face = face-1; faces{i} = face; edges = [edges; sort([face' face([2:end 1])'], 2)]; %#ok end % remove duplicate edges as they were created twice (once for each face) edges = unique(edges, 'rows'); matgeom-1.2.4/inst/graphs/PaxHeaders/knnGraph.m0000644000000000000000000000013214576357161016433 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/knnGraph.m0000644000175000017500000000473514576357161020224 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges = knnGraph(nodes, varargin) %KNNGRAPH Create the k-nearest neighbors graph of a set of points. % % EDGES = knnGraph(NODES) % % Example % nodes = rand(10, 2); % edges = knnGraph(nodes); % drawGraph(nodes, edges); % % See also % graphs % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2008-07-28, using Matlab 7.4.0.287 (R2007a) % Copyright 2008-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % get number of neighbors for each node k = 2; if ~isempty(varargin) k = varargin{1}; end % init size of arrays n = size(nodes, 1); edges = zeros(k*n, 2); % iterate on nodes for i = 1:n dists = distancePoints(nodes(i,:), nodes); [dists, inds] = sort(dists); %#ok for j = 1:k edges(k*(i-1)+j, :) = [i inds(j+1)]; end end % remove double edges edges = unique(sort(edges, 2), 'rows'); matgeom-1.2.4/inst/graphs/PaxHeaders/cvtIterate.m0000644000000000000000000000013214576357161016775 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/cvtIterate.m0000644000175000017500000000732414576357161020563 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cvtIterate(germs, funcPtr, funcArgs, N) %CVTITERATE Update germs of a CVT using random points with given density. % % G2 = cvtIterate(G, FPTR, FARGS, N) % G: inital germs % FPTR: pointer to a function which accept a scalar M and return M random % points with a given distribution % FARGS: arguments to be given to the FPTR function (can be empty) % N: number of random points to generate % % Example % P = randPointDiscUnif(50); % P2 = cvtIterate(P, @randPointDiscUnif, [], 1000); % P3 = cvtIterate(P2, @randPointDiscUnif, [], 1000); % % See also % % % Rewritten from programs found in % http://people.scs.fsu.edu/~burkardt/m_src/cvt/cvt.html % % Reference: % Qiang Du, Vance Faber, and Max Gunzburger, % Centroidal Voronoi Tessellations: Applications and Algorithms, % SIAM Review, Volume 41, 1999, pages 637-676. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-10, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas %% Init % format input if isempty(funcArgs) funcArgs = {}; end % number of germs Ng = size(germs, 1); % initialize centroids with values of germs centroids = germs; % number of updates of each centroid count = ones(Ng, 1); %% random points % generate N random points pts = feval(funcPtr, N, funcArgs{:}); % for each point, determines which germ is the closest ones [dist, ind] = minDistancePoints(pts, germs); %#ok h = zeros(Ng, 1); for i = 1:Ng h(i) = sum(ind==i); end %% Centroids update % add coordinate of each point to closest centroid energy = 0; for j = 1:N centroids(ind(j), :) = centroids(ind(j), :) + pts(j, :); energy = energy + sum ( ( centroids(ind(j), :) - pts(j, :) ).^2); count(ind(j)) = count(ind(j)) + 1; end % estimate coordinate by dividing by number of counts centroids = centroids ./ repmat(count, 1, size(germs, 2)); % normalizes energy by number of sample points energy = energy / N; %% format output varargout{1} = centroids; if nargout > 1 varargout{2} = energy; end matgeom-1.2.4/inst/graphs/PaxHeaders/quiverToGraph.m0000644000000000000000000000013214576357161017463 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/quiverToGraph.m0000644000175000017500000000524414576357161021250 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [v, e] = quiverToGraph(x, y, dx, dy) %QUIVERTOGRAPH Converts quiver data to quad mesh. % % [V E] = quiverToGraph(x, y, dx, dy) % x, y, dx and dy are matrices the same dimension, typically ones used % for display using 'quiver'. % V and E are vertex coordinates, and edge vertex indices of the graph % joining end points of vector arrows. % % Example % quiverToGraph % % See also % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-06-16, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % compute vertex coordinates vx = x+dx; vy = y+dy; v = [vx(:) vy(:)]; % index of vertices labels = reshape(1:numel(x), size(x)); % compute indices of vertical edges N1 = numel(labels(1:end-1,:)); vedges = [reshape(labels(1:end-1, :), [N1 1]) reshape(labels(2:end, :), [N1 1])]; % compute indices of horizontal edges N2 = numel(labels(:, 1:end-1)); hedges = [reshape(labels(:, 1:end-1), [N2 1]) reshape(labels(:, 2:end), [N2 1])]; % concatenate horizontal and vertical edges e = [hedges ; vedges]; matgeom-1.2.4/inst/graphs/PaxHeaders/grNodeOuterDegree.m0000644000000000000000000000013214576357161020234 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grNodeOuterDegree.m0000644000175000017500000000453314576357161022021 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function degree = grNodeOuterDegree(node, edges) %GRNODEOUTERDEGREE Outer degree of a node in a graph. % % DEG = grNodeOuterDegree(NODE, EDGES); % Returns the outer degree of a node in the given edge list, i.e. the % number of edges emanating from it. % NODE is the index of the node, and EDGES is a liste of couples of % indices (origin and destination node). % % Note: Also works when node is a vector of indices % % See also % grNodeDegree, grNodeInnerDegree % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-17 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % allocate memory N = size(node, 1); degree = zeros(N, 1); % compute outer degree of each vertex for i=1:N degree(i) = sum(edges(:,1)==node(i)); end matgeom-1.2.4/inst/graphs/PaxHeaders/grVertexEccentricity.m0000644000000000000000000000013214576357161021037 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grVertexEccentricity.m0000644000175000017500000000565414576357161022631 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function g = grVertexEccentricity(v, e, l, inds) %GRVERTEXECCENTRICITY Eccentricity of vertices in the graph. % % G = grVertexEccentricity(V, E, L) % V is the array of vertices % E is the array of edges % L is a column vector containing length of each edge (assumes 1 for each % edge if not specified). % G is the maximal geodesic length of each vertex. % % G = grVertexEccentricity(V, E, L, INDV) % Compute eccentricity only for vertices whose index is given in INDV. % % Example % nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; % edges = [1 2;2 3;2 4;4 6;5 6;6 7]; % figure; drawGraph(nodes, edges); % axis([0 100 0 100]); axis equal; hold on % G = grVertexEccentricity(nodes, edges); % drawNodeLabels(nodes+2, G); % % See also % graphRadius, graphCenter, graphDiameter, graphPeripheralVertices % grPropagateDistance % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % init result Nv = size(v, 1); g = zeros(Nv, 1); % ensure there is a valid length array if nargin<3 l = ones(size(e,1), 1); end if nargin<4 inds = 1:Nv; end % compuite maximal geodesic length for each vertex for i=1:Nv g(i) = max(grPropagateDistance(v, e, inds(i), l)); end matgeom-1.2.4/inst/graphs/PaxHeaders/drawDirectedEdges.m0000644000000000000000000000013214576357161020234 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/drawDirectedEdges.m0000644000175000017500000000646114576357161022023 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawDirectedEdges(nodes, edges, varargin) %DRAWDIRECTEDEDGES Draw edges with arrow indicating direction. % % usage: % drawDirectedEdges(NODES, EDGES); % Draw edges joining nodes at position NODES, using a small arrow mark to % depict the direction of the edges? % % % drawDirectedEdges(NODES, EDGES, DIRECT) % Also specifies the base direction of all edges. DIRECT is true by % default. If DIRECT is false all edges are inverted. % % H = drawDirectedEdges(NODES, EDGES) % Returns handles to each of the lines created. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-03-12 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % determinate direction of arrows direct = true; if ~isempty(varargin) direct = varargin{1}; end % prepare display hold on; % iterate on edges to draw h = zeros(length(edges),1); for ie = 1:length(edges) p1 = edges(ie, 1); p2 = edges(ie, 2); h(ie*4) = line([nodes(p1,1) nodes(p2,1)], [nodes(p1,2) nodes(p2,2)]); % position of middles of edge xm = (nodes(p1,1) + nodes(p2,1))/2; ym = (nodes(p1,2) + nodes(p2,2))/2; % orientation of edge theta = atan2(nodes(p2,2) - nodes(p1,2), nodes(p2,1) - nodes(p1,1)) + (direct==0)*pi; % pin of the arrow xa0 = xm + 10*cos(theta); ya0 = ym + 10*sin(theta); % right side of the arrow xa1 = xm + 3*cos(theta-pi/2); ya1 = ym + 3*sin(theta-pi/2); % left side of the arrow xa2 = xm + 3*cos(theta+pi/2); ya2 = ym + 3*sin(theta+pi/2); h(ie*4+1) = line([xa1 xa0], [ya1 ya0]); h(ie*4+2) = line([xa2 xa0], [ya2 ya0]); end if nargout == 1 varargout(1) = {h}; end matgeom-1.2.4/inst/graphs/PaxHeaders/grMergeNodes.m0000644000000000000000000000013214576357161017244 xustar0030 mtime=1710874225.166193317 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grMergeNodes.m0000644000175000017500000000523614576357161021032 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges] = grMergeNodes(nodes, edges, mnodes) %GRMERGENODES Merge two (or more) nodes in a graph. % % usage: % [NODES2 EDGES2] = grMergeNodes(NODES, EDGES, NODE_INDS) % NODES and EDGES are wo arrays representing a graph, and NODE_INDS is % the set of indices of the nodes to merge. % The nodes corresponding to indices in NODE_INDS are removed from the % list, and edges between two nodes are removed. % % Example: merging of lables 1 and 2 % Edges: Edges2: % [1 2] [1 3] % [1 3] [1 4] % [1 4] [3 4] % [2 3] % [3 4] % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-30 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE refNode = mnodes(1); mnodes = mnodes(2:length(mnodes)); % replace merged nodes references by references to refNode edges(ismember(edges, mnodes))=refNode; % remove "loop edges" from and to reference node edges = edges(edges(:,1) ~= refNode | edges(:,2) ~= refNode, :); % format output edges = sortrows(unique(sort(edges, 2), 'rows')); matgeom-1.2.4/inst/graphs/PaxHeaders/graphCenter.m0000644000000000000000000000013214576357161017125 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.166193317 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/graphCenter.m0000644000175000017500000000535514576357161020715 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function center = graphCenter(v, e, l) %GRAPHCENTER Center of a graph. % % CENTER = graphCenter(V, E) % Computes the center of the graph given by V and E. The center of the % graph is the set of vertices whose eccentricity is minimal. The % function returns indices of center vertices. % % CENTER = graphCenter(V, E, L) % Specifies the weight of each edge for computing the distances. Default % is to consider a weight of 1 for each edge. % % Example % nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; % edges = [1 2;2 3;2 4;4 6;5 6;6 7]; % figure; drawGraph(nodes, edges); % axis([0 100 0 100]); axis equal; hold on % C = graphCenter(nodes, edges) % C = % 4 % % See also % grPropagateDistance, grVertexEccentricity % graphRadius, graphDiameter, graphPeripheralVertices % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % ensure there is a valid length array if nargin<3 l = ones(size(e,1), 1); end g = grVertexEccentricity(v, e, l); center = find(g==min(g)); matgeom-1.2.4/inst/graphs/PaxHeaders/delaunayGraph.m0000644000000000000000000000013214576357161017447 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/delaunayGraph.m0000644000175000017500000000604214576357161021231 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [points, edges] = delaunayGraph(points, varargin) %DELAUNAYGRAPH Graph associated to Delaunay triangulation of input points. % % [NODES, EDGES] = delaunayGraph(POINTS) % Compute the Delaunay triangulation of the set of input points, and % convert to a set of edges. The output NODES is the same as the input % POINTS. % % Example % % Draw a planar graph correpspionding to Delaunay triangulation % points = rand(30, 2) * 100; % [nodes, edges] = delaunayGraph(points); % figure; % drawGraph(nodes, edges); % % % Draw a 3D graph corresponding to Delaunay tetrahedrisation % points = rand(20, 3) * 100; % [nodes, edges] = delaunayGraph(points); % figure; % drawGraph(nodes, edges); % view(3); % % See also % delaunay, delaunayn, delaunayTriangulation % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-19, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % compute triangulation tri = delaunayn(points, varargin{:}); % number of simplices (triangles), and of vertices by simplex (3 in 2D) nt = size(tri, 1); nv = size(tri, 2); % allocate memory edges = zeros(nt * nv, 2); % compute edges of each simplex for i = 1:nv-1 edges((1:nt) + (i-1)*nt, :) = sort([tri(:, i) tri(:, i+1)], 2); end edges((1:nt) + (nv-1)*nt, :) = sort([tri(:, end) tri(:, 1)], 2); % remove multiple edges edges = unique(edges, 'rows'); matgeom-1.2.4/inst/graphs/PaxHeaders/drawGraphEdges.m0000644000000000000000000000013214576357161017552 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/drawGraphEdges.m0000644000175000017500000000767514576357161021351 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawGraphEdges(varargin) %DRAWGRAPHEDGES Draw edges of a graph. % % drawGraphEdges(NODES, EDGES) % Draws a graph specified by a set of nodes (array N-by-2 or N-by-3, % corresponding to coordinate of each node), and a set of edges (an array % Ne-by-2, containing to the first and the second node of each edge). % % drawGraphEdges(..., SEDGES) % Specifies the draw mode for each element, as in the classical 'plot' % function. % Default drawing is a blue line for edges. % % % H = drawGraphEdges(...) % Returns handle to the set of edges. % % See also % graphs, drawGraph, fillGraphFaces % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-24 % Copyright 2005-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) %% Input argument processing % initialisations e = []; % check input arguments number if nargin == 0 help drawGraphEdges; return; end % extract handle of axis to draw on if isAxisHandle(varargin{1}) ax = varargin{1}; varargin(1) = []; else ax = gca; end % First extract the graph structure var = varargin{1}; if iscell(var) % TODO: should consider array of graph structures. % graph is stored as a cell array: first cell is nodes, second one is % edges, and third one is faces n = var{1}; if length(var) > 1 e = var{2}; end varargin(1) = []; elseif isstruct(var) % graph is stored as a structure, with fields 'nodes', 'edges' n = var.nodes; e = var.edges; varargin(1) = []; else % graph is stored as set of variables: nodes + edges n = varargin{1}; e = varargin{2}; varargin(1:2) = []; end % check if there are edges to draw if size(e, 1) == 0 return; end % setup default drawing style if not specified if isempty(varargin) varargin = {'-b'}; end %% main drawing processing if size(n, 2) == 2 % Draw 2D edges x = [n(e(:,1), 1) n(e(:,2), 1)]'; y = [n(e(:,1), 2) n(e(:,2), 2)]'; he = plot(ax, x, y, varargin{:}); elseif size(n, 2) == 3 % Draw 3D edges x = [n(e(:,1), 1) n(e(:,2), 1)]'; y = [n(e(:,1), 2) n(e(:,2), 2)]'; z = [n(e(:,1), 3) n(e(:,2), 3)]'; he = plot3(ax, x, y, z, varargin{:}); end %% format output arguments if nargout == 1 varargout = {he}; end matgeom-1.2.4/inst/graphs/PaxHeaders/grAdjacentNodes.m0000644000000000000000000000013214576357161017716 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grAdjacentNodes.m0000644000175000017500000000541214576357161021500 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function nodes2 = grAdjacentNodes(edges, node) %GRADJACENTNODES Find list of nodes adjacent to a given node. % % NEIGHS = grAdjacentNodes(EDGES, NODE) % EDGES: the complete edges list (containing indices of neighbor nodes) % NODE: index of the node % NEIGHS: the nodes adjacent to the given node. % % NODE can also be a vector of node indices, in this case the result is % the set of neighbors of any input node, excluding the input nodes. % % Example % % create a basic graph and display it % nodes = [10 10;20 10;10 20;20 20;27 15]; % edges = [1 2;1 3;2 4;2 5;3 4;4 5]; % figure; drawGraph(nodes, edges); % hold on; drawNodeLabels(nodes, 1:5) % axis equal; axis([0 40 0 30]); % % compute list of nodes adjacent to node with index 2 % grAdjacentNodes(edges, 2) % ans = % 1 % 4 % 5 % % See also % grAdjacentEdges % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-08-16 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE [i, j] = find(ismember(edges, node)); %#ok nodes2 = edges(i,1:2); nodes2 = unique(nodes2(:)); nodes2 = sort(nodes2(~ismember(nodes2, node))); matgeom-1.2.4/inst/graphs/PaxHeaders/euclideanMST.m0000644000000000000000000000013214576357161017200 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/euclideanMST.m0000644000175000017500000000726514576357161020772 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = euclideanMST(points) %EUCLIDEANMST Build euclidean minimal spanning tree of a set of points. % % EDGES = euclideanMST(POINTS) % POINTS is a [NxP] array, N being the number of points and P being the % dimension. % Result EDGES is a [Mx2] array, containing indices of each vertex for % each edges. % % [EDGES DISTS] = euclideanMST(POINTS) % Also returns the lengths of edges computed by MST algorithm. % % Algorithm first computes Delaunay triangulation of the set of points, % then computes euclidean length of each edge of triangulation, and % finally uses prim algorithm to simplify the graph. % % Example % % choose random points in the plane and display their Euclidean MST % pts = rand(50, 2)*100; % edges = euclideanMST(pts); % drawGraph(pts, edges) % % See also % prim_mst, distancePoints, delaunayn % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-07-27, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % dimension D = size(points, 2); Df = factorial(D); % compute all couples of vertices in unit triangle, tetrahedron, or n-dim % simplex subs = zeros(Df, 2); k = 1; for i = 1:D for j = i+1:D+1 subs(k, 1) = i; subs(k, 2) = j; k = k + 1; end end % compute delaunay triangulation in D dimensions tri = delaunayn(points); Nt = size(tri, 1); % compute all possible edges edges = zeros(Nt*Df, 2); for t = 1:Nt for i = 1:Df edges((t-1)*Df+i, 1) = tri(t, subs(i, 1)); edges((t-1)*Df+i, 2) = tri(t, subs(i, 2)); end end % simplify edges edges = unique(sort(edges, 2), 'rows'); % compute euclidean length of each edge val = zeros(size(edges, 1), 1); for i = 1:size(edges,1) val(i) = distancePoints(points(edges(i,1), :), points(edges(i,2), :)); end % compute MST of created graph [edges2, vals2] = prim_mst(edges, val); % process output arguments if nargout == 1 varargout{1} = edges2; elseif nargout==2 varargout{1} = edges2; varargout{2} = vals2; end matgeom-1.2.4/inst/graphs/PaxHeaders/drawSquareMesh.m0000644000000000000000000000013214576357161017616 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/drawSquareMesh.m0000644000175000017500000000501014576357161021372 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawSquareMesh(nodes, edges, faces, varargin) %#ok %DRAWSQUAREMESH Draw a 3D square mesh given as a graph. % % drawSquareMesh(NODES, EDGES, FACES) % Draw the mesh defined by NODES, EDGES and FACES. FACES must be a N-by-4 % array of vertex indices. % % See also % boundaryGraph, drawGraph % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-28 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE % input size check up if size(faces, 2) ~= 4 error('Requires a face array with 4 columns'); end % number of faces Nf = size(faces, 1); % allocate memory for vertex coordinates px = zeros(4, Nf); py = zeros(4, Nf); pz = zeros(4, Nf); % initialize vertex coordinates of each face for f = 1:Nf face = faces(f, 1:4); px(1:4, f) = nodes(face, 1); py(1:4, f) = nodes(face, 2); pz(1:4, f) = nodes(face, 3); end p = patch(px, py, pz, 'r'); if nargout > 0 varargout = {p}; end matgeom-1.2.4/inst/graphs/PaxHeaders/gcontour3d.m0000644000000000000000000000013214576357161016752 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/gcontour3d.m0000644000175000017500000001273514576357161020542 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges, faces] = gcontour3d(img) %GCONTOUR3D Create contour graph of a 3D binary image. % % deprecated: use imageBoundaryGraph instead % % See also % imageBoundaryGraph % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-28 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE nodes = zeros([0 3]); % 3 coordinates vertices edges = zeros([0 2]); % first node and second nodes faces = zeros([0 4]); % indices of 4 corners of each square face D1 = size(img, 1); D2 = size(img, 2); D3 = size(img, 3); % first direction for image for y = 1:D2 for z = 1:D3 % find transitions between the two phases ind = find(img(1:D1-1, y, z)~=img(2:D1, y, z)); % process each transition in direction 1 for i2 = 1:length(ind) % coordinates of each node n1 = [ind(i2)+.5 y-.5 z-.5]; n2 = [ind(i2)+.5 y-.5 z+.5]; n3 = [ind(i2)+.5 y+.5 z+.5]; n4 = [ind(i2)+.5 y+.5 z-.5]; % add the face (and edges) with the 4 given nodes [nodes, edges, faces] = addFace(nodes, edges, faces, [n1; n2; n3; n4]); end end end % second direction for image for x=1:D1 for z=1:D3 % find transitions between the two phases ind = find(img(x, 1:D2-1, z)~=img(x, 2:D2, z)); % process each transition in direction 1 for i2 = 1:length(ind) % coordinates of each node n1 = [x-.5 ind(i2)+.5 z-.5]; n2 = [x-.5 ind(i2)+.5 z+.5]; n3 = [x+.5 ind(i2)+.5 z+.5]; n4 = [x+.5 ind(i2)+.5 z-.5]; % add the face (and edges) with the 4 given nodes [nodes, edges, faces] = addFace(nodes, edges, faces, [n1; n2; n3; n4]); end end end % third direction for image for x=1:D1 for y=1:D2 % find transitions between the two phases ind = find(img(x, y, 1:D3-1)~=img(x, y, 2:D3)); % process each transition in direction 1 for i2 = 1:length(ind) % coordinates of each node n1 = [x-.5 y-.5 ind(i2)+.5]; n2 = [x-.5 y+.5 ind(i2)+.5]; n3 = [x+.5 y+.5 ind(i2)+.5]; n4 = [x+.5 y-.5 ind(i2)+.5]; % add the face (and edges) with the 4 given nodes [nodes, edges, faces] = addFace(nodes, edges, faces, [n1; n2; n3; n4]); end end end return; function [nodes, edges, faces] = addFace(nodes, edges, faces, faceNodes) % add given nodes and coresponding face to the graph. n1 = faceNodes(1,:); n2 = faceNodes(2,:); n3 = faceNodes(3,:); n4 = faceNodes(4,:); % search indices of each nodes ind1 = find(ismember(nodes, n1, 'rows')); ind2 = find(ismember(nodes, n2, 'rows')); ind3 = find(ismember(nodes, n3, 'rows')); ind4 = find(ismember(nodes, n4, 'rows')); % if nodes are not in the list, we add them if isempty(ind1) nodes = [nodes; n1]; ind1 = size(nodes, 1); end if isempty(ind2) nodes = [nodes; n2]; ind2 = size(nodes, 1); end if isempty(ind3) nodes = [nodes; n3]; ind3 = size(nodes, 1); end if isempty(ind4) nodes = [nodes; n4]; ind4 = size(nodes, 1); end % add current face to the list faces(size(faces, 1)+1, 1:4) = [ind1(1) ind2(1) ind3(1) ind4(1)]; % create edges of the face % (first index is the smallest one, by convention) e1 = [min(ind1, ind2) max(ind1, ind2)]; e2 = [min(ind2, ind3) max(ind2, ind3)]; e3 = [min(ind3, ind4) max(ind3, ind4)]; e4 = [min(ind4, ind1) max(ind4, ind1)]; % if nodes are not in the list, we add them if isempty(find(ismember(edges, e1, 'rows'), 1)) edges = [edges; e1]; end if isempty(find(ismember(edges, e2, 'rows'), 1)) edges = [edges; e2]; end if isempty(find(ismember(edges, e3, 'rows'), 1)) edges = [edges; e3]; end if isempty(find(ismember(edges, e4, 'rows'), 1)) edges = [edges; e4]; end matgeom-1.2.4/inst/graphs/PaxHeaders/addSquareFace.m0000644000000000000000000000013214576357161017353 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/addSquareFace.m0000644000175000017500000000670114576357161021137 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges, faces] = addSquareFace(nodes, edges, faces, faceNodes) %ADDSQUAREFACE Add a (square) face defined from its vertices to a graph. % % [N2 E2 F2] = addSquareFace(N, E, F, FN) % Add a new face, defined by the nodes indices FN, to the graph defined % by node list N, edge list E, and face list F. % Edges of the face are also added, if they are not already present in % the edge list. % % See also % patchGraph, boundaryGraph % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-28 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE n1 = faceNodes(1,:); n2 = faceNodes(2,:); n3 = faceNodes(3,:); n4 = faceNodes(4,:); % search indices of each nodes ind1 = find(ismember(nodes, n1, 'rows')); ind2 = find(ismember(nodes, n2, 'rows')); ind3 = find(ismember(nodes, n3, 'rows')); ind4 = find(ismember(nodes, n4, 'rows')); % if nodes are not in the list, we add them if isempty(ind1) nodes = [nodes; n1]; ind1 = size(nodes, 1); end if isempty(ind2) nodes = [nodes; n2]; ind2 = size(nodes, 1); end if isempty(ind3) nodes = [nodes; n3]; ind3 = size(nodes, 1); end if isempty(ind4) nodes = [nodes; n4]; ind4 = size(nodes, 1); end % add current face to the list faces(size(faces, 1)+1, 1:4) = [ind1(1) ind2(1) ind3(1) ind4(1)]; % create edges of the face % (first index is the smallest one, by convention) e1 = [min(ind1, ind2) max(ind1, ind2)]; e2 = [min(ind2, ind3) max(ind2, ind3)]; e3 = [min(ind3, ind4) max(ind3, ind4)]; e4 = [min(ind4, ind1) max(ind4, ind1)]; % search edge indices in the list % if nodes are not in the list if isempty(ismember(edges, e1, 'rows')) edges = [edges; e1]; end if isempty(ismember(edges, e2, 'rows')) edges = [edges; e2]; end if isempty(ismember(edges, e3, 'rows')) edges = [edges; e3]; end if isempty(ismember(edges, e4, 'rows')) edges = [edges; e4]; end matgeom-1.2.4/inst/graphs/PaxHeaders/graph2Contours.m0000644000000000000000000000013214576357161017603 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/graph2Contours.m0000644000175000017500000000705214576357161021367 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = graph2Contours(nodes, edges) %#ok %GRAPH2CONTOURS Convert a graph to a set of contour curves. % % CONTOURS = GRAPH2CONTOURS(NODES, EDGES) % NODES, EDGES is a graph representation (type "help graphs" for details) % The algorithm assume every node has degree 2, and the set of edges % forms only closed loops. The result is a list of indices arrays, each % array containing consecutive point indices of a contour. % % To transform contours into drawable curves, please use : % CURVES{i} = NODES(CONTOURS{i}, :); % % % NOTE : contours are not oriented. To manage contour orientation, edges % also need to be oriented. So we must precise generation of edges. % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-08-05 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE curves = {}; c = 0; while size(edges,1)>0 % find first point of the curve n0 = edges(1,1); curve = n0; % second point of the curve n = edges(1,2); e = 1; while true % add current point to the curve curve = [curve n]; %#ok % remove current edge from the list edges = edges((1:size(edges,1))~=e,:); % find index of edge containing reference to current node e = find(edges(:,1)==n | edges(:,2)==n); e = e(1); % get index of next current node % (this is the other node of the current edge) if edges(e,1)==n n = edges(e,2); else n = edges(e,1); end % if node is same as start node, loop is closed, and we stop % node iteration. if n==n0 break; end end % remove the last edge of the curve from edge list. edges = edges((1:size(edges,1))~=e,:); % add the current curve to the list, and start a new curve c = c+1; curves{c} = curve; %#ok end if nargout == 1 varargout = {curves}; end matgeom-1.2.4/inst/graphs/PaxHeaders/grMergeNodeClusters.m0000644000000000000000000000013214576357161020606 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grMergeNodeClusters.m0000644000175000017500000000701514576357161022371 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2] = grMergeNodeClusters(nodes, edges) %GRMERGENODECLUSTERS Merge cluster of connected nodes in a graph. % % grMergeNodeClusters(nodes, edges) % Detects groups of nodes that belongs to the same global node, and % replace them by a unique node. Coordinates of reference node is given % by the median coordinates of cluster nodes. % % This function is intended to be used as filter after a binary image % skeletonization and vectorization. % % % See also % grMergeNodesMedian % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% Initialization % intialize result nodes2 = nodes; edges2 = edges; % compute degree of each node degrees = grNodeDegree(1:size(nodes, 1), edges)'; % find index of multiple nodes indMul = find(degrees > 2); % indices of edges that link several multiple nodes indEdges = sum(ismember(edges, indMul), 2) == 2; % associate a label to each cluster labels = grLabel(nodes, edges(indEdges, :)); clusterLabels = unique(labels(indMul)); %% Replace each cluster by median point % iterate on clusters for i = 1:length(clusterLabels) % indices of nodes of the current cluster inds = find(labels == clusterLabels(i)); % coordinates of new reference node clusterNodes = nodes(inds, :); medianNode = median(clusterNodes, 1); % replace coordinates of reference node refNode = min(inds); nodes2(refNode, :) = medianNode; % replace node indices in edge array edges2(ismember(edges2, inds)) = refNode; end %% Clean up % keep only relevant nodes inds = unique(edges2(:)); nodes2 = nodes2(inds, :); % relabeling of edges for i = 1:length(inds) edges2(edges2 == inds(i)) = i; end % remove double edges edges2 = unique(sort(edges2, 2), 'rows'); % remove 'loops' edges2(edges2(:,1) == edges2(:,2), :) = []; matgeom-1.2.4/inst/graphs/PaxHeaders/drawGraph.m0000644000000000000000000000013214576357161016602 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/drawGraph.m0000644000175000017500000001753214576357161020372 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawGraph(varargin) %DRAWGRAPH Draw a graph, given as a set of vertices and edges. % % drawGraph(NODES, EDGES) % Draws a graph specified by a set of nodes (array N-by-2 or N-by-3, % corresponding to coordinate of each node), and a set of edges (an array % NE-by-2, containing for each edge the first and the second node). % Default drawing is a red circle for nodes and a blue line for edges. % % drawGraph(NODES, EDGES, FACES) % Also draws faces of the graph as patches. % % drawGraph(GRAPH) % Passes argument in a srtucture with at least 2 fields named 'nodes' and % 'edges', and possibly one field 'faces', corresponding to previously % described parameters. % GRAPH can also be a cell array, whose first element is node array, % second element is edges array, and third element, if present, is faces % array. % % % drawGraph(..., SNODES) % drawGraph(..., SNODES, SEDGES) % drawGraph(..., SNODES, SEDGES, SFACES) % Specifies the draw mode for each element, as in the classical 'plot' % function. To not display some elements, uses 'none'. % % % H = drawGraph(...) % Returns handle to the set of edges. % % [HN, HE] = drawGraph(...) % Returns handle to the set of nodes and to the set of edges. % % [HN, HE, HF] = drawGraph(...) % Also returns handle to the set of faces. % % See also % graphs, drawGraphEdges, fillGraphFaces, clipGraph, clipGraphPolygon % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-07-17 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% initialisations % uses empty arrays by default for edges and faces e = []; f = []; % default styles for nodes, edges, and faces % nodes are drawn as red circles sn = {'linestyle', 'none', 'color', 'r', 'marker', 'o'}; % edges are drawn as blue lines se = {'linestyle', '-', 'color', 'b'}; % faces are cyan, their edges are not drawn sf = {'EdgeColor', 'none', 'Facecolor', 'c'}; %% Process input arguments % case of a call without arguments if nargin == 0 help drawGraph; return; end % First extract the graph structure var = varargin{1}; if iscell(var) % graph is stored as a cell array: first cell is nodes, second one is % edges, and third is faces n = var{1}; if length(var)>1 e = var{2}; end if length(var)>2 f = var{3}; end varargin(1) = []; elseif isstruct(var) % graph is stored as a structure, with fields 'nodes', 'edges', and % eventually 'faces'. n = var.nodes; e = var.edges; if isfield(var, 'faces') f = var.faces; end varargin(1) = []; else % graph is stored as set of variables: nodes, edges, and eventually % faces n = varargin{1}; e = varargin{2}; varargin(1:2) = []; if ~isempty(varargin) var = varargin{1}; if isnumeric(var) % faces are stored in a numeric array of indices f = var; varargin(1) = []; elseif iscell(var) if ~ischar(var{1}) % faces are stored in a cell array, each cell containing a % row vector of indices f = var; varargin(1) = []; end end end end % extract drawing style if ~isempty(varargin) sn = concatArguments(sn, varargin{1}); end if length(varargin)>1 se = concatArguments(se, varargin{2}); end if length(varargin)>2 sf = concatArguments(sf, varargin{3}); end %% Main drawing processing hold on; if size(n, 2) == 2 % Draw a 2 dimensional graph % Draw faces of the graph if ~strcmp(sf{1}, 'none') && ~isempty(f) if iscell(f) % each face is contained in a cell. hf = zeros(size(f)); for fi = 1:length(f) hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:}); end else % process faces as an Nf*N array. Nf is the number of faces, % and all faces have the same number of vertices (nodes). hf = patch('Faces', f, 'Vertices', n, sf{:}); end end % Draw 2D Edges if ~strcmp(se{1}, 'none') && size(e, 1) > 0 he = plot([n(e(:,1),1) n(e(:,2),1)]', [n(e(:,1),2) n(e(:,2),2)]', se{:}); end % Draw 2D nodes if ~strcmp(sn{1}, 'none') hn = plot(n(:,1), n(:,2), sn{:}); end elseif size(n, 2)==3 % Draw a 3 dimensional graph % use a zbuffer to avoid display pbms. set(gcf, 'renderer', 'zbuffer'); % Draw 3D Faces if ~strcmp(sf{1}, 'none') if iscell(f) % each face is contained in a cell. hf = zeros(size(f)); for fi = 1:length(f) hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:}); end else % process faces as an Nf*N array. Nf i the number of faces, % and all faces have the same number of vertices (nodes). hf = patch('Faces', f, 'Vertices', n, sf{:}); end end % Draw 3D edges if ~strcmp(se{1}, 'none') && size(e, 1) > 0 he = line(... [n(e(:,1),1) n(e(:,2),1)]', ... [n(e(:,1),2) n(e(:,2),2)]', ... [n(e(:,1),3) n(e(:,2),3)]', ... se{:}); end % Draw 3D nodes if ~strcmp(sn{1}, 'none') hn = plot3(n(:,1), n(:,2), n(:,3), sn{:}); end end %% Format output arguments % return handle to edges if nargout==1 varargout{1} = he; end % return handle to nodes and edges if nargout==2 varargout{1} = hn; varargout{2} = he; end % return handle to nodes, edges and faces if nargout==3 varargout{1} = hn; varargout{2} = he; varargout{3} = hf; end end function res = concatArguments(in1, in2) % in1 is a cell array already initialized % in2 is an argument that can be: % - empty % - the string 'none' % - another cell array if isempty(in2) res = in1; return; end if ischar(in2) if strcmp('none', in2) res = {'none'}; return; end end if iscell(in1) res = [in1(:)' in2(:)']; else res = [{in1} in2(:)]; end end matgeom-1.2.4/inst/graphs/PaxHeaders/grShortestPath.m0000644000000000000000000000013214576357161017644 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grShortestPath.m0000644000175000017500000001547214576357161021435 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodePath, edgePath] = grShortestPath(nodes, edges, ind0, ind1, edgeWeights) %GRSHORTESTPATH Find a shortest path between two nodes in the graph. % % PATH = grShortestPath(NODES, EDGES, NODE1, NODE2, WEIGHTS) % NODES and EDGES defines the graph, NODE1 and NODE2 are indices of the % node extremities, and WEIGHTS is the set of weights associated to each % edge. % The function returns a set of node indices. % % PATH = grShortestPath(NODES, EDGES, NODEINDS, WEIGHTS) % Specifies two or more points that must be traversed by the path, in the % specified order. % % % Create a simple tree graph, and compute shortest path % [x y] = meshgrid([10 20 30], [10 20 30]); % nodes = [x(:) y(:)]; % edges = [1 2;2 3;2 5;3 6; 4 5;4 7;5 8; 8 9]; % drawGraph(nodes, edges) % axis equal; axis([0 40 0 40]); % drawNodeLabels(nodes, 1:9) % path = grShortestPath(nodes, edges, 1, 9); % % same as: % path = grShortestPath(nodes, edges, [1 9]); % % See also % graphs, grFindMaximalLengthPath % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % process the case where several node indices are specified in first arg. if length(ind0) > 1 % following optional argument is edge values if exist('ind1', 'var') edgeWeights = ind1; else edgeWeights = ones(size(edges, 1), 1); end % concatenate path pieces nodePath = ind0(1); edgePath = size(0, 2); for i = 2:length(ind0) [node0, edge0] = grShortestPath(nodes, edges, ind0(i-1), ind0(i), edgeWeights); nodePath = [nodePath ; node0(2:end)]; %#ok edgePath = [edgePath ; edge0]; %#ok end return; end % ensure weights are defined if ~exist('edgeWeights', 'var') edgeWeights = ones(size(edges, 1), 1); end % check indices limits nNodes = size(nodes, 1); if max(ind0) > nNodes error('Start index exceed number of nodes in the graph'); end if max(ind1) > nNodes error('End index exceed number of nodes in the graph'); end %% Initialisations % consider infinite distance for all nodes dists = inf * ones(nNodes, 1); % initial node is at distance 0 by definition dists(ind0) = 0; % create an array of indices for the predessor of each node preds = zeros(nNodes, 1); preds(ind0) = 0; % allocate memory to store the subgraph, which is a tree edges2 = zeros(nNodes-1, 2); % create an array of node flags unprocessedNodeInds = 1:nNodes; edgeCount = 0; %% Iterate until all nodes are flagged to 1 while ~isempty(unprocessedNodeInds) % choose unprocessed node with lowest distance [tmp, ind] = min(dists(unprocessedNodeInds)); %#ok ind = unprocessedNodeInds(ind); ind = ind(1); % mark current node as processed unprocessedNodeInds(unprocessedNodeInds == ind) = []; % if the current node is the target, it is not necessary to continue... if ind == ind1 break; end % find the index list of edges incident to current node adjEdgeInds = grAdjacentEdges(edges, ind); % select edges whose opposite node has not yet been processed inds2 = sum(ismember(edges(adjEdgeInds, :), unprocessedNodeInds), 2) > 0; adjEdgeInds = adjEdgeInds(inds2); % iterate over incident edges to update adjacent nodes for iNeigh = 1:length(adjEdgeInds) % extract index of current adjacent node edge = edges(adjEdgeInds(iNeigh), :); adjNodeInd = edge(~ismember(edge, ind)); newDist = dists(ind) + edgeWeights(adjEdgeInds(iNeigh)); % dists(adjNodeInd) = min(dists(adjNodeInd), newDist); if newDist < dists(adjNodeInd) dists(adjNodeInd) = newDist; preds(adjNodeInd) = ind; end end % find the list of adjacent nodes adjNodeInds = unique(edges(adjEdgeInds, :)); adjNodeInds(adjNodeInds == ind) = []; % choose the adjacent nodes with lowest distance, and add the % corresponding edges to the subgraph if ~isempty(adjNodeInds) minDist = min(dists(adjNodeInds)); closestNodeInds = adjNodeInds(dists(adjNodeInds) <= minDist); for iCloseNode = 1:length(closestNodeInds) edgeCount = edgeCount + 1; edges2(edgeCount, :) = [ind closestNodeInds(iCloseNode)]; end end end %% Path creation % create the path: start from end index, and identify successive set of % neighbor edges and nodes nodeInd = ind1; nodePath = nodeInd; edgePath = []; % find predecessors until we reach ind0 node while nodeInd ~= ind0 newNodeInd = preds(nodeInd); nodePath = [nodePath ; newNodeInd]; %#ok % search the edge (both directions) in the list of edges e_tmp = [nodeInd newNodeInd]; [~,edgeInd] = ismember ([e_tmp; e_tmp(end:-1:1)], edges, 'rows'); edgeInd(edgeInd == 0) = []; % erase the one that isn't there edgePath = [edgePath ; edgeInd]; %#ok nodeInd = newNodeInd; end % reverse the path nodePath = nodePath(end:-1:1); edgePath = edgePath(end:-1:1); matgeom-1.2.4/inst/graphs/PaxHeaders/centroidalVoronoi2d_MC.m0000644000000000000000000000013214576357161021170 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/centroidalVoronoi2d_MC.m0000644000175000017500000001770214576357161022757 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [germs, germPaths] = centroidalVoronoi2d_MC(germs, poly, varargin) %CENTROIDALVORONOI2D_MC Centroidal Voronoi tesselation by Monte-Carlo. % % PTS = centroidalVoronoi2d_MC(NPTS, POLY) % Generate points in a polygon based on centroidal voronoi tesselation. % Centroidal germs can be computed by using the Llyod's algorithm: % 1) initial germs are chosen at random within polygon % 2) voronoi polygon of the germs is computed % 3) the centroids of each domain are computed, and used as germs of the % next iteration % % This version uses a Monte-Carlo version of Llyod's algorithm. The % centroids are not computed explicitly, but approximated by sampling N % points within the bounding polygon. % % [PTS, PATHLIST] = centroidalVoronoi2d_MC(NPTS, POLY) % Also returns the path of each germs at each iteration. The result % PATHLIST is a cell array with as many cells as the number of germs, % containing in each cell the successive positions of the germ. % % PTS = centroidalVoronoi2d_MC(.., PARAM, VALUE) % Specify one or several optional arguments. PARAM can be one of: % * 'nIter' specifies the number of iterations of the algorithm % (default is 50) % * 'nPoints' number of points for updating positions of germs at each % iteration. Default is 200 times the number of germs. % * 'verbose' display iteration number. Default is false. % % Example % poly = ellipseToPolygon([50 50 40 30 20], 200); % nGerms = 100; % germs = centroidalVoronoi2d(nGerms, poly); % figure; hold on; % drawPolygon(poly, 'k'); % drawPoint(germs, 'bo'); % axis equal; axis([0 100 10 90]); % % extract regions of the CVD % box = polygonBounds(poly); % [n, e] = boundedVoronoi2d(box, germs); % [n2, e2] = clipGraphPolygon(n, e, poly); % drawGraphEdges(n2, e2, 'b'); % % See also % graphs, boundedVoronoi2d, centroidalVoronoi2d % % Rewritten from programs found in % http://people.scs.fsu.edu/~burkardt/m_src/cvt/cvt.html % % Reference: % Qiang Du, Vance Faber, and Max Gunzburger, % Centroidal Voronoi Tessellations: Applications and Algorithms, % SIAM Review, Volume 41, 1999, pages 637-676. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-23, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform %% Parse input arguments % number of germs if isscalar(germs) nGerms = germs; germs = []; else nGerms = size(germs, 1); end % random point generator % Should be either empty (-> use random generator) or be an instance of % quasi-random sequence generator sucha as haltonset or sobolset. generator = []; % Number of points nPts = 200 * nGerms; % Number of iterations nIter = 50; verbose = false; keepPaths = nargout > 1; while length(varargin) > 1 paramName = varargin{1}; switch lower(paramName) case 'verbose' verbose = varargin{2}; case 'niter' nIter = varargin{2}; case 'npoints' nPts = varargin{2}; case 'generator' generator = varargin{2}; % ensure generator is a stream if isa(generator, 'qrandset') generator = qrandstream(generator); elseif isa(generator, 'qrandstream') % ok, nothing to do... else error('quasi-random generator is not properly specified'); end otherwise error(['Unknown parameter name: ' paramName]); end varargin(1:2) = []; end %% Initialisations % bounding box of polygon box = polygonBounds(poly); % init germs if needed if isempty(germs) if isempty(generator) germs = generatePointsInPoly(nGerms); else germs = generateQRandPointsInPoly(nGerms); end end germIters = cell(nIter, 1); %% Iteration of the Lloyd algorithm for i = 1:nIter if verbose disp(sprintf('Iteration: %d/%d', i, nIter)); %#ok end if keepPaths germIters{i} = germs; end % random uniform points in polygon if verbose disp(' generate points'); end if isempty(generator) points = generatePointsInPoly(nPts); else points = generateQRandPointsInPoly(nPts); end % for each point, determines index of the closest germ if verbose disp(' find closest germ'); end ind = zeros(nPts, 1); for iPoint = 1:nPts x0 = points(iPoint, 1); y0 = points(iPoint, 2); [tmp, ind(iPoint)] = min((germs(:,1)-x0).^2 + (germs(:,2)-y0).^2); %#ok end % update the position of each germ if verbose disp(' update germ position'); end for iGerm = 1:nGerms germs(iGerm,:) = centroid(points(ind == iGerm, :)); end end %% Evenutally compute germs trajectories if nargout > 1 % init germPaths = cell(nGerms, 1); path = zeros(nIter+1, 2); % Iteration on germs for i = 1:nGerms % create path corresponding to germ for j = 1:nIter pts = germIters{j}; path(j,:) = pts(i,:); end path(nIter+1, :) = germs(i,:); germPaths{i} = path; end end function pts = generatePointsInPoly(nPts) % extreme coordinates xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % compute size of box dx = xmax - xmin; dy = ymax - ymin; % allocate memory for result pts = zeros(nPts, 2); % iterate until all points have been sampled within the polygon ind = (1:nPts)'; while ~isempty(ind) NI = length(ind); x = rand(NI, 1) * dx + xmin; y = rand(NI, 1) * dy + ymin; pts(ind, :) = [x y]; ind = ind(~polygonContains(poly, pts(ind, :))); end end function pts = generateQRandPointsInPoly(nPts) % extreme coordinates xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); % compute size of box dx = xmax - xmin; dy = ymax - ymin; % allocate memory for result pts = zeros(nPts, 2); % iterate until all points have been sampled within the polygon ind = (1:nPts)'; while ~isempty(ind) NI = length(ind); pts0 = qrand(generator, NI); x = pts0(:, 1) * dx + xmin; y = pts0(:, 2) * dy + ymin; pts(ind, :) = [x y]; ind = ind(~polygonContains(poly, pts(ind, :))); end end end matgeom-1.2.4/inst/graphs/PaxHeaders/grRemoveNodes.m0000644000000000000000000000013214576357161017442 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grRemoveNodes.m0000644000175000017500000000631414576357161021226 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2] = grRemoveNodes(nodes, edges, rmNodes) %GRREMOVENODES Remove several nodes in a graph. % % usage: % [NODES2 EDGES2] = grRemoveNodes(NODES, EDGES, NODES2REMOVE) % remove the nodes with indices NODE2REMOVE from array NODES, and also % remove edges containing the nodes NODE2REMOVE. % % Example % nodes = [... % 10 10; 20 10; 30 10; ... % 10 20; 20 20; 30 20]; % edges = [... % 1 2; 1 4; 1 5; ... % 2 3; 2 5; 2 6; ... % 3 6; 4 5; 5 6]; % toRemove = [3 4]; % [nodes2 edges2] = grRemoveNodes(nodes, edges, toRemove); % drawGraph(nodes2, edges2); % axis equal; axis([0 40 0 30]); % % See also % grRemoveEdges % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE %% edges processing % remove all edges connected to one of the nodes to remove edges2 = edges(~any(ismember(edges, rmNodes), 2), :); % change edges information, due to the node index shift for i = 1:length(rmNodes) inds = edges2 > (rmNodes(i) - i + 1); edges2(inds) = edges2(inds) - 1; end %% nodes processing % number of nodes N = size(nodes, 1); NR = length(rmNodes); N2 = N-NR; % allocate memory nodes2 = zeros(N2, 2); % process the first node nodes2(1:rmNodes(1)-1,:) = nodes(1:rmNodes(1)-1,:); for i = 2:NR inds = rmNodes(i-1)+1:rmNodes(i)-1; if isempty(inds) continue; end nodes2(inds - i + 1, :) = nodes(inds, :); end % process the last node nodes2(rmNodes(NR)-NR+1:N2, :) = nodes(rmNodes(NR)+1:N, :); matgeom-1.2.4/inst/graphs/PaxHeaders/cvtUpdate.m0000644000000000000000000000013214576357161016622 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/cvtUpdate.m0000644000175000017500000000653514576357161020413 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = cvtUpdate(germs, points) %CVTUPDATE Update germs of a CVT with given points. % % G2 = cvtUpdate(G, PTS) % G: inital germs % PTS: the points % % Example % G = randPointDiscUnif(50); % P = randPointDiscUnif(10000); % G2 = cvtUpdate(G, P); % % See also % % % Rewritten from programs found in % http://people.scs.fsu.edu/~burkardt/m_src/cvt/cvt.html % % Reference: % Qiang Du, Vance Faber, and Max Gunzburger, % Centroidal Voronoi Tessellations: Applications and Algorithms, % SIAM Review, Volume 41, 1999, pages 637-676. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-10-10, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas %% Init % number of germs and of points Ng = size(germs, 1); N = size(points, 1); % initialize centroids with values of germs centroids = germs; % number of updates of each centroid count = ones(Ng, 1); %% Generate random points % for each point, determines which germ is the closest ones [dist, ind] = minDistancePoints(points, germs); %#ok h = zeros(Ng, 1); for i = 1:Ng h(i) = sum(ind==i); end %% Centroids update % add coordinate of each point to closest centroid energy = 0; for j = 1:N centroids(ind(j), :) = centroids(ind(j), :) + points(j, :); energy = energy + sum ( ( centroids(ind(j), :) - points(j, :) ).^2); count(ind(j)) = count(ind(j)) + 1; end % estimate coordinate by dividing by number of counts centroids = centroids ./ repmat(count, 1, size(germs, 2)); % normalizes energy by number of sample points energy = energy / N; %% Format output varargout{1} = centroids; if nargout > 1 varargout{2} = energy; end matgeom-1.2.4/inst/graphs/PaxHeaders/grMergeMultipleNodes.m0000644000000000000000000000013214576357161020760 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grMergeMultipleNodes.m0000644000175000017500000001000114576357161022530 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grMergeMultipleNodes(varargin) %GRMERGEMULTIPLENODES Simplify a graph by merging multiple nodes. % % OUTPUT = grMergeMultipleNodes(INPUT); % simplify the graph INPUT, and return the result in the graph OUTPUT. % format for input can be one of % nodes, edges % % Two steps in the procedure : % * first remove multiple nodes. find all nodes with same coords, and % keep only one % * remove edges that link same nodes % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-08-09 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE %% process input arguments n = []; e = []; f = []; % extract data of the graph var = varargin{1}; if iscell(var) % graph is stored as a cell array : first cell is nodes, second one is % edges, and third is faces n = var{1}; if length(var)>1 e = var{2}; end if length(var)>2 f = var{3}; end elseif isstruct(var) % graph is stored as a structure, with fields 'nodes', 'edges', and % eventually 'faces'. n = var.nodes; e = var.edges; if isfield(var, 'faces') f = var.faces; end elseif length(varargin)>1 % graph is stored as set of variables : nodes, edges, and eventually % faces n = varargin{1}; e = varargin{2}; if length(varargin)==3 f = varargin{3}; end end %% Main processing % simplify graph to remove multiple nodes, and adapt edges and faces % indices % simplify nodes [n, i, j] = unique(n, 'rows'); %#ok % change edges indices and remove double edges (undirected graph) for i = 1:length(e(:)) e(i) = j(e(i)); %#ok end e = unique(sort(e, 2), 'rows'); % change faces indices if iscell(f) % faces stored as cell array (irregular mesh) for k = 1:length(f) face = f{k}; for i = 1:length(face(:)) face(i) = j(face(i)); end f{k} = face; %#ok end else % faces indices stored as regular array (square or triangle mesh). for i = 1:length(f(:)) f(i) = j(f(i)); %#ok end end %% process output depending on how many arguments are needed if nargout == 1 out{1} = n; out{2} = e; varargout{1} = out; end if nargout == 2 varargout{1} = n; varargout{2} = e; end if nargout == 3 varargout{1} = n; varargout{2} = e; varargout{3} = f; end matgeom-1.2.4/inst/graphs/PaxHeaders/clipGraphPolygon.m0000644000000000000000000000013214576357161020144 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/clipGraphPolygon.m0000644000175000017500000001217014576357161021725 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2] = clipGraphPolygon(nodes, edges, poly) %CLIPGRAPHPOLYGON Clip a graph with a polygon. % % [NODES2, EDGES2] = clipGraphPolygon(NODES, EDGES, POLY) % Clips the graph defined by nodes NODES and edges EDGES with the polygon % given in POLY. POLY is a N-by-2 array of vertices. % The result is a new graph containing nodes inside the polygon, as well % as nodes created by the intersection of edges with the polygon. % % Example % elli = [50 50 40 20 30]; % figure; hold on; % drawEllipse(elli, 'k'); % poly = ellipseToPolygon(elli, 200); % box = polygonBounds(poly); % germs = randomPointInPolygon(poly, 100); % drawPoint(germs, 'b.'); % [n, e, f] = boundedVoronoi2d(box, germs); % [n2, e2] = clipGraphPolygon(n, e, poly); % drawGraphEdges(n2, e2); % % See also % graphs, drawGraph, clipGraph % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2012-02-24, using Matlab 7.9.0.529 (R2009b) % Copyright 2012-2023 INRA - Cepia Software Platform % Algorithm summary: % * For each edge not outside do: % * clip edge with poly % * if no inter % * add current edge (same vertex indices) % * continue % * end % * add intersections to list, compute their indices % * create the new edge(s) %% Clip the nodes % find index of nodes inside clipping window nodeInside = isPointInPolygon(nodes, poly); innerNodeInds = find(nodeInside); % create correspondance between original nodes and inside nodes nodeIndsMap = zeros(size(nodes, 1), 1); for i = 1:length(innerNodeInds) nodeIndsMap(innerNodeInds(i)) = i; end % select clipped nodes nodes2 = nodes(innerNodeInds, :); %% Clip the edges insideEnds = nodeInside(edges); % allocate memory for edges with at least one vertex inside nEdges2 = sum(sum(insideEnds, 2) ~= 0); % allocate memory for at least edges inside edges2 = zeros(nEdges2, 2); nEdges = size(edges, 1); % index of next edge iEdge2 = 1; % index of next vertex iNode2 = size(nodes2, 1) + 1; % iterate over all edges for iEdge = 1:nEdges % index of edge vertices v1 = edges(iEdge, 1); v2 = edges(iEdge, 2); % compute intersection(s) of current edge with boundary edge0 = [nodes(v1,:) nodes(v2,:)]; intersects = intersectEdgePolygon(edge0, poly); % process edges that do not cross polygon boundary if isempty(intersects) if nodeInside(v1) && nodeInside(v2) % current edge is totally inside the clipping polygon edges2(iEdge2,:) = nodeIndsMap([v1 v2]); iEdge2 = iEdge2 + 1; end continue; end % add intersection(s) to the vertex array nInters = size(intersects, 1); intersectInds = iNode2:iNode2+nInters-1; nodes2(intersectInds,:) = intersects; iNode2 = iNode2 + nInters; % concatenate vertex indices with indices of extremities inside poly if nodeInside(v1) intersectInds = [nodeIndsMap(v1) intersectInds]; %#ok end if nodeInside(v2) intersectInds = [intersectInds nodeIndsMap(v2)]; %#ok end % create new edge for each couple of contiguous intersection while length(intersectInds) > 1 edges2(iEdge2, :) = intersectInds(1:2); intersectInds(1:2) = []; iEdge2 = iEdge2 + 1; end if ~isempty(intersectInds) warning('matGeom:graphs:AlgorithmicError', ... 'edge %d has odd number of intersects', iEdge); end end matgeom-1.2.4/inst/graphs/PaxHeaders/grFindGeodesicPath.m0000644000000000000000000000013214576357161020354 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grFindGeodesicPath.m0000644000175000017500000000676614576357161022153 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function path = grFindGeodesicPath(nodes, edges, ind0, ind1, edgeWeights) %GRFINDGEODESICPATH Find a geodesic path between two nodes in the graph. % % PATH = grFindGeodesicPath(NODES, EDGES, NODE1, NODE2, WEIGHTS) % NODES and EDGES defines the graph, NODE1 and NODE2 are indices of the % node extremities, and WEIGHTS is the set of weights associated to each % edge. % The function returns a set of edge indices. % % % See also % grFindMaximalLengthPath % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % ensure weights are defined if ~exist('edgeWeights', 'var') edgeWeights = ones(size(edges, 1), 1); end % check indices limits nNodes = size(nodes, 1); if max(ind0) > nNodes error('Start index exceed number of nodes in the graph'); end if max(ind1) > nNodes error('End index exceed number of nodes in the graph'); end % find a vertex opposite to the first extremity dists = grPropagateDistance(nodes, edges, ind0, edgeWeights); % iterate on neighbors of current node: choose next neighbor with smallest % cumulated weight, until we are back on source node path = []; while true % find neighbor with lowest cumulated distance neighs = grAdjacentNodes(edges, ind1); neighDists = dists(neighs); indN = find(neighDists == min(neighDists), 1); ind2 = neighs(indN); if isempty(ind2) warning('graphs:grFindGeodesicPath', ... 'No neighbor node found for node %d, graph may be not connected', ind1); break; end % add edge index to the path indE = find(sum(ismember(edges, [ind1 ind2]), 2) == 2, 1); path = [path indE]; %#ok % test if path is finished or not if ind2 == ind0 break; end ind1 = ind2; end % reverse path direction path = path(end:-1:1); matgeom-1.2.4/inst/graphs/PaxHeaders/grMedian.m0000644000000000000000000000013214576357161016411 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grMedian.m0000644000175000017500000000471114576357161020174 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grMedian(varargin) %GRMEDIAN Compute median value from neighbour nodes. % % VALS2 = grMedian(EDGES, VALS) % new value for each node of the graph is computed as the median of the % values of neighbours and of old value. % % Example % grMedian % % See also % grMean, grDilate, grErode % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin) == 2 edges = varargin{1}; values = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; values = varargin{3}; else error('Wrong number of arguments in "grMedian"'); end res = zeros(size(values)); uni = unique(edges(:)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); res(uni(n)) = median(values([uni(n); neigh])); end varargout{1} = res; matgeom-1.2.4/inst/graphs/PaxHeaders/grMergeNodesMedian.m0000644000000000000000000000013214576357161020362 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grMergeNodesMedian.m0000644000175000017500000000620714576357161022147 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2] = grMergeNodesMedian(nodes, edges, mnodes) %GRMERGENODESMEDIAN Replace several nodes by their median coordinate. % % [NODES2, EDGES2] = grMergeNodesMedian(NODES, EDGES, NODES2MERGE) % NODES ans EDGES are the graph structure, and NODES2MERGE is the list of % indices of nodes to be merged. % The median coordinate of merged nodes is computed, and all nodes are % merged to this new node. % % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % coordinates of reference node x = median(nodes(mnodes, 1)); y = median(nodes(mnodes, 2)); % index of reference node refNode = findPoint([x y], nodes); mnodes = sort(mnodes(mnodes ~= refNode)); for n = 1:length(mnodes) node = mnodes(n); % process each neighbor of the current node neighbors = grAdjacentNodes(edges, node); for e = 1:length(neighbors) edge = neighbors(e); if edges(edge, 1) == refNode || edges(edge, 2) == refNode continue; end % find if the node is referenced as 1 or 2 in the edge, % and replace it with the reference node. if edges(edge, 1) == node edges(edge, 1) = refNode; else edges(edge, 2) = refNode; end end end % remove nodes from the list, except the reference node. for n = 1:length(mnodes) [nodes, edges] = grRemoveNode(nodes, edges, mnodes(n)-n+1); end nodes2 = nodes; edges2 = edges; matgeom-1.2.4/inst/graphs/PaxHeaders/adjacencyListToEdges.m0000644000000000000000000000013214576357161020713 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/adjacencyListToEdges.m0000644000175000017500000000543714576357161022504 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function edges = adjacencyListToEdges(adjList) %ADJACENCYLISTTOEDGES Convert an adjacency list to an edge array. % % EDGES = adjacencyListToEdges(ADJ) % Converts the adjacency list ADJ, given as a cell array of adjacent % indices, to an edge array. % % Example % % create adjacency list for a simple graph % adj = {[2 3], [1 4 5], [1 4], [2 3 5], [2 4]}; % edges = adjacencyListToEdges(adj) % edges = % 1 2 % 1 3 % 2 4 % 2 5 % 3 4 % 4 5 % % See also % graphs, polygonSkeletonGraph % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2020-06-02, using Matlab 9.8.0.1323502 (R2020a) % Copyright 2020-2023 INRAE - BIA Research Unit - BIBS Platform (Nantes) % count total number of edges ne = 0; for iVertex = 1:length(adjList) ne = ne + length(adjList{iVertex}); end % allocate memory edges = zeros([ne 2]); % create edges by iterating on vertices ie = 0; for iVertex = 1:length(adjList) neighs = adjList{iVertex}; for iNeigh = 1:length(neighs) edge = sort([iVertex neighs(iNeigh)]); ie = ie + 1; edges(ie,:) = edge; end end % sort edges edges = unique(edges, 'rows'); matgeom-1.2.4/inst/graphs/PaxHeaders/drawEdgeLabels.m0000644000000000000000000000013214576357161017530 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/drawEdgeLabels.m0000644000175000017500000000575314576357161021322 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawEdgeLabels(p, e, value) %DRAWEDGELABELS Draw values associated to graph edges. % % usage: % drawEdgeLabels(NODES, EDGES, VALUES); % NODES: array of double, containing x and y values of nodes % EDGES: array of int, containing indices of in and out nodes % VALUES is an array the same length of EDGES, containing values % associated to each edges of the graph. % % The function computes the center of each edge, and puts the text with % associated value. % % H = drawEdgeLabels(...) return array of handles to each text structure, % making possible to change font, color, size % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-02-10 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE if length(p) > 1 && length(e) > 1 h = zeros(length(e), 1); hold on; for l=1:length(e) % indices of source and target nodes n1 = e(l, 1); n2 = e(l, 2); % node coordinates x1 = p(n1, 1); y1 = p(n1, 2); x2 = p(n2, 1); y2 = p(n2, 2); % display the edge line([x1 x2], [y1 y2]); % coordinates of edge label xm = (x1 + x2)/2; ym = (y1 + y2)/2; % display label h(l) = text(xm, ym, sprintf('%3d', floor(value(l)))); end end if nargout == 1 varargout = {h}; end matgeom-1.2.4/inst/graphs/PaxHeaders/grNodeInnerDegree.m0000644000000000000000000000013214576357161020211 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grNodeInnerDegree.m0000644000175000017500000000454314576357161021777 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function degree = grNodeInnerDegree(node, edges) %GRNODEINNERDEGREE Inner degree of a node in a graph. % % DEG = grNodeInnerDegree(NODE, EDGES); % Returns the inner degree of a node in the given edge list, i.e. the % number of edges arriving to it. % NODE is the index of the node, and EDGES is a liste of couples of % indices (origin and destination node). % % Note: Also works when node is a vector of indices % % See also % grNodeDegree, grNodeOuterDegree % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-17 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % allocate memory N = size(node, 1); degree = zeros(N, 1); % compute inner degree of each vertex for i=1:length(node) degree(i) = sum(edges(:,2)==node(i)); end matgeom-1.2.4/inst/graphs/PaxHeaders/grSimplifyBranches.m0000644000000000000000000000013214576357161020456 xustar0030 mtime=1710874225.170193314 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grSimplifyBranches.m0000644000175000017500000001343614576357161022245 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grSimplifyBranches(nodes, edges) %GRSIMPLIFYBRANCHES Replace branches of a graph by single edges. % % [NODES2 EDGES2] = grSimplifyBranches(NODES, EDGES) % renvoie une version simplifiee d'un graphe, en ne gardant que les % points multiples et les aretes reliant les points multiples. % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE Mnodes = []; % size Nn*2 -> nodes coordinates Sedges = []; % size Ne*2 -> indices of nodes Mpoints = []; % size Nn*1 -> indices of Multiple points % in nodes input array branch = []; % size Nb*2 (variable) Nn = 0; Ne = 0; Nb = 0; % look for the first multiple point p = 1; while length(find(edges(:,1) == p | edges(:,2) == p)) < 3 p = p + 1; end Mpoints(1) = p; Mnodes(1, 1:2) = nodes(p, 1:2); Nn = Nn + 1; % add the branches of the first multiple point neighbours = find(edges(:,1)==p | edges(:,2)==p); for b = 1:length(neighbours) Nb = Nb+1; edge = edges(neighbours(b),:); if edge(1) == p branch(Nb, 1:2) = [p edge(2)]; %#ok else branch(Nb, 1:2) = [p edge(1)]; %#ok end end % process each branch, until there is no more branch to process. % b is index of current branch b = 0; while b < length(branch) b = b+1; % check if the branch is valid if branch(b, 1) == 0 continue; end % initialize iteration pNode = branch(b, 1); node = branch(b,2); neighbours = find(edges(:,1) == node | edges(:,2) == node); % disp(sprintf('node %3d (%03d ; %03d) -> %3d (%03d ; %03d)', ... % Mnode, nodes(Mnode, 1), nodes(Mnode, 2), ... % node, nodes(node, 1), nodes(node, 2))); while length(neighbours) < 3 % look for the next point on the current branch next = 0; for n = 1:length(neighbours) edge = edges(neighbours(n), :); if edge(1)~= node && edge(1)~= pNode next = edge(1); break; end if edge(2)~= node && edge(2)~= pNode next = edge(2); break; end end pNode = node; node = next; neighbours = find(edges(:,1) == node | edges(:,2) == node); end % node is now the next multiple point, and pNode contains the last % point of the branch. % check if the multiple point has already been processed index = find(Mpoints==node); if ~isempty(index) % find the branch starting with node, and with pNode has % second point, and set it to [0 0] to avoid it to be % processed again %disp('remove branch'); for b2 = 1:Nb if branch(b2, 1) == node && branch(b2, 2) == pNode %disp('find branch'); branch(b2, 1:2) = 0; %#ok break; end end else % add the multiple point to the list of points %disp('add point'); Nn = Nn+1; Mnodes(Nn, 1:2) = nodes(node, 1:2); %#ok index = Nn; Mpoints(Nn) = node; %#ok % add each neighbour of the new multiple point (but not % the neighbour containing pNode) to the list of branches for n = 1:length(neighbours) edge = edges(neighbours(n), :); if edge(1) ~= pNode && edge(2) ~= pNode %disp('add a branch'); Nb = Nb + 1; if edge(1) == node branch(Nb, 1:2) = [node edge(2)]; %#ok else branch(Nb, 1:2) = [node edge(1)]; %#ok end end end end %disp('add new Edge'); Ne = Ne + 1; Sedges(Ne, 1:2) = [find(Mpoints == branch(b,1)), index]; %#ok end % process output depending on how many arguments are needed if nargout == 1 out{1} = Mnodes; out{2} = Sedges; varargout{1} = out; end if nargout == 2 varargout{1} = Mnodes; varargout{2} = Sedges; end return; matgeom-1.2.4/inst/graphs/PaxHeaders/drawNodeLabels.m0000644000000000000000000000013114576357161017550 xustar0029 mtime=1710874225.17419331 30 atime=1710874225.170193314 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/drawNodeLabels.m0000644000175000017500000000611414576357161021333 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawNodeLabels(nodes, value, varargin) %DRAWNODELABELS Draw values associated to graph nodes. % % Usage: % drawNodeLabels(NODES, VALUES); % NODES: array of double, containing x and y values of nodes % VALUES is an array the same length of EDGES, containing values % associated to each edges of the graph. % % H = drawNodeLabels(...) % Returns array of handles to each text structure, making it possible to % change font, color, size % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-02-10 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE % extract handle of axis to draw on if isAxisHandle(nodes) ax = nodes; nodes = value; value = varargin{1}; else ax = gca; end % number and dimension of nodes Nn = size(nodes, 1); Nd = size(nodes, 2); % check input size if length(value) ~= Nn error('Value array must have same length as node number'); end % allocate memory h = zeros(Nn, 1); axes(ax); if Nd == 2 % Draw labels of 2D nodes for i = 1:Nn x = nodes(i, 1); y = nodes(i, 2); h(i) = text(x, y, sprintf('%3d', floor(value(i)))); end elseif Nd == 3 % Draw labels of 3D nodes for i = 1:Nn x = nodes(i, 1); y = nodes(i, 2); z = nodes(i, 3); h(i) = text(x, y, z, sprintf('%3d', floor(value(i)))); end else error('Node dimension must be 2 or 3'); end if nargout == 1 varargout = {h}; end matgeom-1.2.4/inst/graphs/PaxHeaders/readGraph.m0000644000000000000000000000013014576357161016556 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/readGraph.m0000644000175000017500000000747614576357161020356 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes, edges] = readGraph(fileName) %READGRAPH Read a graph from a text file. % % [NODES EDGES] = readGraph(FILENAME) % % Example % % create a basic graph, save it to a file, and read it again % nodes = [10 10;20 10;10 20;20 20;27 15]; % edges = [1 2;1 3;2 4;2 5;3 4;4 5]; % writeGraph(nodes, edges, 'simpleGraph.txt'); % [n2 e2] = readGraph('simpleGraph.txt'); % figure; drawGraph(n2, e2); axis equal; axis([0 40 0 30]); % % See also % writeGraph % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2014-01-21, using Matlab 7.9.0.529 (R2009b) % Copyright 2014-2023 INRA - Cepia Software Platform %% Open file and read header % open file for reading in text mode f = fopen(fileName, 'rt'); if f == -1 error(['could not open file for reading: ' fileName]); end % check header line = fgetl(f); if ~ischar(line) error(['can not read graph from empty file: ' fileName]); end if ~strcmpi(strtrim(line(2:end)), 'graph') error(['Wrong header line in file:' fileName]); end %% read node section % check sub-header line = fgetl(f); if ~strcmpi(strtrim(line(2:end)), 'nodes') error(['Could not interpret node section in file:' fileName]); end % read the number of nodes line = fgetl(f); [nNodesStr, line] = strtok(line); nNodes = str2double(nNodesStr); % read number of dimension, assumes 2 by default if not specified nDims = 2; if ~isempty(line) nDims = str2double(strtok(line)); end % read node coordinates [nodes, nRead] = fscanf(f, '%g', [nDims nNodes]); assert(nRead == nNodes * nDims, ... 'Could not read all node info in file %s', fileName); nodes = nodes'; % terminate the reading of current line fgetl(f); %% read edge section % check sub-header line = fgetl(f); if ~strcmpi(strtrim(line(2:end)), 'edges') error(['Could not interpret edge section in file:' fileName]); end % read the number of nodes line = fgetl(f); nEdgesStr = strtok(line); nEdges = str2double(nEdgesStr); % read node indices of each edge [edges, nRead] = fscanf(f, '%d %d\n', [2 nEdges]); assert(nRead == nEdges * 2, ... 'Could not read all edge info in file %s', fileName); edges = edges'; %% Clean up fclose(f); matgeom-1.2.4/inst/graphs/PaxHeaders/Contents.m0000644000000000000000000000013014576357161016456 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/Contents.m0000644000175000017500000002217614576357161020250 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. %CONTENTS GRAPHS Simple Toolbox for manipulating Geometric Graphs. % Version 0.6 04-Sep-2017 . % % The aim of this package is to provide functions to easily create, % modify and display geometric graphs (geometric in a sense position % nodes are associated to geometric position in 2D or 3D). % % Graph are represented by a structure with at least two arrays: % * NODES, which contains coordinates of each vertex % * EDGES, which contains indices of start and end vertex. % Some graph functions consider adjacency list, as a cell array where % each cell contains the indices of the neighbor vertices. % % Others arrays may sometimes be used: % * FACES, which contains indices of vertices of each face (either a % double array, or a cell array) % * CELLS, which contains indices of faces of each cell. % % An alternative representation is to use a structure, with fields: % * 'nodes' % * 'edges' % corresponding to the data described above. % % Note that topological description of 2D graph is entirely contained in % EDGES array, and that NODES array is used only to display the graph. % % Caution: this type of data structure is easy to create and to manage, % but may be very inefficient for some algorithms. % % Graphs are usually considered as non-oriented in this package. % % % Graph creation % delaunayGraph - Graph associated to Delaunay triangulation of input points. % euclideanMST - Build euclidean minimal spanning tree of a set of points. % prim_mst - Minimal spanning tree by Prim's algorithm. % knnGraph - Create the k-nearest neighbors graph of a set of points. % relativeNeighborhoodGraph - Relative Neighborhood Graph of a set of points. % gabrielGraph - Gabriel Graph of a set of points. % % Create graph from images % imageGraph - Create equivalent graph of a binary image. % imageBoundaryGraph - Convert boundary of a 2D/3D binary image into a graph or mesh. % % Voronoi Graphs % voronoi2d - Compute a voronoi diagram as a graph structure. % boundedVoronoi2d - Comptues a bounded voronoi diagram as a graph structure. % centroidalVoronoi2d - Centroidal Voronoi tesselation within a polygon. % centroidalVoronoi2d_MC - Centroidal Voronoi tesselation by Monte-Carlo. % boundedCentroidalVoronoi2d - Create a 2D Centroidal Voronoi Tesselation in a box. % cvtUpdate - Update germs of a CVT with given points. % cvtIterate - Update germs of a CVT using random points with given density. % meshEnergy - Computes the energy of a tesselation, as the sum of second area moments. % % Geodesic and shortest path operations % grShortestPath - Find a shortest path between two nodes in the graph. % grPropagateDistance - Propagates distances from a vertex to other vertices. % grVertexEccentricity - Eccentricity of vertices in the graph. % graphDiameter - Diameter of a graph. % graphPeripheralVertices - Peripheral vertices of a graph. % graphCenter - Center of a graph. % graphRadius - Radius of a graph. % grFindGeodesicPath - Find a geodesic path between two nodes in the graph. % grFindMaximalLengthPath - Find a path that maximizes sum of edge weights. % % Graph processing (general applications) % adjacencyListToEdges - Convert an adjacency list to an edge array. % pruneGraph - Remove all edges with a terminal vertex. % mergeGraphs - Merge two graphs, by adding nodes, edges and faces lists. % grMergeNodes - Merge two (or more) nodes in a graph. % grMergeMultipleNodes - Simplify a graph by merging multiple nodes. % grMergeMultipleEdges - Remove all edges sharing the same extremities. % grSimplifyBranches - Replace branches of a graph by single edges. % % Filtering operations on Graph % grMean - Compute mean value from neighbour nodes. % grMedian - Compute median value from neighbour nodes. % grDilate - Morphological dilation on graph. % grErode - Morphological erosion on graph. % grClose - Morphological closing on graph. % grOpen - Morphological opening on graph. % % Operations for geometric graphs % grEdgeLengths - Compute length of edges in a geometric graph. % grMergeNodeClusters - Merge cluster of connected nodes in a graph. % grMergeNodesMedian - Replace several nodes by their median coordinate. % clipGraph - Clip a graph with a rectangular area. % clipGraphPolygon - Clip a graph with a polygon. % clipMesh2dPolygon - Clip a planar mesh with a polygon. % addSquareFace - Add a (square) face defined from its vertices to a graph. % grFaceToPolygon - Compute the polygon corresponding to a graph face. % graph2Contours - Convert a graph to a set of contour curves. % % Graph information % grNodeDegree - Degree of a node in a (undirected) graph. % grNodeInnerDegree - Inner degree of a node in a graph. % grNodeOuterDegree - Outer degree of a node in a graph. % grAdjacentNodes - Find list of nodes adjacent to a given node. % grAdjacentEdges - Find list of edges adjacent to a given node. % grOppositeNode - Return opposite node in an edge. % grLabel - Associate a label to each connected component of the graph. % % Graph management (low level operations) % grRemoveNode - Remove a node in a graph. % grRemoveNodes - Remove several nodes in a graph. % grRemoveEdge - Remove an edge in a graph. % grRemoveEdges - Remove several edges from a graph. % % Graph display % drawGraph - Draw a graph, given as a set of vertices and edges. % drawGraphEdges - Draw edges of a graph. % fillGraphFaces - Fill faces of a graph with specified color. % drawDigraph - Draw a directed graph, given as a set of vertices and edges. % drawDirectedEdges - Draw edges with arrow indicating direction. % drawEdgeLabels - Draw values associated to graph edges. % drawNodeLabels - Draw values associated to graph nodes. % drawSquareMesh - Draw a 3D square mesh given as a graph. % patchGraph - Transform 3D graph (mesh) into a patch handle. % % Input/Output % readGraph - Read a graph from a text file. % writeGraph - Write a graph to an ascii file. % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2005-11-07 % Copyright 2005-2023 INRA - Cepia Software Platform help(mfilename); % Deprecated functions % grSimplifyBranches_old - Replace branches of a graph by single edges. % grRemoveMultiplePoints - Remove groups of close nodes in a graph. % boundaryGraph - Get boundary of image as a graph. % gcontour2d - Creates contour graph of a 2D binary image. % gcontour3d - Create contour graph of a 3D binary image. % Functions that requires further development % quiverToGraph - Converts quiver data to quad mesh. % Other functions matgeom-1.2.4/inst/graphs/PaxHeaders/mergeGraphs.m0000644000000000000000000000013014576357161017125 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/mergeGraphs.m0000644000175000017500000001246714576357161020721 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = mergeGraphs(varargin) %MERGEGRAPHS Merge two graphs, by adding nodes, edges and faces lists. % % % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-08-09 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE simplify = false; edges = {}; edges2 = {}; faces = {}; faces2 = {}; %% process input arguments % extract simplify tag var = varargin{nargin}; if ischar(var) if strcmp(var, 'simplify') simplify = true; varargin = varargin(1:length(varargin)-1); end end %% extract data of first graph var = varargin{1}; if iscell(var) % graph is stored as a cell array : first cell is nodes, second one is % edges, and third is faces nodes = var{1}; if length(var)>1 edges = var{2}; end if length(var)>2 faces = var{3}; end varargin = varargin(2:length(varargin)); elseif isstruct(var) % graph is stored as a structure, with fields 'nodes', 'edges', and % eventually 'faces'. nodes = var.nodes; edges = var.edges; if isfield(var, 'faces') faces = var.faces; end varargin = varargin(2:length(varargin)); elseif length(varargin)>2 % graph is stored as set of variables : nodes, edges, and eventually % faces nodes = varargin{1}; edges = varargin{2}; if length(varargin)==3 % last argument describe graph 2 varargin = varargin(3); else if length(varargin)~=4 || ~isnumeric(varargin{4}) % third argument is faces of graph 1 faces = varargin{3}; varargin = varargin(4:length(varargin)); else varargin = varargin(3:length(varargin)); end end else error('Error in passing arguments in mergeGraphs'); end %% extract data of second graph var = varargin{1}; if iscell(var) % graph is stored as a cell array : first cell is nodes, second one is % edges, and third is faces nodes2 = var{1}; if length(var)>1 edges2 = var{2}; end if length(var)>2 faces2 = var{3}; end elseif isstruct(var) % graph is stored as a structure, with fields 'nodes', 'edges', and % eventually 'faces'. nodes2 = var.nodes; edges2 = var.edges; if isfield(var, 'faces') faces2 = var.faces; end elseif length(varargin)>1 % graph is stored as set of variables : nodes, edges, and eventually % faces nodes2 = varargin{1}; edges2 = varargin{2}; if length(varargin)>2 % last argument describe graph 2 faces2 = varargin{3}; end else error('Error in passing arguments in mergeGraphs'); end %% Main algorithm % eventually convert faces if ~iscell(faces) f = cell(size(faces, 1), 1); for i = 1:size(faces, 1) f{i} = faces(i,:); end faces = f; end edges = [edges ; edges2 + size(nodes, 1)]; if iscell(faces2) for i = 1:length(faces2) faces{length(faces)+1} = faces2{i} + size(nodes, 1); %#ok end else % TODO end nodes = [nodes; nodes2]; if simplify if ~isempty(faces) [nodes, edges, faces] = grSimplifyBranches(nodes, edges, faces); else [nodes, edges] = grSimplifyBranches(nodes, edges); end end %% process output depending on how many arguments are needed if nargout == 1 graph.nodes = nodes; graph.edges = edges; if ~isempty(faces) graph.faces = faces; end varargout{1} = graph; end if nargout == 2 varargout{1} = nodes; varargout{2} = edges; end if nargout == 3 varargout{1} = nodes; varargout{2} = edges; varargout{3} = faces; end matgeom-1.2.4/inst/graphs/PaxHeaders/grNodeDegree.m0000644000000000000000000000013014576357161017213 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grNodeDegree.m0000644000175000017500000000632314576357161021001 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [degree, node] = grNodeDegree(node, edges) %GRNODEDEGREE Degree of a node in a (undirected) graph. % % DEGREE = grNodeDegree(NODE_INDEX, EDGES); % return the degree of a node in the given edge list, that is the number % of edges connected to it. % NODE_INDEX is the index of the node, and EDGES is a liste of couples of % indices (origin and destination node). % This degree is the sum of inner degree (number of edges arriving on the % node) and the outer degree (number of emanating edges). % % Note: Also works when NODE_INDEX is a vector of indices % % DEGREE = grNodeDegree(EDGES); % Return the degree of each node references by the array EDGES. DEGREE is % a column vector with as many rows as the number of nodes referenced by % edges. % % [DEG, INDS] = grNodeDegree(EDGES); % Also returns the indices of the nodes that were referenced. % % Example % edges = [1 2;1 3;2 3;2 4;3 4]; % grNodeDegree(2, edges) % ans = % 3 % grNodeDegree(edges)' % ans = % 2 3 3 2 % % See also grNodeInnerDegree, grNodeOuterDegree % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % If only edge array is given, assume we want the degree of each node if nargin == 1 edges = node; node = unique(edges(:)); end % allocate array for result degree = zeros(size(node)); % for each node ID, count the number of edges containing it for i = 1:length(node(:)) degree(i) = sum(edges(:,1) == node(i)) + sum(edges(:,2) == node(i)); end matgeom-1.2.4/inst/graphs/PaxHeaders/grMergeMultipleEdges.m0000644000000000000000000000013014576357161020735 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grMergeMultipleEdges.m0000644000175000017500000000504614576357161022524 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grMergeMultipleEdges(nodes, edges) %GRMERGEMULTIPLEEDGES Remove all edges sharing the same extremities. % % [NODES2, EDGES2] = grMergeMultipleEdges(NODES, EDGES) % Remove configuration with two edges sharing the same 2 nodes. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE rmedge = []; for e = 1:length(edges) edge = edges(e, :); for e2 = e+1:length(edges) if (edge(1) == edges(e2, 1) && edge(2) == edges(e2, 2)) || ... (edge(1) == edges(e2, 2) && edge(2) == edges(e2, 1)) rmedge(length(rmedge)+1) = e2; %#ok end end end [nodes, edges] = grRemoveEdges(nodes, edges, rmedge); % process output depending on how many arguments are needed if nargout == 1 out{1} = nodes; out{2} = edges; varargout{1} = out; end if nargout == 2 varargout = {nodes, edges}; end matgeom-1.2.4/inst/graphs/PaxHeaders/meshEnergy.m0000644000000000000000000000013014576357161016767 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/meshEnergy.m0000644000175000017500000000502214576357161020550 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function energy = meshEnergy(vertices, faces) %MESHENERGY Computes the energy of a tesselation, as the sum of second area moments. % % This function can be used to check that the total energy of Centroidal % Voronoi Tesselation (CVT) decreases with the iterations of the Lloyd % algorithm. % % E = meshEnergy(V, F) % V is the list of mesh vertices, and F are faces, as a cell array of % vertex indices. % % Example % meshEnergy % % See also % centroidalVoronoi2d, cvtUpdate, polygonSecondAreaMoments % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2017-09-01, using Matlab 9.1.0.441655 (R2016b) % Copyright 2017-2023 INRA - Cepia Software Platform nFaces = meshFaceNumber(vertices, faces); energyList = zeros(nFaces, 1); polygons = meshFacePolygons(vertices, faces); for i = 1:nFaces [Ix, Iy, Ixy] = polygonSecondAreaMoments(polygons{i}); %#ok energyList(i) = hypot(Ix, Iy); end energy = sum(energyList); matgeom-1.2.4/inst/graphs/PaxHeaders/relativeNeighborhoodGraph.m0000644000000000000000000000013014576357161022006 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/relativeNeighborhoodGraph.m0000644000175000017500000000744014576357161023575 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [gnodes, gedges] = relativeNeighborhoodGraph(points) %RELATIVENEIGHBORHOODGRAPH Relative Neighborhood Graph of a set of points. % % [NODES, EDGES] = relativeNeighborhoodGraph(POINTS) % EDGES = relativeNeighborhoodGraph(POINTS) % % The Relative Neighborhood Graph (RNG) is a subgraph of the Delaunay % Triangulation computed from the same set of points. The Gabriel graph % and the euclidean minimal spanning tree (EMST) are subgraphs of the % RNG. % % Example % nodes = rand(100, 2) * 100; % edges = relativeNeighborhoodGraph(nodes); % figure; drawGraph(nodes, edges); % % See also % gabrielGraph, euclideanMST % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2016-03-02, using Matlab 8.6.0.267246 (R2015b) % Copyright 2016-2023 INRA - Cepia Software Platform % first compute Delaunay triangulation to reduce further computations DT = delaunayTriangulation(points); E = edges(DT); % compute edge lengths nEdges = size(E, 1); edgeLengths = zeros(nEdges, 1); for i = 1:nEdges edgeLengths(i) = distancePoints(points(E(i,1),:), points(E(i,2),:)); end % identify indices of faces attached to each vertex vertexFaces = vertexAttachments(DT); % iterate over edges to check if the should be kept keepEdge = true(nEdges, 1); for iEdge = 1:nEdges iVertex1 = E(iEdge, 1); iVertex2 = E(iEdge, 2); vertex1 = points(iVertex1, :); vertex2 = points(iVertex2, :); % compute indices of faces containing one of the two vertices inds = [vertexFaces{iVertex1} vertexFaces{iVertex2}]; localFaces = DT.ConnectivityList(inds, :); % compute indices of vertices is the first neighborhood of the edge inds = unique(localFaces); inds(ismember(inds, [iVertex1 iVertex2])) = []; % compute max of distances to both original vertices dists1 = distancePoints(vertex1, points(inds, :)); dists2 = distancePoints(vertex2, points(inds, :)); distsMax = max(dists1, dists2); % keep edge if all points are outside the "lunule" defined by the edge if edgeLengths(iEdge) > min(distsMax) keepEdge(iEdge) = false; end end % filter edges gedges = E(keepEdge, :); % format output gnodes = points; if nargin == 1 gnodes = gedges; end matgeom-1.2.4/inst/graphs/PaxHeaders/imageBoundaryGraph.m0000644000000000000000000000013014576357161020431 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/imageBoundaryGraph.m0000644000175000017500000001256214576357161022221 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = imageBoundaryGraph(img) %IMAGEBOUNDARYGRAPH Convert boundary of a 2D/3D binary image into a graph or mesh. % % [NODES, EDGES] = imageBoundaryGraph(IMG) (2D) % [NODES, EDGES, FACES] = imageBoundaryGraph(IMG) (3D) % Creates a graph on the boundary of binary image IMG. Each pixel is % considered as a unit square (or cube), centered on integer coordinates. % Boundary of the shape is selected as a graph. % % Result is a set of nodes with (x,y) or (x,y,z) coordinates, a set of % edges linking two neighbour nodes, and in 3D also a set of square % faces, containing reference to each 4-tuple of nodes. % % The resulting shell is open if the binary structure touches edges of % image. % % See also % patch, drawMesh % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-28 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE %% Initialisations % retrieve image size dim = size(img); nd = length(dim); if nd==2 && (dim(1)==1 || dim(2)==1) nd=1; end % initialize result arrays nodes = zeros([0 nd]); % coordinates of vertices edges = zeros([0 2]); % first node and second nodes faces = zeros([0 4]); % indices of 4 corners of each square face %% Main processing % switch processing depending on dimension if nd == 1 img = img(:)>0; D1 = size(img,1); nodes = find(img(1:D1-1) ~= img(2:D1))+.5; if nargout == 1 varargout{1} = nodes; end return elseif nd == 2 D1 = size(img, 1); D2 = size(img, 2); px = []; py = []; ind = find(img(1:D1-1, :) ~= img(2:D1, :)); [x, y] = ind2sub([D1-1 D2], ind); px = [px; reshape([x+.5 x+.5]', length(x)*2,1)]; py = [py; reshape([y-.5 y+.5]', length(x)*2,1)]; ind = find(img(:, 1:D2-1) ~= img(:, 2:D2)); [x, y] = ind2sub([D1 D2-1], ind); px = [px; reshape([x-.5 x+.5]', length(x)*2,1)]; py = [py; reshape([y+.5 y+.5]', length(x)*2,1)]; [nodes, i, j] = unique([py px], 'rows'); %#ok ne = floor(size(px, 1)/2); edges = repmat(1:2, [ne 1]) + repmat((0:2:2*ne-1)', [1 2]); for i=1:length(edges(:)) edges(i) = j(edges(i)); end edges = unique(sort(edges, 2), 'rows'); elseif nd == 3 D1 = size(img, 1); D2 = size(img, 2); D3 = size(img, 3); px = []; py = []; pz = []; ind = find(img(1:D1-1, :, :) ~= img(2:D1, :, :)); [x, y, z] = ind2sub([D1-1 D2 D3], ind); px = [px; reshape([x+.5 x+.5 x+.5 x+.5]', length(x)*4,1)]; py = [py; reshape([y-.5 y+.5 y+.5 y-.5]', length(x)*4,1)]; pz = [pz; reshape([z-.5 z-.5 z+.5 z+.5]', length(x)*4,1)]; ind = find(img(:, 1:D2-1, :) ~= img(:, 2:D2, :)); [x, y, z] = ind2sub([D1 D2-1 D3], ind); px = [px; reshape([x-.5 x-.5 x+.5 x+.5]', length(x)*4,1)]; py = [py; reshape([y+.5 y+.5 y+.5 y+.5]', length(x)*4,1)]; pz = [pz; reshape([z-.5 z+.5 z+.5 z-.5]', length(x)*4,1)]; ind = find(img(:, :, 1:D3-1) ~= img(:, :, 2:D3)); [x, y, z] = ind2sub([D1 D2 D3-1], ind); px = [px; reshape([x-.5 x+.5 x+.5 x-.5]', length(x)*4,1)]; py = [py; reshape([y-.5 y-.5 y+.5 y+.5]', length(x)*4,1)]; pz = [pz; reshape([z+.5 z+.5 z+.5 z+.5]', length(x)*4,1)]; [nodes, i, j] = unique([py px pz], 'rows'); %#ok nf = floor(size(px, 1)/4); faces = repmat(1:4, [nf 1]) + repmat((0:4:4*nf-1)', [1 4]); for i=1:length(faces(:)) faces(i) = j(faces(i)); end edges = [edges ; [faces(:,1) faces(:,2)]]; edges = [edges ; [faces(:,2) faces(:,3)]]; edges = [edges ; [faces(:,3) faces(:,4)]]; edges = [edges ; [faces(:,4) faces(:,1)]]; edges = unique(sort(edges, 2), 'rows'); end %% format output arguments if nargout == 3 varargout{1} = nodes; varargout{2} = edges; varargout{3} = faces; elseif nargout == 2 varargout{1} = nodes; varargout{2} = edges; elseif nargout == 1 graph.nodes = nodes; graph.edges = edges; graph.faces = faces; varargout{1} = graph; end matgeom-1.2.4/inst/graphs/PaxHeaders/grMean.m0000644000000000000000000000013014576357161016072 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grMean.m0000644000175000017500000000467214576357161017665 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grMean(varargin) %GRMEAN Compute mean value from neighbour nodes. % % LBL2 = grMean(EDGES, LBL1) % new label for each node of the graph is computed as the mean of the % values of neighbours and of old value. % % Example % grMean % % See also % grMedian, grDilate, grErode % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin) == 2 edges = varargin{1}; values = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; values = varargin{3}; else error('Wrong number of arguments in "grMean"'); end res = zeros(size(values)); uni = unique(edges(:)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); res(uni(n)) = mean(values([uni(n); neigh])); end varargout{1} = res; matgeom-1.2.4/inst/graphs/PaxHeaders/grFindMaximalLengthPath.m0000644000000000000000000000013014576357161021362 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grFindMaximalLengthPath.m0000644000175000017500000000714514576357161023153 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function path = grFindMaximalLengthPath(nodes, edges, edgeWeights) %GRFINDMAXIMALLENGTHPATH Find a path that maximizes sum of edge weights. % % PATH = grFindMaximalLengthPath(NODES, EDGES, EDGE_WEIGHTS); % Finds a greatest geodesic path in the graph. A path between two nodes % is a succession of adjacent edges that link the first and last nodes. % the length of the path is the sum of weights of edges that constitute % the path. % A geodesic path is a path that minimizes the length of the path among % the set of paths between the nodes. % A maximal length path maximizes the length of the geodesic path between % couples of nodes in the graph % % The result PATH is the list of edge indices that constitutes the path. % % PATH = grFindMaximalLengthPath(NODES, EDGES); % Assumes each edge has a weight equal to 1. % % See also % grFindGeodesicPath % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2011-2023 INRA - Cepia Software Platform % ensure weights are defined if ~exist('edgeWeights', 'var') edgeWeights = ones(size(edges, 1), 1); end % find an extremity vertex inds = graphPeripheralVertices(nodes, edges, edgeWeights); ind0 = inds(end); % find a vertex opposite to the first extremity dists = grPropagateDistance(nodes, edges, ind0, edgeWeights); ind1 = find(dists == max(dists), 1, 'first'); % iterate on neighbors of current node: choose next neighbor with smallest % cumulated weight, until we are back on source node path = []; while true % find neighbor with lowest cumulated distance neighs = grAdjacentNodes(edges, ind1); neighDists = dists(neighs); indN = find(neighDists == min(neighDists), 1); ind2 = neighs(indN); % add edge index to the path indE = find(sum(ismember(edges, [ind1 ind2]), 2) == 2, 1); path = [path indE]; %#ok % test if path is finished or not if ind2 == ind0 break; end ind1 = ind2; end matgeom-1.2.4/inst/graphs/PaxHeaders/pruneGraph.m0000644000000000000000000000013014576357161016774 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/pruneGraph.m0000644000175000017500000000500114576357161020552 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2] = pruneGraph(nodes, edges) %PRUNEGRAPH Remove all edges with a terminal vertex. % % [NODES2, EDGES2] = pruneGraph(NODES, EDGES) % % Example % nodes = [... % 10 30; 30 30; 20 45; 50 30; 40 15; 70 30; 90 30; 80 15; 100 45]; % edges = [1 2;2 3;2 4;4 5;4 6;6 7;6 8;7 8;7 9]; % figure; % subplot(2, 1, 1); drawGraph(nodes, edges); % axis equal; axis([0 110 10 50]); % [nodes2, edges2] = pruneGraph(nodes, edges); % subplot(2, 1, 2); drawGraph(nodes2, edges2); % axis equal; axis([0 110 10 50]); % % See also % graphs % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2015-02-19, using Matlab 8.4.0.150421 (R2014b) % Copyright 2015-2023 INRA - Cepia Software Platform nNodes = size(nodes, 1); degs = grNodeDegree(1:nNodes, edges)'; termNodeInds = find(degs == 1); [nodes2, edges2] = grRemoveNodes(nodes, edges, termNodeInds); matgeom-1.2.4/inst/graphs/PaxHeaders/grRemoveEdges.m0000644000000000000000000000013014576357161017417 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grRemoveEdges.m0000644000175000017500000000530214576357161021201 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function [nodes2, edges2] = grRemoveEdges(nodes, edges, rmEdges) %GRREMOVEEDGES Remove several edges from a graph. % % [NODES2 EDGES2] = grRemoveEdges(NODES, EDGES, EDGES2REMOVE) % Remove some edges in the edges list, and return the modified graph. % The NODES array is not modified. % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE rmEdges = sort(rmEdges); % do not change the node list nodes2 = nodes; % number of edges N = size(edges, 1); NR = length(rmEdges); N2 = N - NR; % allocate memory for new edges list edges2 = zeros(N2, 2); % case of no edge to remove if NR == 0 nodes2 = nodes; edges2 = edges; return; end % process the first edge edges2(1:rmEdges(1)-1,:) = edges(1:rmEdges(1)-1,:); % process the classical edges for i = 2:NR %if rmEdges(i)-i < rmEdges(i-1)-i+2 % continue; %end edges2(rmEdges(i-1)-i+2:rmEdges(i)-i, :) = edges(rmEdges(i-1)+1:rmEdges(i)-1, :); end % process the last edge edges2(rmEdges(NR)-NR+1:N2, :) = edges(rmEdges(NR)+1:N, :); matgeom-1.2.4/inst/graphs/PaxHeaders/drawDigraph.m0000644000000000000000000000013014576357161017115 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/drawDigraph.m0000644000175000017500000000661414576357161020706 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = drawDigraph(varargin) %DRAWDIGRAPH Draw a directed graph, given as a set of vertices and edges. % % drawDigraph(NODES1, NODES2, EDGES) % NODES1 are originating vertices % NODES2 are destination vertices % EDGES is an array, with first column containing index of origin vertex % (index in NODES1), and second column containing index of destination % vertex (index in NODES2). % Edges are drawn with arrows. % % H = drawDigraph(...) % return handle to the set of edges. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-08-17 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE %% Initialisations % check number of arguments if nargin < 3 help drawDigraph; return; end % initialisations sn1 = 'bo'; % nodes are red circles sn2 = 'ro'; % nodes are red circles %% process input arguments % First extract the graph structure n1 = varargin{1}; n2 = varargin{2}; e = varargin{3}; varargin = varargin(4:length(varargin)); % extract drawing style if ~isempty(varargin) sn1 = varargin{1}; end if length(varargin)>1 sn2 = varargin{2}; end %% main drawing processing hold on; nodes = [n1 ; n2]; e(:,2) = e(:,2)+length(n1); % Draw a 2 dimensional directed graph % Draw 2D Edges %if ~strcmp(se, 'none') & size(e, 1)>0 % he = plot([n1(e(:,1),1) n2(e(:,2),1)]', [n1(e(:,1),2) n2(e(:,2),2)]', se); %end he = drawDirectedEdges(nodes, e); hn = []; % Draw 2D nodes if ~strcmp(sn1, 'none') hn = plot(n1(:,1), n1(:,2), sn1); end % Draw 2D nodes if ~strcmp(sn2, 'none') hn = plot(n2(:,1), n2(:,2), sn2); end %% format output arguments if nargout==1 varargout{1} = he; end if nargout==2 varargout{1} = hn; varargout{2} = he; end matgeom-1.2.4/inst/graphs/PaxHeaders/grPropagateDistance.m0000644000000000000000000000013014576357161020607 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grPropagateDistance.m0000644000175000017500000001003414576357161022367 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function d = grPropagateDistance(v, e, v0, l) %GRPROPAGATEDISTANCE Propagates distances from a vertex to other vertices. % % DISTS = grPropagateDistance(V, E, V0, L) % V0 is index of initial vertex % E is array of source and target vertices % L is the vector of length of each edge. If not specified, length 1 is % assumed for all edges. % The result DISTS is a column array with as many rows as the number of % vertices, containing the geodesic distance of each vertex to the vertex % of index V0. % % Example % nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; % edges = [1 2;2 3;2 4;4 6;5 6;6 7]; % figure; drawGraph(nodes, edges); % axis([0 100 0 100]); axis equal; hold on % DISTS = grPropagateDistance(nodes, edges, 2) % DISTS = % 1 % 0 % 1 % 1 % 3 % 2 % 3 % drawNodeLabels(nodes+1, DISTS); % % See also % graphRadius, graphCenter, graphDiameter, graphPeripheralVertices % grVertexEccentricity % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % initialize empty array for result Nv = length(v); d = ones(Nv, 1)*inf; d(v0) = 0; % ensure there is a valid length array if nargin < 4 l = ones(size(e,1), 1); end % iterate from germ vertex until there are no more vertices to process verticesToProcess = v0; while ~isempty(verticesToProcess) % init new iteration newVerticesToProcess = []; % iterate over vertices that need to be updated for i = 1:length(verticesToProcess) vertex = verticesToProcess(i); % iterate over neighbor edges of current vertex vertexEdges = grAdjacentEdges(e, vertex); for j = 1:length(vertexEdges) iEdge = vertexEdges(j); % compute distance between current vertex and its neighbor vertex2 = grOppositeNode(e(iEdge,:), vertex); newDist = d(vertex) + l(iEdge); % update geodesic distance of neighbor node if needed if newDist < d(vertex2) d(vertex2) = newDist; newVerticesToProcess = [newVerticesToProcess ; vertex2]; %#ok end end end % update set of vertices for next tieration verticesToProcess = newVerticesToProcess; end matgeom-1.2.4/inst/graphs/PaxHeaders/graphDiameter.m0000644000000000000000000000013014576357161017435 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/graphDiameter.m0000644000175000017500000000526314576357161021225 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function diam = graphDiameter(v, e, l) %GRAPHDIAMETER Diameter of a graph. % % D = graphDiameter(V, E) % Computes the diameter of the graph given by V and E. The diameter of % the graph is the greatest eccentricity over all vertices in the graph. % % D = graphDiameter(V, E, L) % Specifies the weight of each edge for computing the distances. Default % is to consider a weight of 1 for each edge. % % Example % nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; % edges = [1 2;2 3;2 4;4 6;5 6;6 7]; % figure; drawGraph(nodes, edges); % axis([0 100 0 100]); axis equal; hold on % D = graphDiameter(nodes, edges) % D = % 4 % % See also % grPropagateDistance, grVertexEccentricity % graphCenter, graphRadius, graphPeripheralVertices % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) % Copyright 2010-2023 INRA - Cepia Software Platform % ensure there is a valid length array if nargin<3 l = ones(size(e,1), 1); end g = grVertexEccentricity(v, e, l); diam = max(g); matgeom-1.2.4/inst/graphs/PaxHeaders/grOpen.m0000644000000000000000000000013014576357161016113 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grOpen.m0000644000175000017500000000507314576357161017702 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grOpen(varargin) %GROPEN Morphological opening on graph. % % LBL2 = grOpen(EDGES, LBL1) % The labels are the result of a morphological erosion followed by a % morphological dilation. % % Example % grOpen % % See also % grClose, grErode, grDilate % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin) == 2 edges = varargin{1}; lbl = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; lbl = varargin{3}; else error('Wrong number of arguments in "grOpen"'); end uni = unique(edges(:)); % performs erosion lbl2 = zeros(size(lbl)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); lbl2(uni(n)) = min(lbl([uni(n); neigh])); end % performs dilation for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); lbl(uni(n)) = max(lbl2([uni(n); neigh])); end varargout{1} = lbl; matgeom-1.2.4/inst/graphs/PaxHeaders/grLabel.m0000644000000000000000000000013014576357161016231 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grLabel.m0000644000175000017500000000600314576357161020012 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function labels = grLabel(nodes, edges) %GRLABEL Associate a label to each connected component of the graph. % % LABELS = grLabel(NODES, EDGES) % Returns an array with as many rows as the array NODES, containing index % number of each connected component of the graph. If the graph is % totally connected, returns an array of 1. % % Example % nodes = rand(6, 2); % edges = [1 2;1 3;4 6]; % labels = grLabel(nodes, edges); % labels = % 1 % 1 % 1 % 2 % 3 % 2 % % See also % grAdjacentNodes % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2007-08-14, using Matlab 7.4.0.287 (R2007a) % Copyright 2007-2023 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas % init Nn = size(nodes, 1); labels = (1:Nn)'; % iteration until stability modif = true; while modif modif = false; % compute the minimum label in the neighborhood of each node for i = 1:Nn neigh = grAdjacentNodes(edges, i); neighLabels = labels([i;neigh]); % check for a modification if length(unique(neighLabels)) > 1 modif = true; end % put new labels labels(ismember(labels, neighLabels)) = min(neighLabels); end end % renumbering to have fewer labels labels2 = unique(labels); for i = 1:length(labels2) labels(labels == labels2(i)) = i; end matgeom-1.2.4/inst/graphs/PaxHeaders/grOppositeNode.m0000644000000000000000000000013014576357161017622 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grOppositeNode.m0000644000175000017500000000460714576357161021413 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function node2 = grOppositeNode(edges, node) %GROPPOSITENODE Return opposite node in an edge. % % NODE2 = grOppositeNode(EDGE, NODE); % Return the index of the node opposite to NODE in EDGE. % If the edge does not contain node NODE, result is 0. % % Works also if EDGE is a N-by-2 array of source and target vertex % indices, in this case the result NODE2 has as many rows as the number % of edges. % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2010-09-07 % Copyright 2010-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) % allocate memory for result Ne = size(edges, 1); node2 = zeros(Ne, 1); % iterate on edges for i = 1:Ne if edges(i,1) == node node2(i) = edges(i,2); elseif edges(i,2) == node node2(i) = edges(i,1); end end matgeom-1.2.4/inst/graphs/PaxHeaders/grClose.m0000644000000000000000000000013014576357161016257 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grClose.m0000644000175000017500000000474514576357161020053 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = grClose(varargin) %GRCLOSE Morphological closing on graph. % % LBL2 = grClose(EDGES, LBL1) % First performs dilatation, then erosion. % % Example % grOpen % % See also % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006-2023 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) if length(varargin) == 2 edges = varargin{1}; lbl = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; lbl = varargin{3}; else error('Wrong number of arguments in "grOpen"'); end uni = unique(edges(:)); % performs dilation lbl2 = zeros(size(lbl)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); lbl2(uni(n)) = max(lbl([uni(n); neigh])); end % performs erosion for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); lbl(uni(n)) = min(lbl2([uni(n); neigh])); end varargout{1} = lbl; matgeom-1.2.4/inst/graphs/PaxHeaders/patchGraph.m0000644000000000000000000000013014576357161016742 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/patchGraph.m0000644000175000017500000000522514576357161020530 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = patchGraph(nodes, edges, faces) %#ok %PATCHGRAPH Transform 3D graph (mesh) into a patch handle. % % [PX, PY, PZ] = PATCHGRAPH(NODES, EDGES, FACES) % Transform the graph defined as a set of nodes, edges and faces in a % patch which can be drawn usind matlab function 'patch'. % The result is a set of 3 array of size [NV*NF], with NV being the % number of vertices per face, and NF being the total number of faces. % each array contains one coordinate of vertices of each patch. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-28 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE if iscell(faces) p = zeros(length(faces), 1); for i = 1:length(faces) p(i) = patch( ... 'Faces', faces{i}, ... 'Vertices', nodes, ... 'FaceColor', 'r', ... 'EdgeColor', 'none') ; end else p = patch( ... 'Faces', faces, ... 'Vertices', nodes, ... 'FaceColor', 'r', ... 'EdgeColor', 'none') ; end if nargout>0 varargout{1}=p; end matgeom-1.2.4/inst/graphs/PaxHeaders/grAdjacentEdges.m0000644000000000000000000000013014576357161017673 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/grAdjacentEdges.m0000644000175000017500000000417014576357161021457 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function neigh = grAdjacentEdges(edges, node) %GRADJACENTEDGES Find list of edges adjacent to a given node. % % NEIGHS = grAdjacentEdges(EDGES, NODE) % EDGES the complete edges list (containing indices of neighbor nodes) % NODE index of the node % NEIGHS the indices of edges containing the node index % % See also % grAdjacentNodes % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2003-08-13 % Copyright 2003-2023 INRA - TPV URPOI - BIA IMASTE neigh = find(edges(:,1) == node | edges(:,2) == node); matgeom-1.2.4/inst/graphs/PaxHeaders/imageGraph.m0000644000000000000000000000013014576357161016725 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/imageGraph.m0000644000175000017500000001454114576357161020514 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function varargout = imageGraph(img, varargin) %IMAGEGRAPH Create equivalent graph of a binary image. % % [N E] = imageGraph(IMG); % or % [N E F] = imageGraph(IMG); % create graph representing adjacencies in image. N is the array of % nodes, E is the array of edges, and F is a 4-columns array containing % indices of vertices of each face. % IMG can be either 2D or 3D image. % This functions uses only 4 neighbors in 2D, and 6 neighbors in 3D. % % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2004-06-28 % Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE %% Initialisations nodes = []; edges = zeros(0, 2); faces = zeros(0, 4); cells = []; dim = size(img); nd = ndims(img); %% Main processing if nd == 2 % Process planar image N1 = dim(1); N2 = dim(2); % first find nodes, equivalent to pixels ind = find(img); [x, y] = ind2sub([N1 N2], ind); nodes = [x y]; % find vertical edges ind = find(img(1:N1, 1:N2-1) & img(1:N1, 2:N2)); for i=1:length(ind) [x, y] = ind2sub([N1 N2-1], ind(i)); i1 = find(ismember(nodes, [x y], 'rows')); i2 = find(ismember(nodes, [x y+1], 'rows')); edges(size(edges, 1)+1, 1:2) = [i1 i2]; end % find horizontal edges ind = find(img(1:N1-1, 1:N2) & img(2:N1, 1:N2)); for i=1:length(ind) [x, y] = ind2sub([N1-1 N2], ind(i)); i1 = find(ismember(nodes, [x y], 'rows')); i2 = find(ismember(nodes, [x+1 y], 'rows')); edges(size(edges, 1)+1, 1:2) = [i1 i2]; end % find faces ind = find(img(1:N1-1, 1:N2-1) & img(2:N1, 1:N2-1) & ... img(1:N1-1, 2:N2) & img(2:N1, 2:N2) ); for i=1:length(ind) [x, y] = ind2sub([N1-1 N2-1], ind(i)); i1 = find(ismember(nodes, [x y], 'rows')); i2 = find(ismember(nodes, [x+1 y], 'rows')); i3 = find(ismember(nodes, [x+1 y+1], 'rows')); i4 = find(ismember(nodes, [x y+1], 'rows')); faces(size(faces, 1)+1, 1:4) = [i1 i2 i3 i4]; end elseif nd == 3 % Process 3D image N1 = dim(1); N2 = dim(2); N3 = dim(3); % first find nodes, equivalent to pixels ind = find(img); [x, y, z] = ind2sub([N1 N2 N3], ind); nodes = [x y z]; % find edges in direction 1 ind = find(img(1:N1-1, 1:N2, 1:N3) & img(2:N1, 1:N2, 1:N3)); [x, y, z] = ind2sub([N1-1 N2 N3], ind); i1 = find(ismember(nodes, [x y z], 'rows')); i2 = find(ismember(nodes, [x+1 y z], 'rows')); edges = [edges ; [i1 i2]]; % find edges in direction 2 ind = find(img(1:N1, 1:N2-1, 1:N3) & img(1:N1, 2:N2, 1:N3)); [x, y, z] = ind2sub([N1 N2-1 N3], ind); i1 = find(ismember(nodes, [x y z], 'rows')); i2 = find(ismember(nodes, [x y+1 z], 'rows')); edges = [edges ; [i1 i2]]; % find edges in direction 3 ind = find(img(1:N1, 1:N2, 1:N3-1) & img(1:N1, 1:N2, 2:N3)); [x, y, z] = ind2sub([N1 N2 N3-1], ind); i1 = find(ismember(nodes, [x y z], 'rows')); i2 = find(ismember(nodes, [x y z+1], 'rows')); edges = [edges ; [i1 i2]]; % find faces in direction 1 ind = find(img(1:N1, 1:N2-1, 1:N3-1) & img(1:N1, 1:N2-1, 2:N3) & ... img(1:N1, 2:N2, 1:N3-1) & img(1:N1, 2:N2, 2:N3) ); [x, y, z] = ind2sub([N1 N2-1 N3-1], ind); i1 = find(ismember(nodes, [x y z], 'rows')); i2 = find(ismember(nodes, [x y+1 z], 'rows')); i3 = find(ismember(nodes, [x y+1 z+1], 'rows')); i4 = find(ismember(nodes, [x y z+1], 'rows')); faces = [faces; [i1 i2 i3 i4]]; % find faces in direction 2 ind = find(img(1:N1-1, 1:N2, 1:N3-1) & img(1:N1-1, 1:N2, 2:N3) & ... img(2:N1, 1:N2, 1:N3-1) & img(2:N1, 1:N2, 2:N3) ); [x, y, z] = ind2sub([N1-1 N2 N3-1], ind); i1 = find(ismember(nodes, [x y z], 'rows')); i2 = find(ismember(nodes, [x+1 y z], 'rows')); i3 = find(ismember(nodes, [x+1 y z+1], 'rows')); i4 = find(ismember(nodes, [x y z+1], 'rows')); faces = [faces; [i1 i2 i3 i4]]; % find faces in direction 3 ind = find(img(1:N1-1, 1:N2-1, 1:N3) & img(1:N1-1, 2:N2, 1:N3) & ... img(2:N1, 1:N2-1, 1:N3) & img(2:N1, 2:N2, 1:N3) ); [x, y, z] = ind2sub([N1-1 N2-1 N3], ind); i1 = find(ismember(nodes, [x y z], 'rows')); i2 = find(ismember(nodes, [x+1 y z], 'rows')); i3 = find(ismember(nodes, [x+1 y+1 z], 'rows')); i4 = find(ismember(nodes, [x y+1 z], 'rows')); faces = [faces; [i1 i2 i3 i4]]; end %% Format output if nargout == 1 graph.nodes = nodes; graph.edges = edges; graph.faces = faces; if nd > 2 graph.cells = cells; end varargout{1} = graph; elseif nargout == 2 varargout{1} = nodes; varargout{2} = edges; elseif nargout == 3 varargout{1} = nodes; varargout{2} = edges; varargout{3} = faces; end matgeom-1.2.4/inst/graphs/PaxHeaders/writeGraph.m0000644000000000000000000000013014576357161016775 xustar0029 mtime=1710874225.17419331 29 atime=1710874225.17419331 30 ctime=1710874225.226193261 matgeom-1.2.4/inst/graphs/writeGraph.m0000644000175000017500000000547614576357161020573 0ustar00juanpijuanpi00000000000000## Copyright (C) 2024 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. function writeGraph(nodes, edges, fileName) %WRITEGRAPH Write a graph to an ascii file. % % writeGraph(NODES, EDGES, FILENAME) % % Example % % create a basic graph and save it to a file % nodes = [10 10;20 10;10 20;20 20;27 15]; % edges = [1 2;1 3;2 4;2 5;3 4;4 5]; % writeGraph(nodes, edges, 'simpleGraph.txt'); % % See also % readGraph % ------ % Author: David Legland % E-mail: david.legland@inrae.fr % Created: 2014-01-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2014-2023 INRA - Cepia Software Platform %% File creation and init % extract "sizes" of the graph nNodes = size(nodes, 1); nEdges = size(edges, 1); nDims = size(nodes, 2); % file opening f = fopen(fileName, 'wt'); if f == -1 error(['could not open file for writing: ' fileName]); end % write header fprintf(f, '# graph\n'); %% write nodes info fprintf(f, '# nodes\n'); fprintf(f, '%d %d\n', nNodes, nDims); format = ['%g' repmat(' %g', 1, nDims-1) '\n']; for iNode = 1:nNodes fprintf(f, format, nodes(iNode, :)); end %% write edges info fprintf(f, '# edges\n'); fprintf(f, '%d\n', nEdges); format = '%d %d\n'; for iEdge = 1:nEdges fprintf(f, format, edges(iEdge, :)); end % close file fclose(f); matgeom-1.2.4/PaxHeaders/INDEX0000644000000000000000000000013214576357161013036 xustar0030 mtime=1710874225.198193287 30 atime=1710874225.182193303 30 ctime=1710874225.226193261 matgeom-1.2.4/INDEX0000644000175000017500000002306214576357161014621 0ustar00juanpijuanpi00000000000000matgeom >> Computational Geometry geom3d anglePoints3d angles3d angleSort3d boundingBox3d box3dVolume boxes3d cart2cyl cart2sph2d cart2sph2 circle3dOrigin circle3dPoint circle3dPosition circles3d clipEdge3d clipLine3d clipPlane clipPoints3d clipPolygonByPlane3d clipRay3d composeTransforms3d Contents createBasisTransform3d createEdge3d createLine3d createPlane createRay3d createRotation3dLineAngle createRotationAboutPoint3d createRotationOx createRotationOy createRotationOz createRotationVector3d createRotationVectorPoint3d createScaling3d createSphere createTranslation3d crossProduct3d cyl2cart cylinderSurfaceArea dihedralAngle distanceLines3d distancePointCircle3d distancePointEdge3d distancePointLine3d distancePointPlane distancePoints3d distancePointTriangle3d drawAngleBetweenVectors3d drawArrow3d drawAxis3d drawAxisCube drawBox3d drawCapsule drawCircle3d drawCircleArc3d drawCube drawCuboid drawCylinder drawDome drawEdge3d drawEllipse3d drawEllipseCylinder drawEllipsoid drawGrid3d drawLabels3d drawLine3d drawPartialPatch drawPlane3d drawPlatform drawPoint3d drawPolygon3d drawPolyline3d drawRay3d drawSphere drawSphericalEdge drawSphericalPolygon drawSphericalTriangle drawSurfPatch drawTorus drawVector3d edgeLength3d edges3d edgeToLine3d ellipsoidSurfaceArea equivalentEllipsoid eulerAnglesToRotation3d fillPolygon3d fillSphericalPolygon fillSphericalTriangle fitAffineTransform3d fitCircle3d fitEllipse3d fitLine3d fitPlane fitSphere geodesicCylinder hypot3 intersectBoxes3d intersectEdgePlane intersectEdgePolygon3d intersectLineCylinder intersectLinePlane intersectLinePolygon3d intersectLineSphere intersectLineTriangle3d intersectPlanes intersectPlaneSphere intersectRayPolygon3d intersectThreePlanes isBelowPlane isCoplanar isParallel3d isPerpendicular3d isPlane isPointInEllipsoid isPointOnEdge3d isPointOnLine3d isPolygon3d isTransform3d linePosition3d lines3d lineToEdge3d medianPlane mergeBoxes3d midPoint3d normalizeLine3d normalizePlane normalizeVector3d oblateSurfaceArea orientedBox3d parallelLine3d parallelPlane planeNormal planePoint planePosition planes3d planesBisector points3d polygon3dNormalAngle polygonArea3d polygonCentroid3d polygons3d projLineOnPlane projPointOnCircle3d projPointOnCylinder projPointOnLine3d projPointOnPlane prolateSurfaceArea randomAngle3d randomPointInBox3d recenterTransform3d registerPoints3dAffine registerPoints3d_icp reverseLine3d reversePlane revolutionSurface rotation3dAxisAndAngle rotation3dToEulerAngles sph2cart2d sph2cart2 spheres sphericalAngle sphericalVoronoiDomain surfaceCurvature transformCircle3d transformLine3d transformPlane3d transformPoint3d transformPolygon3d transforms3d transformVector3d triangleArea3d vectorAngle3d vectorNorm3d vectors3d polygons2d cart2geod clipPolygonByLine clipPolygon clipPolyline Contents contourMatrixToPolylines convexHull convexification curvature curveCMoment curveCSMoment curveMoment densifyPolygon distancePointPolygon distancePointPolyline distancePolygons distancePolygonsNoCross distancePolylines drawPolygon drawPolyline drawVertices expandPolygon fillPolygon findPoint geod2cart intersectEdgePolygon intersectLinePolygon intersectLinePolyline intersectPolylines intersectRayPolygon isPointInPolygon isPointOnPolyline medialAxisConvex minimumCaliperDiameter padPolyline parametrize parsePolygon pointSetsAverage polygonArea polygonBounds polygonCentroid polygonContains polygonCurvature polygonEdges polygonEquivalentEllipse polygonLength polygonLoops polygonNormalAngle polygonOuterNormal polygonPoint polygonSecondAreaMoments polygonSelfIntersections polygonSignature polygonSkeleton polygonSubcurve polygonSymmetryAxis polygonToPolyshape polygonToRow polygonVertices polylineCentroid polylineCurvature polylineLength polylinePoint polylineSelfIntersections polylineSubcurve projPointOnPolygon projPointOnPolyline randomPointInPolygon readPolygonSet removeMultipleVertices resamplePolygonByLength resamplePolygon resamplePolylineByLength resamplePolyline reversePolygon reversePolyline rowToPolygon signatureToPolygon simplifyPolygon simplifyPolyline smoothPolygon smoothPolyline splitPolygons steinerPoint steinerPolygon supportFunction triangulatePolygon writePolygonSet geom2d angle2Points angle3Points angleAbsDiff angleDiff angles2d angleSort bisector boundingBox boxes2d boxToPolygon boxToRect cartesianLine centeredEdgeToEdge centroid circleArcToPolyline circles2d circleToPolygon circumCenter circumCircle clipEdge clipLine clipPoints clipRay Contents crackPattern2 crackPattern createBasisTransform createCircle createDirectedCircle createEdge createEllipse createHomothecy createLine createLineReflection createRay createRotation90 createRotation createScaling createTranslation createVector cubicBezierToPolyline distancePointEdge distancePointEllipse distancePointLine distancePoints drawArrow drawBezierCurve drawBox drawCenteredEdge drawCircleArc drawCircle drawEdge drawEllipseArc drawEllipseAxes drawEllipse drawLabels drawLine drawOrientedBox drawParabola drawPoint drawRay drawRect drawShape drawVector edgeAngle edgeLength edgePosition edges2d edgeToLine edgeToPolyline ellipseArea ellipseCartesianCoefficients ellipsePerimeter ellipsePoint ellipses2d ellipseToPolygon enclosingCircle equivalentEllipse findClosestPoint fitAffineTransform2d fitEllipse fitLine fitPolynomialTransform2d hausdorffDistance hexagonalGrid intersectBoxes intersectCircles intersectEdges intersectLineCircle intersectLineEdge intersectLines isCounterClockwise isLeftOriented isParallel isPerpendicular isPointInCircle isPointInEllipse isPointInTriangle isPointOnCircle isPointOnEdge isPointOnLine isPointOnRay lineAngle linePosition lines2d lineToEdge medianLine mergeBoxes mergeClosePoints midPoint minDistancePoints nndist normalizeAngle normalizeVector orientedBox orientedBoxToPolygon orthogonalLine parallelEdge parallelLine pointOnLine points2d polarPoint polynomialTransform2d principalAxes principalAxesTransform projPointOnEllipse projPointOnLine radicalAxis randomPointInBox rays2d rectToBox rectToPolygon registerICP reverseEdge reverseLine rotateVector squareGrid transformEdge transformEllipse transformLine transformPoint transforms2d transformVector triangleArea triangleGrid vectorAngle vectorNorm vectors2d meshes3d averageMesh boxToMesh checkMeshAdjacentFaces circleMesh clipConvexPolyhedronByPlane clipMeshByPlane clipMeshVertices collapseEdgesWithManyFaces concatenateMeshes Contents createCube createCubeOctahedron createDodecahedron createDurerPolyhedron createIcosahedron createMengerSponge createOctahedron createRhombododecahedron createSoccerBall createStellatedMesh createTetrahedron createTetrakaidecahedron curveToMesh cutMeshByPlane cylinderMesh distancePointMesh drawFaceNormals drawMesh drawPolyhedron ellipsoidMesh ensureManifoldMesh fillMeshFaces intersectEdgeMesh3d intersectLineMesh3d intersectPlaneMesh isManifoldMesh isPointInMesh mergeCoplanarFaces mergeMeshVertices meshAdjacencyMatrix meshBoundaryEdgeIndices meshBoundaryEdges meshBoundary meshBoundaryVertexIndices meshComplement meshCurvatures meshDihedralAngles meshEdgeFaces meshEdgeLength meshEdges meshFaceAdjacency meshFaceAreas meshFaceCentroids meshFaceEdges meshFace meshFaceNormals meshFaceNumber meshFacePolygons meshSilhouette meshSurfaceArea meshVertexClustering meshVertexNormals meshVolume meshVoronoiDiagram minConvexHull polyhedra polyhedronCentroid polyhedronMeanBreadth polyhedronNormalAngle polyhedronSlice readMesh readMesh_obj readMesh_off readMesh_ply readMesh_stl removeDuplicateFaces removeDuplicateVertices removeInvalidBorderFaces removeMeshEars removeMeshFaces removeMeshVertices removeUnreferencedVertices smoothMeshFunction smoothMesh sphereMesh splitMesh steinerPolytope subdivideMesh surfToMesh tetrahedronVolume torusMesh transformMesh triangulateCurvePair triangulateFaces triangulateMesh triangulatePolygonPair3d triangulatePolygonPair trimeshEdgeFaces trimeshMeanBreadth trimeshSurfaceArea trimMesh writeMesh writeMesh_off writeMesh_ply writeMesh_stl utils isAxisHandle parseAxisHandle parseDrawInput graphs addSquareFace adjacencyListToEdges boundaryGraph boundedCentroidalVoronoi2d boundedVoronoi2d centroidalVoronoi2d centroidalVoronoi2d_MC clipGraph clipGraphPolygon clipMesh2dPolygon Contents cvtIterate cvtUpdate delaunayGraph drawDigraph drawDirectedEdges drawEdgeLabels drawGraphEdges drawGraph drawNodeLabels drawSquareMesh euclideanMST fillGraphFaces gabrielGraph gcontour2d gcontour3d grAdjacentEdges grAdjacentNodes graph2Contours graphCenter graphDiameter graphPeripheralVertices graphRadius grClose grDilate grEdgeLengths grErode grFaceToPolygon grFindGeodesicPath grFindMaximalLengthPath grLabel grMean grMedian grMergeMultipleEdges grMergeMultipleNodes grMergeNodeClusters grMergeNodes grMergeNodesMedian grNodeDegree grNodeInnerDegree grNodeOuterDegree grOpen grOppositeNode grPropagateDistance grRemoveEdge grRemoveEdges grRemoveMultiplePoints grRemoveNode grRemoveNodes grShortestPath grSimplifyBranches grVertexEccentricity imageBoundaryGraph imageGraph knnGraph mergeGraphs meshEnergy patchGraph prim_mst pruneGraph quiverToGraph readGraph relativeNeighborhoodGraph voronoi2d writeGraph polynomialCurves2d matgeom-1.2.4/PaxHeaders/COPYING0000644000000000000000000000013214576357161013277 xustar0030 mtime=1710874225.214193271 30 atime=1710874225.202193284 30 ctime=1710874225.226193261 matgeom-1.2.4/COPYING0000644000175000017500000000303414576357161015057 0ustar00juanpijuanpi00000000000000Copyright (c) 2011, INRA All rights reserved. (simplified BSD License) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of copyright holder. matgeom-1.2.4/PaxHeaders/NEWS0000644000000000000000000000013214576357161012743 xustar0030 mtime=1710874225.182193303 30 atime=1710874225.182193303 30 ctime=1710874225.226193261 matgeom-1.2.4/NEWS0000644000175000017500000000447514576357161014535 0ustar00juanpijuanpi00000000000000Summary of important user-visible changes for releases of the matgeom package =============================================================================== matgeom-1.2.5 Release Date: 2024-03-15 Release Manager: Juan Pablo Carbajal =============================================================================== * This release corresponds to upstream matgeom-1.2.7 + developments * Removed normalize.m, see https://savannah.gnu.org/bugs/?64678 * Latest fixes and developments from upstream were added. Refer to the original matgeom website for news on that =============================================================================== matgeom-1.2.4 Release Date: 2021-06-17 Release Manager: Juan Pablo Carbajal =============================================================================== * This release corresponds to upstream matgeom-1.2.2 + developments * Removed spurious files from octave distribution (see https://savannah.gnu.org/bugs/?60744) * Latest fixes and developments from upstream were added. Refer to the original matgeom website for news on that =============================================================================== matgeom-1.2.3 Release Date: 2021-06-01 Release Manager: Juan Pablo Carbajal =============================================================================== * This release corresponds to upstream matgeom-1.2.2 + developments * Latest fixes and developments from upstream were added. Refer to the original matgeom website for news on that =============================================================================== matgeom-1.2.2 Release Date: 2019-02-12 Release Manager: Juan Pablo Carbajal =============================================================================== * Installation with GNU Octave 6.0.0 was fixed * The dummy function varLessThan.m in this package now installas only for GNU Octave versions lower than 6.0.0 * Latest fixes and developments from upstream were added. Refer to the original matgeom website for news on that =============================================================================== matgeom-1.2.1 Release Date: 2019-20-11 Release Manager: Juan Pablo Carbajal =============================================================================== ** First official release. =============================================================================== matgeom-1.2.4/PaxHeaders/DESCRIPTION0000644000000000000000000000013214576357161013752 xustar0030 mtime=1710874225.178193307 30 atime=1710874225.182193303 30 ctime=1710874225.226193261 matgeom-1.2.4/DESCRIPTION0000644000175000017500000000052714576357161015536 0ustar00juanpijuanpi00000000000000Name: matgeom Version: 1.2.4 Date: 2024-19-03 Author: David Legland Maintainer: Juan Pablo Carbajal Title: Computational Geometry Description: Geometry toolbox for 2D/3D geometric computing Depends: octave (>= 4.2.0) Autoload: no License: FreeBSD Url: https://github.com/mattools/matGeom