diff -Nru octave-matgeom-1.2.2/debian/changelog octave-matgeom-1.2.3/debian/changelog --- octave-matgeom-1.2.2/debian/changelog 2020-11-14 08:36:34.000000000 +0000 +++ octave-matgeom-1.2.3/debian/changelog 2021-08-16 15:37:14.000000000 +0000 @@ -1,3 +1,18 @@ +octave-matgeom (1.2.3-2) unstable; urgency=medium + + * Upload to unstable + + -- Rafael Laboissière Mon, 16 Aug 2021 12:37:14 -0300 + +octave-matgeom (1.2.3-1) experimental; urgency=medium + + * New upstream version 1.2.3 + * d/copyright: Reflect upstream changes + * d/control: Bump Standards-Version to 4.5.1 (no changes needed) + * d/rules: Remove useless file sedgewick_points.txt + + -- Rafael Laboissière Mon, 07 Jun 2021 08:53:20 -0300 + octave-matgeom (1.2.2-3) unstable; urgency=medium [ Debian Janitor ] diff -Nru octave-matgeom-1.2.2/debian/control octave-matgeom-1.2.3/debian/control --- octave-matgeom-1.2.2/debian/control 2020-06-19 15:57:16.000000000 +0000 +++ octave-matgeom-1.2.3/debian/control 2021-08-15 12:44:37.000000000 +0000 @@ -4,7 +4,7 @@ Maintainer: Debian Octave Group Uploaders: Rafael Laboissière Build-Depends: debhelper-compat (= 13), dh-octave (>= 0.7.3) -Standards-Version: 4.5.0 +Standards-Version: 4.5.1 Homepage: https://octave.sourceforge.io/matgeom/ Vcs-Git: https://salsa.debian.org/pkg-octave-team/octave-matgeom.git Vcs-Browser: https://salsa.debian.org/pkg-octave-team/octave-matgeom diff -Nru octave-matgeom-1.2.2/debian/copyright octave-matgeom-1.2.3/debian/copyright --- octave-matgeom-1.2.2/debian/copyright 2020-06-19 15:57:16.000000000 +0000 +++ octave-matgeom-1.2.3/debian/copyright 2021-08-15 12:44:37.000000000 +0000 @@ -1,7 +1,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: * -Copyright: 2019 David Legland +Copyright: 2021 David Legland 2011 INRA License: BSD-2-clause Redistribution and use in source and binary forms, with or without @@ -37,7 +37,7 @@ License: GPL-3+ Files: debian/* -Copyright: 2020 Rafael Laboissière +Copyright: 2020, 2021 Rafael Laboissière License: GPL-3+ License: GPL-3+ diff -Nru octave-matgeom-1.2.2/debian/gbp.conf octave-matgeom-1.2.3/debian/gbp.conf --- octave-matgeom-1.2.2/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/debian/gbp.conf 2021-08-15 12:44:40.000000000 +0000 @@ -0,0 +1,4 @@ +[DEFAULT] +debian-branch = debian/latest +upstream-branch = upstream/latest +pristine-tar = True diff -Nru octave-matgeom-1.2.2/debian/rules octave-matgeom-1.2.3/debian/rules --- octave-matgeom-1.2.2/debian/rules 2020-11-14 08:34:01.000000000 +0000 +++ octave-matgeom-1.2.3/debian/rules 2021-08-15 12:44:37.000000000 +0000 @@ -13,3 +13,6 @@ [ -f $$f ] && mv $$f $(SHRDIR)/doc/octave-matgeom/$$i-$$j.txt ; \ done ; \ done + # Remove useless file sedgewick_points.txt, introduced in + # the upstream version 1.2.3 (see https://savannah.gnu.org/bugs/index.php?60744) + find debian -name sedgewick_points.txt -exec rm \{} \; diff -Nru octave-matgeom-1.2.2/DESCRIPTION octave-matgeom-1.2.3/DESCRIPTION --- octave-matgeom-1.2.2/DESCRIPTION 2019-12-04 12:15:23.011635227 +0000 +++ octave-matgeom-1.2.3/DESCRIPTION 2021-06-01 09:14:26.118813416 +0000 @@ -1,6 +1,6 @@ Name: matgeom -Version: 1.2.2 -Date: 2019-11-20 +Version: 1.2.3 +Date: 2021-01-06 Author: David Legland Maintainer: Juan Pablo Carbajal Title: Computational Geometry diff -Nru octave-matgeom-1.2.2/INDEX octave-matgeom-1.2.3/INDEX --- octave-matgeom-1.2.2/INDEX 2019-12-04 12:15:23.067636319 +0000 +++ octave-matgeom-1.2.3/INDEX 2021-06-01 09:14:26.142813325 +0000 @@ -18,13 +18,16 @@ clipLine3d clipPoints3d clipPolygon3dHP + clipRay3d composeTransforms3d Contents createBasisTransform3d createEdge3d createLine3d createPlane + createRay3d createRotation3dLineAngle + createRotationAboutPoint3d createRotationOx createRotationOy createRotationOz @@ -43,14 +46,18 @@ distancePointPlane distancePoints3d distancePointTriangle3d + drawAngleBetweenVectors3d + drawArrow3d drawAxis3d drawAxisCube drawBox3d + drawCapsule drawCircle3d drawCircleArc3d drawCube drawCuboid drawCylinder + drawDome drawEdge3d drawEllipse3d drawEllipseCylinder @@ -64,6 +71,7 @@ drawPoint3d drawPolygon3d drawPolyline3d + drawRay3d drawSphere drawSphericalEdge drawSphericalPolygon @@ -85,10 +93,12 @@ fitEllipse3d fitLine3d fitPlane + fitSphere + geodesicCylinder hypot3 - inertiaEllipsoid intersectBoxes3d intersectEdgePlane + intersectEdgePolygon3d intersectLineCylinder intersectLinePlane intersectLinePolygon3d @@ -103,6 +113,8 @@ isParallel3d isPerpendicular3d isPlane + isPointInEllipsoid + isPointOnEdge3d isPointOnLine3d isTransform3d linePosition3d @@ -111,6 +123,7 @@ medianPlane mergeBoxes3d midPoint3d + normalizeLine3d normalizePlane normalizeVector3d oblateSurfaceArea @@ -128,6 +141,8 @@ polygonCentroid3d polygons3d projLineOnPlane + projPointOnCircle3d + projPointOnCylinder projPointOnLine3d projPointOnPlane prolateSurfaceArea @@ -209,6 +224,7 @@ polygonSecondAreaMoments polygonSelfIntersections polygonSignature + polygonSkeleton polygonSubcurve polygonSymmetryAxis polygonToRow @@ -361,6 +377,7 @@ polarPoint polynomialTransform2d principalAxes + principalAxesTransform projPointOnLine radicalAxis randomPointInBox @@ -383,6 +400,7 @@ vectorNorm vectors2d meshes3d + averageMesh boxToMesh checkMeshAdjacentFaces clipConvexPolyhedronHP @@ -411,6 +429,8 @@ drawPolyhedron ellipsoidMesh ensureManifoldMesh + fillMeshFaces + intersectEdgeMesh3d intersectLineMesh3d intersectPlaneMesh isManifoldMesh @@ -421,6 +441,7 @@ meshBoundaryEdgeIndices meshBoundary meshBoundaryVertexIndices + meshComplement meshDihedralAngles meshEdgeFaces meshEdgeLength @@ -433,6 +454,7 @@ meshFaceNormals meshFaceNumber meshFacePolygons + meshSilhouette meshSurfaceArea meshVertexClustering meshVertexNormals @@ -443,8 +465,10 @@ polyhedronMeanBreadth polyhedronNormalAngle polyhedronSlice + readMesh readMesh_off readMesh_ply + readMesh_stl removeDuplicateFaces removeInvalidBorderFaces removeMeshEars @@ -467,12 +491,15 @@ trimeshSurfaceArea trimMesh vertexNormal + writeMesh writeMesh_off writeMesh_ply + writeMesh_stl utils isAxisHandle graphs addSquareFace + adjacencyListToEdges boundaryGraph boundedCentroidalVoronoi2d boundedVoronoi2d diff -Nru octave-matgeom-1.2.2/inst/Contents.m octave-matgeom-1.2.3/inst/Contents.m --- octave-matgeom-1.2.2/inst/Contents.m 2019-12-04 12:15:22.811631327 +0000 +++ octave-matgeom-1.2.3/inst/Contents.m 2021-06-01 09:14:26.030813749 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/angle2Points.m octave-matgeom-1.2.3/inst/geom2d/angle2Points.m --- octave-matgeom-1.2.2/inst/geom2d/angle2Points.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/angle2Points.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/angle3Points.m octave-matgeom-1.2.3/inst/geom2d/angle3Points.m --- octave-matgeom-1.2.2/inst/geom2d/angle3Points.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/angle3Points.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/angleAbsDiff.m octave-matgeom-1.2.3/inst/geom2d/angleAbsDiff.m --- octave-matgeom-1.2.2/inst/geom2d/angleAbsDiff.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/angleAbsDiff.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/angleDiff.m octave-matgeom-1.2.3/inst/geom2d/angleDiff.m --- octave-matgeom-1.2.2/inst/geom2d/angleDiff.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/angleDiff.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/angles2d.m octave-matgeom-1.2.3/inst/geom2d/angles2d.m --- octave-matgeom-1.2.2/inst/geom2d/angles2d.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/angles2d.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function angles2d -%ANGLES2D Description of functions for manipulating angles. +% 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 @@ -39,11 +39,11 @@ % See also: % normalizeAngle, angleDiff, angleAbsDiff, angleSort % angle2Points, angle3Points, vectorAngle, lineAngle, edgeAngle -% deg2rad, rad2deg % + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2010-03-31, using Matlab 7.4.0.287 (R2007a) % Copyright 2010 INRA - Cepia Software Platform. diff -Nru octave-matgeom-1.2.2/inst/geom2d/angleSort.m octave-matgeom-1.2.3/inst/geom2d/angleSort.m --- octave-matgeom-1.2.2/inst/geom2d/angleSort.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/angleSort.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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. +%ANGLESORT Sort points in the plane according to their angle to origin. % % % PTS2 = angleSort(PTS); @@ -43,6 +43,9 @@ % [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 % @@ -79,14 +82,19 @@ angle = lineAngle([zeros(n, 2) pts2]); angle = mod(angle - theta0 + 2*pi, 2*pi); -[dummy, I] = sort(angle); %#ok +[angles, I] = sort(angle); % format output -if nargout<2 - varargout{1} = pts(I, :); -elseif nargout==2 - varargout{1} = pts(I, :); - varargout{2} = I; +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 diff -Nru octave-matgeom-1.2.2/inst/geom2d/bisector.m octave-matgeom-1.2.3/inst/geom2d/bisector.m --- octave-matgeom-1.2.2/inst/geom2d/bisector.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/bisector.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/boundingBox.m octave-matgeom-1.2.3/inst/geom2d/boundingBox.m --- octave-matgeom-1.2.2/inst/geom2d/boundingBox.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/boundingBox.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/boxes2d.m octave-matgeom-1.2.3/inst/geom2d/boxes2d.m --- octave-matgeom-1.2.2/inst/geom2d/boxes2d.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/boxes2d.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/boxToPolygon.m octave-matgeom-1.2.3/inst/geom2d/boxToPolygon.m --- octave-matgeom-1.2.2/inst/geom2d/boxToPolygon.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/boxToPolygon.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/boxToRect.m octave-matgeom-1.2.3/inst/geom2d/boxToRect.m --- octave-matgeom-1.2.2/inst/geom2d/boxToRect.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/boxToRect.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/cartesianLine.m octave-matgeom-1.2.3/inst/geom2d/cartesianLine.m --- octave-matgeom-1.2.2/inst/geom2d/cartesianLine.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/cartesianLine.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/centeredEdgeToEdge.m octave-matgeom-1.2.3/inst/geom2d/centeredEdgeToEdge.m --- octave-matgeom-1.2.2/inst/geom2d/centeredEdgeToEdge.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/centeredEdgeToEdge.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/centroid.m octave-matgeom-1.2.3/inst/geom2d/centroid.m --- octave-matgeom-1.2.2/inst/geom2d/centroid.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/centroid.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/circleArcToPolyline.m octave-matgeom-1.2.3/inst/geom2d/circleArcToPolyline.m --- octave-matgeom-1.2.2/inst/geom2d/circleArcToPolyline.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/circleArcToPolyline.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/circles2d.m octave-matgeom-1.2.3/inst/geom2d/circles2d.m --- octave-matgeom-1.2.2/inst/geom2d/circles2d.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/circles2d.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/circleToPolygon.m octave-matgeom-1.2.3/inst/geom2d/circleToPolygon.m --- octave-matgeom-1.2.2/inst/geom2d/circleToPolygon.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/circleToPolygon.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/circumCenter.m octave-matgeom-1.2.3/inst/geom2d/circumCenter.m --- octave-matgeom-1.2.2/inst/geom2d/circumCenter.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/circumCenter.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/circumCircle.m octave-matgeom-1.2.3/inst/geom2d/circumCircle.m --- octave-matgeom-1.2.2/inst/geom2d/circumCircle.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/circumCircle.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/clipEdge.m octave-matgeom-1.2.3/inst/geom2d/clipEdge.m --- octave-matgeom-1.2.2/inst/geom2d/clipEdge.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/clipEdge.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/clipLine.m octave-matgeom-1.2.3/inst/geom2d/clipLine.m --- octave-matgeom-1.2.2/inst/geom2d/clipLine.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/clipLine.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/clipPoints.m octave-matgeom-1.2.3/inst/geom2d/clipPoints.m --- octave-matgeom-1.2.2/inst/geom2d/clipPoints.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/clipPoints.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/clipRay.m octave-matgeom-1.2.3/inst/geom2d/clipRay.m --- octave-matgeom-1.2.2/inst/geom2d/clipRay.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/clipRay.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -47,7 +47,7 @@ % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2010-05-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2010 INRA - Cepia Software Platform. @@ -71,8 +71,8 @@ inds = find(isfinite(edge(:, 1))); % compute position of edge extremities relative to the ray -pos1 = linePosition(edge(inds,1:2), ray(inds,:)); -pos2 = linePosition(edge(inds,3:4), ray(inds,:)); +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); diff -Nru octave-matgeom-1.2.2/inst/geom2d/Contents.m octave-matgeom-1.2.3/inst/geom2d/Contents.m --- octave-matgeom-1.2.2/inst/geom2d/Contents.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/Contents.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -42,12 +42,12 @@ % points2d - Description of functions operating on points. % midPoint - Middle point of two points or of an edge. % circumCenter - Circumcenter of three points. -% isCounterClockwise - Compute relative orientation of 3 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 - Transform a point with an affine transform. +% transformPoint - Apply an affine transform to a point or a point set. % drawPoint - Draw the point on the axis. % % Point Sets @@ -66,7 +66,7 @@ % 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 - Angle of a vector, or between 2 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. @@ -161,7 +161,8 @@ % 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. -% fitAffineTransform2d - Fit an affine transform using two point sets. +% 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. @@ -171,8 +172,6 @@ % normalizeAngle - Normalize an angle value within a 2*PI interval. % angleAbsDiff - Absolute difference between two angles. % angleDiff - Difference between two angles. -% deg2rad - Convert angle from degrees to radians. -% rad2deg - Convert angle from radians to degrees. % % Boxes % boxes2d - Description of functions operating on bounding boxes. @@ -205,7 +204,6 @@ % 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. @@ -220,7 +218,7 @@ % % ----- % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2005-11-07 % Copyright INRA - Cepia Software Platform. % Project homepage: http://github.com/mattools/matGeom @@ -233,3 +231,4 @@ % inertiaEllipse - Inertia ellipse of a set of points. %% Others... + diff -Nru octave-matgeom-1.2.2/inst/geom2d/crackPattern2.m octave-matgeom-1.2.3/inst/geom2d/crackPattern2.m --- octave-matgeom-1.2.2/inst/geom2d/crackPattern2.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/crackPattern2.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/crackPattern.m octave-matgeom-1.2.3/inst/geom2d/crackPattern.m --- octave-matgeom-1.2.2/inst/geom2d/crackPattern.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/crackPattern.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createBasisTransform.m octave-matgeom-1.2.3/inst/geom2d/createBasisTransform.m --- octave-matgeom-1.2.2/inst/geom2d/createBasisTransform.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createBasisTransform.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createCircle.m octave-matgeom-1.2.3/inst/geom2d/createCircle.m --- octave-matgeom-1.2.2/inst/geom2d/createCircle.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createCircle.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createDirectedCircle.m octave-matgeom-1.2.3/inst/geom2d/createDirectedCircle.m --- octave-matgeom-1.2.2/inst/geom2d/createDirectedCircle.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createDirectedCircle.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createEdge.m octave-matgeom-1.2.3/inst/geom2d/createEdge.m --- octave-matgeom-1.2.2/inst/geom2d/createEdge.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createEdge.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createHomothecy.m octave-matgeom-1.2.3/inst/geom2d/createHomothecy.m --- octave-matgeom-1.2.2/inst/geom2d/createHomothecy.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createHomothecy.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createLine.m octave-matgeom-1.2.3/inst/geom2d/createLine.m --- octave-matgeom-1.2.2/inst/geom2d/createLine.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createLine.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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. +%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 @@ -131,6 +131,8 @@ % 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. diff -Nru octave-matgeom-1.2.2/inst/geom2d/createLineReflection.m octave-matgeom-1.2.3/inst/geom2d/createLineReflection.m --- octave-matgeom-1.2.2/inst/geom2d/createLineReflection.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createLineReflection.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createRay.m octave-matgeom-1.2.3/inst/geom2d/createRay.m --- octave-matgeom-1.2.2/inst/geom2d/createRay.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createRay.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createRotation90.m octave-matgeom-1.2.3/inst/geom2d/createRotation90.m --- octave-matgeom-1.2.2/inst/geom2d/createRotation90.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createRotation90.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createRotation.m octave-matgeom-1.2.3/inst/geom2d/createRotation.m --- octave-matgeom-1.2.2/inst/geom2d/createRotation.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createRotation.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createScaling.m octave-matgeom-1.2.3/inst/geom2d/createScaling.m --- octave-matgeom-1.2.2/inst/geom2d/createScaling.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createScaling.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createTranslation.m octave-matgeom-1.2.3/inst/geom2d/createTranslation.m --- octave-matgeom-1.2.2/inst/geom2d/createTranslation.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createTranslation.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/createVector.m octave-matgeom-1.2.3/inst/geom2d/createVector.m --- octave-matgeom-1.2.2/inst/geom2d/createVector.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/createVector.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/cubicBezierToPolyline.m octave-matgeom-1.2.3/inst/geom2d/cubicBezierToPolyline.m --- octave-matgeom-1.2.2/inst/geom2d/cubicBezierToPolyline.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/cubicBezierToPolyline.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/distancePointEdge.m octave-matgeom-1.2.3/inst/geom2d/distancePointEdge.m --- octave-matgeom-1.2.2/inst/geom2d/distancePointEdge.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/distancePointEdge.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/distancePointLine.m octave-matgeom-1.2.3/inst/geom2d/distancePointLine.m --- octave-matgeom-1.2.2/inst/geom2d/distancePointLine.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/distancePointLine.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/distancePoints.m octave-matgeom-1.2.3/inst/geom2d/distancePoints.m --- octave-matgeom-1.2.2/inst/geom2d/distancePoints.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/distancePoints.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawArrow.m octave-matgeom-1.2.3/inst/geom2d/drawArrow.m --- octave-matgeom-1.2.2/inst/geom2d/drawArrow.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawArrow.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawBezierCurve.m octave-matgeom-1.2.3/inst/geom2d/drawBezierCurve.m --- octave-matgeom-1.2.2/inst/geom2d/drawBezierCurve.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawBezierCurve.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawBox.m octave-matgeom-1.2.3/inst/geom2d/drawBox.m --- octave-matgeom-1.2.2/inst/geom2d/drawBox.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawBox.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawCenteredEdge.m octave-matgeom-1.2.3/inst/geom2d/drawCenteredEdge.m --- octave-matgeom-1.2.2/inst/geom2d/drawCenteredEdge.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawCenteredEdge.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawCircleArc.m octave-matgeom-1.2.3/inst/geom2d/drawCircleArc.m --- octave-matgeom-1.2.2/inst/geom2d/drawCircleArc.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawCircleArc.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawCircle.m octave-matgeom-1.2.3/inst/geom2d/drawCircle.m --- octave-matgeom-1.2.2/inst/geom2d/drawCircle.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawCircle.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawEdge.m octave-matgeom-1.2.3/inst/geom2d/drawEdge.m --- octave-matgeom-1.2.2/inst/geom2d/drawEdge.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawEdge.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawEllipseArc.m octave-matgeom-1.2.3/inst/geom2d/drawEllipseArc.m --- octave-matgeom-1.2.2/inst/geom2d/drawEllipseArc.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawEllipseArc.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawEllipse.m octave-matgeom-1.2.3/inst/geom2d/drawEllipse.m --- octave-matgeom-1.2.2/inst/geom2d/drawEllipse.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawEllipse.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawLabels.m octave-matgeom-1.2.3/inst/geom2d/drawLabels.m --- octave-matgeom-1.2.2/inst/geom2d/drawLabels.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawLabels.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,21 +26,27 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawLabels(varargin) -%DRAWLABELS Draw labels at specified positions. +% Draw labels at specified positions. % -% DRAWLABELS(X, Y, LBL) draw labels LBL at position X and Y. +% 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, with '%.2f' mask. +% string are created by using sprintf function, using the '%.2f' format. % -% DRAWLABELS(POS, LBL) draw labels LBL at position specified by POS,. -% where POS is a N*2 int array. +% drawLabels(POS, LBL) +% Draws labels LBL at position specified by POS, where POS is a N-by-2 +% numeric array. % -% DRAWLABELS(..., NUMBERS, FORMAT) create labels using sprintf function,. -% with the mask given by FORMAT (e. g. '%03d' or '5.3f'), and the -% corresponding values. +% 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 % INRA - TPV URPOI - BIA IMASTE % created the 15/12/2003. @@ -87,8 +93,12 @@ % format for displaying numeric values format = '%.2f'; -if ~isempty(varargin) - format = varargin{1}; +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); @@ -110,7 +120,7 @@ labels = char(labels); % display the text -h = text(px, py, labels, 'parent', ax); +h = text(px, py, labels, 'parent', ax, varargin{:}); % format output if nargout > 0 diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawLine.m octave-matgeom-1.2.3/inst/geom2d/drawLine.m --- octave-matgeom-1.2.2/inst/geom2d/drawLine.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawLine.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawOrientedBox.m octave-matgeom-1.2.3/inst/geom2d/drawOrientedBox.m --- octave-matgeom-1.2.2/inst/geom2d/drawOrientedBox.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawOrientedBox.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawParabola.m octave-matgeom-1.2.3/inst/geom2d/drawParabola.m --- octave-matgeom-1.2.2/inst/geom2d/drawParabola.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawParabola.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawPoint.m octave-matgeom-1.2.3/inst/geom2d/drawPoint.m --- octave-matgeom-1.2.2/inst/geom2d/drawPoint.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawPoint.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawRay.m octave-matgeom-1.2.3/inst/geom2d/drawRay.m --- octave-matgeom-1.2.2/inst/geom2d/drawRay.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawRay.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawRect.m octave-matgeom-1.2.3/inst/geom2d/drawRect.m --- octave-matgeom-1.2.2/inst/geom2d/drawRect.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawRect.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawShape.m octave-matgeom-1.2.3/inst/geom2d/drawShape.m --- octave-matgeom-1.2.2/inst/geom2d/drawShape.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawShape.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/drawVector.m octave-matgeom-1.2.3/inst/geom2d/drawVector.m --- octave-matgeom-1.2.2/inst/geom2d/drawVector.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/drawVector.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/edgeAngle.m octave-matgeom-1.2.3/inst/geom2d/edgeAngle.m --- octave-matgeom-1.2.2/inst/geom2d/edgeAngle.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/edgeAngle.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/edgeLength.m octave-matgeom-1.2.3/inst/geom2d/edgeLength.m --- octave-matgeom-1.2.2/inst/geom2d/edgeLength.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/edgeLength.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/edgePosition.m octave-matgeom-1.2.3/inst/geom2d/edgePosition.m --- octave-matgeom-1.2.2/inst/geom2d/edgePosition.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/edgePosition.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/edges2d.m octave-matgeom-1.2.3/inst/geom2d/edges2d.m --- octave-matgeom-1.2.2/inst/geom2d/edges2d.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/edges2d.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/edgeToLine.m octave-matgeom-1.2.3/inst/geom2d/edgeToLine.m --- octave-matgeom-1.2.2/inst/geom2d/edgeToLine.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/edgeToLine.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/edgeToPolyline.m octave-matgeom-1.2.3/inst/geom2d/edgeToPolyline.m --- octave-matgeom-1.2.2/inst/geom2d/edgeToPolyline.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/edgeToPolyline.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/ellipsePerimeter.m octave-matgeom-1.2.3/inst/geom2d/ellipsePerimeter.m --- octave-matgeom-1.2.2/inst/geom2d/ellipsePerimeter.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/ellipsePerimeter.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/ellipses2d.m octave-matgeom-1.2.3/inst/geom2d/ellipses2d.m --- octave-matgeom-1.2.2/inst/geom2d/ellipses2d.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/ellipses2d.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/ellipseToPolygon.m octave-matgeom-1.2.3/inst/geom2d/ellipseToPolygon.m --- octave-matgeom-1.2.2/inst/geom2d/ellipseToPolygon.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/ellipseToPolygon.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/enclosingCircle.m octave-matgeom-1.2.3/inst/geom2d/enclosingCircle.m --- octave-matgeom-1.2.2/inst/geom2d/enclosingCircle.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/enclosingCircle.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/equivalentEllipse.m octave-matgeom-1.2.3/inst/geom2d/equivalentEllipse.m --- octave-matgeom-1.2.2/inst/geom2d/equivalentEllipse.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/equivalentEllipse.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -52,7 +52,8 @@ % drawEllipse(ell, 'linewidth', 2, 'color', 'r'); % % See also -% ellipses2d, drawEllipse, equivalentEllipsoid, principalAxes +% ellipses2d, drawEllipse, equivalentEllipsoid, principalAxes, +% principalAxesTransform % % ------ diff -Nru octave-matgeom-1.2.2/inst/geom2d/findClosestPoint.m octave-matgeom-1.2.3/inst/geom2d/findClosestPoint.m --- octave-matgeom-1.2.2/inst/geom2d/findClosestPoint.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/findClosestPoint.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/fitAffineTransform2d.m octave-matgeom-1.2.3/inst/geom2d/fitAffineTransform2d.m --- octave-matgeom-1.2.2/inst/geom2d/fitAffineTransform2d.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/fitAffineTransform2d.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,18 +25,34 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function trans = fitAffineTransform2d(pts1, pts2) -%FITAFFINETRANSFORM2D Fit an affine transform using two point sets. -% TRANS = fitAffineTransform2d(PTS1, PTS2) +function trans = fitAffineTransform2d(ref, src) +% 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 -% N = 10; -% pts = rand(N, 2)*10; -% trans = createRotation(3, 4, pi/4); -% pts2 = transformPoint(pts, trans); -% pts3 = pts2 + randn(N, 2)*2; -% fitted = fitAffineTransform2d(pts, pts2); -% +% % 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, @@ -45,24 +61,23 @@ % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2009-07-31, using Matlab 7.7.0.471 (R2008b) -% Copyright 2009 INRA - Cepia Software Platform. - +% Copyright 2009 INRAE - Cepia Software Platform. -% number of points -N = size(pts1, 1); -if size(pts2, 1) ~= N +% 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 = [... - pts1(:,1) pts1(:,2) ones(N,1) zeros(N, 3) ; ... - zeros(N, 3) pts1(:,1) pts1(:,2) ones(N,1) ]; + src(:,1) src(:,2) ones(N,1) zeros(N, 3) ; ... + zeros(N, 3) src(:,1) src(:,2) ones(N,1) ]; % conditions initialisations -B = [pts2(:,1) ; pts2(:,2)]; +B = [ref(:,1) ; ref(:,2)]; % compute coefficients using least square coefs = A\B; diff -Nru octave-matgeom-1.2.2/inst/geom2d/fitPolynomialTransform2d.m octave-matgeom-1.2.3/inst/geom2d/fitPolynomialTransform2d.m --- octave-matgeom-1.2.2/inst/geom2d/fitPolynomialTransform2d.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/fitPolynomialTransform2d.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/hausdorffDistance.m octave-matgeom-1.2.3/inst/geom2d/hausdorffDistance.m --- octave-matgeom-1.2.2/inst/geom2d/hausdorffDistance.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/hausdorffDistance.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function [hd, ind1, ind2] = hausdorffDistance(pts1, pts2) -%HAUSDORFFDISTANCE Hausdorff distance between two point sets. +%HAUSDORFFDISTANCE Hausdorff distance between two point sets. % % HD = hausdorffDistance(PTS1, PTS2) % Computes the Hausdorff distance between the two point sets PTS1 and @@ -59,16 +59,17 @@ % drawEdge([p1h p2h], 'm') % % See also -% minDistancePoints +% points2d, minDistancePoints % % References % http://en.wikipedia.org/wiki/Hausdorff_distance % + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2012-05-04, using Matlab 7.9.0.529 (R2009b) -% Copyright 2012 INRA - Cepia Software Platform. +% Copyright 2012 INRAE - Cepia Software Platform. % distance from pts1 to pts2 [dists1, ind12] = minDistancePoints(pts1, pts2); diff -Nru octave-matgeom-1.2.2/inst/geom2d/hexagonalGrid.m octave-matgeom-1.2.3/inst/geom2d/hexagonalGrid.m --- octave-matgeom-1.2.2/inst/geom2d/hexagonalGrid.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/hexagonalGrid.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/inertiaEllipse.m octave-matgeom-1.2.3/inst/geom2d/inertiaEllipse.m --- octave-matgeom-1.2.2/inst/geom2d/inertiaEllipse.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/inertiaEllipse.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/intersectBoxes.m octave-matgeom-1.2.3/inst/geom2d/intersectBoxes.m --- octave-matgeom-1.2.2/inst/geom2d/intersectBoxes.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/intersectBoxes.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/intersectCircles.m octave-matgeom-1.2.3/inst/geom2d/intersectCircles.m --- octave-matgeom-1.2.2/inst/geom2d/intersectCircles.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/intersectCircles.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/intersectEdges.m octave-matgeom-1.2.3/inst/geom2d/intersectEdges.m --- octave-matgeom-1.2.2/inst/geom2d/intersectEdges.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/intersectEdges.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/intersectLineCircle.m octave-matgeom-1.2.3/inst/geom2d/intersectLineCircle.m --- octave-matgeom-1.2.2/inst/geom2d/intersectLineCircle.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/intersectLineCircle.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function points = intersectLineCircle(line, circle) -%INTERSECTLINECIRCLE Intersection point(s) of a line and a circle. +% 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 @@ -64,7 +64,7 @@ % % ------ -% Author: David Legland, david.legland@inra.fr +% Author: David Legland, david.legland@inrae.fr % Author: JuanPi Carbajal % Created: 2011-01-14, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. @@ -90,9 +90,9 @@ dp = line(:, 1:2) - center; vl = line(:, 3:4); -% coefficient of second order equation +% coefficients of second order equation a = sum(line(:, 3:4).^2, 2); -b = 2*sum(dp .* vl, 2); +b = 2 * sum(dp .* vl, 2); c = sum(dp.^2, 2) - radius.^2; % discriminant @@ -103,11 +103,11 @@ valid = delta >= 0; if any(valid) - % compute roots + % 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 nCircles == 1 + if sum(valid) == 1 points = [... line(1:2) + u(:,1) .* line(3:4); ... line(1:2) + u(:,2) .* line(3:4)]; diff -Nru octave-matgeom-1.2.2/inst/geom2d/intersectLineEdge.m octave-matgeom-1.2.3/inst/geom2d/intersectLineEdge.m --- octave-matgeom-1.2.2/inst/geom2d/intersectLineEdge.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/intersectLineEdge.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/intersectLines.m octave-matgeom-1.2.3/inst/geom2d/intersectLines.m --- octave-matgeom-1.2.2/inst/geom2d/intersectLines.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/intersectLines.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isCounterClockwise.m octave-matgeom-1.2.3/inst/geom2d/isCounterClockwise.m --- octave-matgeom-1.2.2/inst/geom2d/isCounterClockwise.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isCounterClockwise.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function res = isCounterClockwise(p1, p2, p3, varargin) -%ISCOUNTERCLOCKWISE Compute relative orientation of 3 points. +% Compute the relative orientation of 3 points. % % CCW = isCounterClockwise(P1, P2, P3); % Computes the orientation of the 3 points. The returns is: @@ -55,16 +55,17 @@ % 0 % % See also -% points2d, isPointOnLine, isPointInTriangle +% points2d, isPointOnLine, isPointInTriangle, polygonArea % % References -% Algorithm adapated from Sedgewick's book. +% Algorithm adapated from Sedgewick's book. % + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2010-04-09 -% Copyright 2011 INRA - Cepia Software Platform. +% Copyright 2011 INRAE - Cepia Software Platform. % HISTORY diff -Nru octave-matgeom-1.2.2/inst/geom2d/isLeftOriented.m octave-matgeom-1.2.3/inst/geom2d/isLeftOriented.m --- octave-matgeom-1.2.2/inst/geom2d/isLeftOriented.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isLeftOriented.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isParallel.m octave-matgeom-1.2.3/inst/geom2d/isParallel.m --- octave-matgeom-1.2.2/inst/geom2d/isParallel.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isParallel.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPerpendicular.m octave-matgeom-1.2.3/inst/geom2d/isPerpendicular.m --- octave-matgeom-1.2.2/inst/geom2d/isPerpendicular.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPerpendicular.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPointInCircle.m octave-matgeom-1.2.3/inst/geom2d/isPointInCircle.m --- octave-matgeom-1.2.2/inst/geom2d/isPointInCircle.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPointInCircle.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPointInEllipse.m octave-matgeom-1.2.3/inst/geom2d/isPointInEllipse.m --- octave-matgeom-1.2.2/inst/geom2d/isPointInEllipse.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPointInEllipse.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPointInTriangle.m octave-matgeom-1.2.3/inst/geom2d/isPointInTriangle.m --- octave-matgeom-1.2.2/inst/geom2d/isPointInTriangle.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPointInTriangle.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPointOnCircle.m octave-matgeom-1.2.3/inst/geom2d/isPointOnCircle.m --- octave-matgeom-1.2.2/inst/geom2d/isPointOnCircle.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPointOnCircle.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPointOnEdge.m octave-matgeom-1.2.3/inst/geom2d/isPointOnEdge.m --- octave-matgeom-1.2.2/inst/geom2d/isPointOnEdge.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPointOnEdge.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPointOnLine.m octave-matgeom-1.2.3/inst/geom2d/isPointOnLine.m --- octave-matgeom-1.2.2/inst/geom2d/isPointOnLine.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPointOnLine.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/isPointOnRay.m octave-matgeom-1.2.3/inst/geom2d/isPointOnRay.m --- octave-matgeom-1.2.2/inst/geom2d/isPointOnRay.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/isPointOnRay.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/lineAngle.m octave-matgeom-1.2.3/inst/geom2d/lineAngle.m --- octave-matgeom-1.2.2/inst/geom2d/lineAngle.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/lineAngle.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,11 +26,11 @@ ## policies, either expressed or implied, of the copyright holders. function theta = lineAngle(varargin) -%LINEANGLE Computes angle between two straight lines. +%LINEANGLE Computes angle between two straight lines. % % A = lineAngle(LINE); % Returns the angle between horizontal, right-axis and the given line. -% Angle is fiven in radians, between 0 and 2*pi, in counter-clockwise +% Angle is given in radians, between 0 and 2*pi, in counter-clockwise % direction. % % A = lineAngle(LINE1, LINE2); diff -Nru octave-matgeom-1.2.2/inst/geom2d/lineFit.m octave-matgeom-1.2.3/inst/geom2d/lineFit.m --- octave-matgeom-1.2.2/inst/geom2d/lineFit.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/lineFit.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/linePosition.m octave-matgeom-1.2.3/inst/geom2d/linePosition.m --- octave-matgeom-1.2.2/inst/geom2d/linePosition.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/linePosition.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/lines2d.m octave-matgeom-1.2.3/inst/geom2d/lines2d.m --- octave-matgeom-1.2.2/inst/geom2d/lines2d.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/lines2d.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/lineToEdge.m octave-matgeom-1.2.3/inst/geom2d/lineToEdge.m --- octave-matgeom-1.2.2/inst/geom2d/lineToEdge.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/lineToEdge.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/medianLine.m octave-matgeom-1.2.3/inst/geom2d/medianLine.m --- octave-matgeom-1.2.2/inst/geom2d/medianLine.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/medianLine.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/mergeBoxes.m octave-matgeom-1.2.3/inst/geom2d/mergeBoxes.m --- octave-matgeom-1.2.2/inst/geom2d/mergeBoxes.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/mergeBoxes.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/mergeClosePoints.m octave-matgeom-1.2.3/inst/geom2d/mergeClosePoints.m --- octave-matgeom-1.2.2/inst/geom2d/mergeClosePoints.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/mergeClosePoints.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/midPoint.m octave-matgeom-1.2.3/inst/geom2d/midPoint.m --- octave-matgeom-1.2.2/inst/geom2d/midPoint.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/midPoint.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/minDistancePoints.m octave-matgeom-1.2.3/inst/geom2d/minDistancePoints.m --- octave-matgeom-1.2.2/inst/geom2d/minDistancePoints.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/minDistancePoints.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,10 +26,10 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = minDistancePoints(p1, varargin) -%MINDISTANCEPOINTS Minimal distance between several points. +% Minimal distance between several points. % % DIST = minDistancePoints(PTS) -% Returns the minimum distance between all couple of points in PTS. 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. % @@ -48,12 +48,12 @@ % to the biggest coordinate difference among dimensions. % % -% [DIST I J] = minDistancePoints(PTS) +% [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, ...) +% [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,:)); @@ -80,14 +80,26 @@ % 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, hausdorffDistance +% points2d, distancePoints, nndist, findClosestPoint, hausdorffDistance % % ------ % Author: David Legland -% e-mail: david.legland@inra.fr -% Copyright 2009 INRA - Cepia Software Platform. +% e-mail: david.legland@inrae.fr +% Copyright 2009 INRAE - Cepia Software Platform. % created the 15/06/2004. @@ -210,7 +222,7 @@ % [r, c] = ind2sub_tril (N, idx) % Convert a linear index to subscripts of a trinagular matrix. % -% An example of trinagular matrix linearly indexed follows +% An example of triangular matrix linearly indexed follows % % N = 4; % A = -repmat (1:N,N,1); diff -Nru octave-matgeom-1.2.2/inst/geom2d/nndist.m octave-matgeom-1.2.3/inst/geom2d/nndist.m --- octave-matgeom-1.2.2/inst/geom2d/nndist.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/nndist.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/normalizeAngle.m octave-matgeom-1.2.3/inst/geom2d/normalizeAngle.m --- octave-matgeom-1.2.2/inst/geom2d/normalizeAngle.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/normalizeAngle.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/normalize.m octave-matgeom-1.2.3/inst/geom2d/normalize.m --- octave-matgeom-1.2.2/inst/geom2d/normalize.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/normalize.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/normalizeVector.m octave-matgeom-1.2.3/inst/geom2d/normalizeVector.m --- octave-matgeom-1.2.2/inst/geom2d/normalizeVector.m 2019-12-04 12:15:22.943633901 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/normalizeVector.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,14 +26,17 @@ ## policies, either expressed or implied, of the copyright holders. function vn = normalizeVector(v) -%NORMALIZEVECTOR Normalize a vector to have norm equal to 1. +%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 MxN array, normalization is performed for each row of the -% array. +% 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]) @@ -44,11 +47,10 @@ % 1 % % See Also: -% vectors2d, vectorNorm -% +% vectors2d, vectorNorm % + % --------- -% % author : David Legland % INRA - TPV URPOI - BIA IMASTE % created the 29/11/2004. @@ -59,13 +61,8 @@ % 2009-05-22 rename as normalizeVector % 2011-01-20 use bsxfun -dim = size(v); - -if dim(1)==1 || dim(2)==1 - % in case of one vector, the norm is a scalar - vn = v / sqrt(sum(v.^2)); -else - % for several vectors, need to adapt size of norm +if ismatrix(v) vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); - %same as: vn = v./repmat(sqrt(sum(v.*v, 2)), [1 dim(2)]); +else + vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, ndims(v)))); end diff -Nru octave-matgeom-1.2.2/inst/geom2d/orientedBox.m octave-matgeom-1.2.3/inst/geom2d/orientedBox.m --- octave-matgeom-1.2.2/inst/geom2d/orientedBox.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/orientedBox.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/orientedBoxToPolygon.m octave-matgeom-1.2.3/inst/geom2d/orientedBoxToPolygon.m --- octave-matgeom-1.2.2/inst/geom2d/orientedBoxToPolygon.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/orientedBoxToPolygon.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/orthogonalLine.m octave-matgeom-1.2.3/inst/geom2d/orthogonalLine.m --- octave-matgeom-1.2.2/inst/geom2d/orthogonalLine.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/orthogonalLine.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/parallelEdge.m octave-matgeom-1.2.3/inst/geom2d/parallelEdge.m --- octave-matgeom-1.2.2/inst/geom2d/parallelEdge.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/parallelEdge.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/parallelLine.m octave-matgeom-1.2.3/inst/geom2d/parallelLine.m --- octave-matgeom-1.2.2/inst/geom2d/parallelLine.m 2019-12-04 12:15:22.951634057 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/parallelLine.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/pointOnLine.m octave-matgeom-1.2.3/inst/geom2d/pointOnLine.m --- octave-matgeom-1.2.2/inst/geom2d/pointOnLine.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/pointOnLine.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/points2d.m octave-matgeom-1.2.3/inst/geom2d/points2d.m --- octave-matgeom-1.2.2/inst/geom2d/points2d.m 2019-12-04 12:15:22.971634447 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/points2d.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/polarPoint.m octave-matgeom-1.2.3/inst/geom2d/polarPoint.m --- octave-matgeom-1.2.2/inst/geom2d/polarPoint.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/polarPoint.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/polynomialTransform2d.m octave-matgeom-1.2.3/inst/geom2d/polynomialTransform2d.m --- octave-matgeom-1.2.2/inst/geom2d/polynomialTransform2d.m 2019-12-04 12:15:22.959634213 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/polynomialTransform2d.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/principalAxes.m octave-matgeom-1.2.3/inst/geom2d/principalAxes.m --- octave-matgeom-1.2.2/inst/geom2d/principalAxes.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/principalAxes.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -46,14 +46,14 @@ % [center, rotMat] = principalAxes(pts); % % See also -% equivalentEllipse, equivalentEllipsoid +% equivalentEllipse, equivalentEllipsoid, principalAxesTransform % % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2019-08-12, using Matlab 9.6.0.1072779 (R2019a) -% Copyright 2019 INRA - Cepia Software Platform. +% Copyright 2019 INRAE - Cepia Software Platform. % number and dimension of points n = size(points, 1); diff -Nru octave-matgeom-1.2.2/inst/geom2d/principalAxesTransform.m octave-matgeom-1.2.3/inst/geom2d/principalAxesTransform.m --- octave-matgeom-1.2.2/inst/geom2d/principalAxesTransform.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/principalAxesTransform.m 2021-06-01 09:14:26.062813629 +0000 @@ -0,0 +1,69 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 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 diff -Nru octave-matgeom-1.2.2/inst/geom2d/private/parseThreePoints.m octave-matgeom-1.2.3/inst/geom2d/private/parseThreePoints.m --- octave-matgeom-1.2.2/inst/geom2d/private/parseThreePoints.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/private/parseThreePoints.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/projPointOnLine.m octave-matgeom-1.2.3/inst/geom2d/projPointOnLine.m --- octave-matgeom-1.2.2/inst/geom2d/projPointOnLine.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/projPointOnLine.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/radicalAxis.m octave-matgeom-1.2.3/inst/geom2d/radicalAxis.m --- octave-matgeom-1.2.2/inst/geom2d/radicalAxis.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/radicalAxis.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/randomPointInBox.m octave-matgeom-1.2.3/inst/geom2d/randomPointInBox.m --- octave-matgeom-1.2.2/inst/geom2d/randomPointInBox.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/randomPointInBox.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/rays2d.m octave-matgeom-1.2.3/inst/geom2d/rays2d.m --- octave-matgeom-1.2.2/inst/geom2d/rays2d.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/rays2d.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/rectToBox.m octave-matgeom-1.2.3/inst/geom2d/rectToBox.m --- octave-matgeom-1.2.2/inst/geom2d/rectToBox.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/rectToBox.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/rectToPolygon.m octave-matgeom-1.2.3/inst/geom2d/rectToPolygon.m --- octave-matgeom-1.2.2/inst/geom2d/rectToPolygon.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/rectToPolygon.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/registerICP.m octave-matgeom-1.2.3/inst/geom2d/registerICP.m --- octave-matgeom-1.2.2/inst/geom2d/registerICP.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/registerICP.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/reverseEdge.m octave-matgeom-1.2.3/inst/geom2d/reverseEdge.m --- octave-matgeom-1.2.2/inst/geom2d/reverseEdge.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/reverseEdge.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/reverseLine.m octave-matgeom-1.2.3/inst/geom2d/reverseLine.m --- octave-matgeom-1.2.2/inst/geom2d/reverseLine.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/reverseLine.m 2021-06-01 09:14:26.070813598 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/rotateVector.m octave-matgeom-1.2.3/inst/geom2d/rotateVector.m --- octave-matgeom-1.2.2/inst/geom2d/rotateVector.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/rotateVector.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/sedgewick_points.txt octave-matgeom-1.2.3/inst/geom2d/sedgewick_points.txt --- octave-matgeom-1.2.2/inst/geom2d/sedgewick_points.txt 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/sedgewick_points.txt 2021-06-01 09:14:25.998813871 +0000 @@ -0,0 +1,16 @@ +13 19 +21 11 +16 18 +14 13 +15 25 +18 21 +11 16 +17 14 +19 17 +24 15 +20 23 +26 24 +25 12 +23 26 +13 22 +22 20 diff -Nru octave-matgeom-1.2.2/inst/geom2d/squareGrid.m octave-matgeom-1.2.3/inst/geom2d/squareGrid.m --- octave-matgeom-1.2.2/inst/geom2d/squareGrid.m 2019-12-04 12:15:22.963634291 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/squareGrid.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/transformEdge.m octave-matgeom-1.2.3/inst/geom2d/transformEdge.m --- octave-matgeom-1.2.2/inst/geom2d/transformEdge.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/transformEdge.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/transformLine.m octave-matgeom-1.2.3/inst/geom2d/transformLine.m --- octave-matgeom-1.2.2/inst/geom2d/transformLine.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/transformLine.m 2021-06-01 09:14:26.066813615 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/transformPoint.m octave-matgeom-1.2.3/inst/geom2d/transformPoint.m --- octave-matgeom-1.2.2/inst/geom2d/transformPoint.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/transformPoint.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,30 +26,32 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = transformPoint(varargin) -%TRANSFORMPOINT Transform a point with an affine transform. +% Apply an affine transform to a point or a point set. % -% PT2 = transformPoint(PT1, TRANS); -% where PT1 has the form [xp yp], and TRANS is a [2*2], [2*3] or [3*3] -% matrix, returns the point transformed with affine transform TRANS. +% 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 TRANS can be one of : +% 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, TRANS); -% Also works when PTA is a [N*2] array of double. In this case, PT2 has -% the same size as PT1. -% -% [PX2 PY2] = transformPoint(PX1, PY1, TRANS); -% Also works when PX1 and PY1 are arrays the same size. The function -% transform each couple of (PX1, PY1), and return the result in -% (PX2, PY2), which is the same size as (PX1 PY1). +% 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 +% points2d, transforms2d, translation, rotation % + % --------- % author : David Legland % INRA - TPV URPOI - BIA IMASTE @@ -59,13 +61,13 @@ % HISTORY % 25/04/2005 : support for 2D arrays of points (px, py, trans). - -if length(varargin)==2 +% parse input arguments +if length(varargin) == 2 var = varargin{1}; px = var(:,1); py = var(:,2); trans = varargin{2}; -elseif length(varargin)==3 +elseif length(varargin) == 3 px = varargin{1}; py = varargin{2}; trans = varargin{3}; @@ -74,20 +76,20 @@ end -% compute position -px2 = px*trans(1,1) + py*trans(1,2); -py2 = px*trans(2,1) + py*trans(2,2); +% 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 +if size(trans, 2) > 2 px2 = px2 + trans(1,3); py2 = py2 + trans(2,3); end - -if nargout==0 || nargout==1 +% format output arguments +if nargout < 2 varargout{1} = [px2 py2]; -elseif nargout==2 +elseif nargout varargout{1} = px2; varargout{2} = py2; end diff -Nru octave-matgeom-1.2.2/inst/geom2d/transforms2d.m octave-matgeom-1.2.3/inst/geom2d/transforms2d.m --- octave-matgeom-1.2.2/inst/geom2d/transforms2d.m 2019-12-04 12:15:22.935633745 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/transforms2d.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function transforms2d(varargin) -%TRANSFORMS2D Description of functions operating on transforms. +%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. @@ -53,9 +53,10 @@ % createTranslation, createRotation, createRotation90, createScaling % createHomothecy, createLineReflection, createBasisTransform % transformPoint, transformVector, transformLine, transformEdge -% rotateVector, fitAffineTransform2d +% rotateVector, principalAxesTransform, fitAffineTransform2d % polynomialTransform2d, fitPolynomialTransform2d + % ------ % Author: David Legland % e-mail: david.legland@inra.fr diff -Nru octave-matgeom-1.2.2/inst/geom2d/transformVector.m octave-matgeom-1.2.3/inst/geom2d/transformVector.m --- octave-matgeom-1.2.2/inst/geom2d/transformVector.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/transformVector.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/triangleArea.m octave-matgeom-1.2.3/inst/geom2d/triangleArea.m --- octave-matgeom-1.2.2/inst/geom2d/triangleArea.m 2019-12-04 12:15:22.939633823 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/triangleArea.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/triangleGrid.m octave-matgeom-1.2.3/inst/geom2d/triangleGrid.m --- octave-matgeom-1.2.2/inst/geom2d/triangleGrid.m 2019-12-04 12:15:22.955634135 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/triangleGrid.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom2d/vectorAngle.m octave-matgeom-1.2.3/inst/geom2d/vectorAngle.m --- octave-matgeom-1.2.2/inst/geom2d/vectorAngle.m 2019-12-04 12:15:22.947633979 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/vectorAngle.m 2021-06-01 09:14:26.062813629 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,20 +26,19 @@ ## policies, either expressed or implied, of the copyright holders. function alpha = vectorAngle(v1, varargin) -%VECTORANGLE Angle of a vector, or between 2 vectors. +% Horizontal angle of a vector, or angle between 2 vectors. % % A = vectorAngle(V); -% Returns angle between Ox axis and vector direction, in Counter -% clockwise orientation. +% 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, and in radians. +% order, in radians. % -% A = vectorAngle(..., 'cutAngle', CUTANGLE); -% A = vectorAngle(..., CUTANGLE); % (deprecated syntax) -% Specifies convention for angle interval. CUTANGLE is the center of the +% 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. % @@ -55,11 +54,12 @@ % 270 % % See also: -% vectors2d, angles2d, normalizeAngle +% vectors2d, angles2d, normalizeAngle % + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2007-10-18 % Copyright 2011 INRA - Cepia Software Platform. @@ -72,14 +72,14 @@ % default values v2 = []; -cutAngle = pi; +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 - cutAngle = varargin{1}; + midAngle = varargin{1}; varargin(1) = []; elseif isnumeric(var) && size(var, 2) == 2 @@ -89,8 +89,8 @@ elseif ischar(var) && length(varargin) >= 2 % argument is option given as string + value - if strcmpi(var, 'cutAngle') - cutAngle = varargin{2}; + if strcmpi(var, 'cutAngle') || strcmpi(var, 'midAngle') + midAngle = varargin{2}; varargin(1:2) = []; else @@ -111,7 +111,7 @@ alpha = atan2(v1(:,2), v1(:,1)); % normalize within a 2*pi interval - alpha = normalizeAngle(alpha + 2*pi, cutAngle); + alpha = normalizeAngle(alpha + 2*pi, midAngle); return; end @@ -120,12 +120,12 @@ %% Case of two vectors % compute angle of each vector -alpha1 = atan2(v1(:,2), v1(:,1)); -alpha2 = atan2(v2(:,2), v2(:,1)); +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, cutAngle); +alpha = normalizeAngle(alpha + 2*pi, midAngle); diff -Nru octave-matgeom-1.2.2/inst/geom2d/vectorNorm.m octave-matgeom-1.2.3/inst/geom2d/vectorNorm.m --- octave-matgeom-1.2.2/inst/geom2d/vectorNorm.m 2019-12-04 12:15:22.967634369 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/vectorNorm.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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. +% Compute norm of a vector, or of a set of vectors. % % N = vectorNorm(V); % Returns the euclidean norm of vector V. @@ -50,10 +50,10 @@ % 10 % % See Also: -% vectors2d, vectorAngle +% vectors2d, vectorAngle % + % --------- -% % author : David Legland % INRA - TPV URPOI - BIA IMASTE % created the 21/02/2005. @@ -65,10 +65,7 @@ % 15/10/2008 add comments % 22/05/2009 rename as vectorNorm % 01/03/2010 fix bug for inf norm - - -% size of vector -dim = size(v); +% 03/01/2020 make it work for more dimensions % extract the type of norm to compute d = 2; @@ -78,30 +75,18 @@ if d==2 % euclidean norm: sum of squared coordinates, and take square root - if dim(1)==1 || dim(2)==1 - n = sqrt(sum(v.*v)); - else - n = sqrt(sum(v.*v, 2)); - end + n = sqrt(sum(v.*v, ndims(v))); + elseif d==1 % absolute norm: sum of absolute coordinates - if dim(1)==1 || dim(2)==1 - n = sum(abs(v)); - else - n = sum(abs(v), 2); - end + n = sum(abs(v), ndims(v)); + elseif d==inf % infinite norm: uses the maximal corodinate - if dim(1)==1 || dim(2)==1 - n = max(v); - else - n = max(v, [], 2); - end + n = max(v, [], ndims(v)); + else % Other norms, use explicit but slower expression - if dim(1)==1 || dim(2)==1 - n = power(sum(power(v, d)), 1/d); - else - n = power(sum(power(v, d), 2), 1/d); - end + n = power(sum(power(v, d), ndims(v)), 1/d); + end diff -Nru octave-matgeom-1.2.2/inst/geom2d/vectors2d.m octave-matgeom-1.2.3/inst/geom2d/vectors2d.m --- octave-matgeom-1.2.2/inst/geom2d/vectors2d.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom2d/vectors2d.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/anglePoints3d.m octave-matgeom-1.2.3/inst/geom3d/anglePoints3d.m --- octave-matgeom-1.2.2/inst/geom3d/anglePoints3d.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/anglePoints3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/angles3d.m octave-matgeom-1.2.3/inst/geom3d/angles3d.m --- octave-matgeom-1.2.2/inst/geom3d/angles3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/angles3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/angleSort3d.m octave-matgeom-1.2.3/inst/geom3d/angleSort3d.m --- octave-matgeom-1.2.2/inst/geom3d/angleSort3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/angleSort3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,14 +26,14 @@ ## 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. +%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 depend on plane orientation: points can be in reverse order -% compared to expected. The reference plane is computed besed on the 3 -% first points. +% 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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/boundingBox3d.m octave-matgeom-1.2.3/inst/geom3d/boundingBox3d.m --- octave-matgeom-1.2.2/inst/geom3d/boundingBox3d.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/boundingBox3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/box3dVolume.m octave-matgeom-1.2.3/inst/geom3d/box3dVolume.m --- octave-matgeom-1.2.2/inst/geom3d/box3dVolume.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/box3dVolume.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/boxes3d.m octave-matgeom-1.2.3/inst/geom3d/boxes3d.m --- octave-matgeom-1.2.2/inst/geom3d/boxes3d.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/boxes3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/cart2cyl.m octave-matgeom-1.2.3/inst/geom3d/cart2cyl.m --- octave-matgeom-1.2.2/inst/geom3d/cart2cyl.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/cart2cyl.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/cart2sph2d.m octave-matgeom-1.2.3/inst/geom3d/cart2sph2d.m --- octave-matgeom-1.2.2/inst/geom3d/cart2sph2d.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/cart2sph2d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/cart2sph2.m octave-matgeom-1.2.3/inst/geom3d/cart2sph2.m --- octave-matgeom-1.2.2/inst/geom3d/cart2sph2.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/cart2sph2.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/circle3dOrigin.m octave-matgeom-1.2.3/inst/geom3d/circle3dOrigin.m --- octave-matgeom-1.2.2/inst/geom3d/circle3dOrigin.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/circle3dOrigin.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/circle3dPoint.m octave-matgeom-1.2.3/inst/geom3d/circle3dPoint.m --- octave-matgeom-1.2.2/inst/geom3d/circle3dPoint.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/circle3dPoint.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/circle3dPosition.m octave-matgeom-1.2.3/inst/geom3d/circle3dPosition.m --- octave-matgeom-1.2.2/inst/geom3d/circle3dPosition.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/circle3dPosition.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/circles3d.m octave-matgeom-1.2.3/inst/geom3d/circles3d.m --- octave-matgeom-1.2.2/inst/geom3d/circles3d.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/circles3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function circles3d(varargin) -%CIRCLES3D Description of functions operating on 3D circles. +% 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. @@ -41,8 +41,9 @@ % circle3dOrigin, circle3dPosition, circle3dPoint, intersectPlaneSphere % drawCircle3d, drawCircleArc3d, drawEllipse3d % + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) % Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff -Nru octave-matgeom-1.2.2/inst/geom3d/clipConvexPolygon3dHP.m octave-matgeom-1.2.3/inst/geom3d/clipConvexPolygon3dHP.m --- octave-matgeom-1.2.2/inst/geom3d/clipConvexPolygon3dHP.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/clipConvexPolygon3dHP.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/clipEdge3d.m octave-matgeom-1.2.3/inst/geom3d/clipEdge3d.m --- octave-matgeom-1.2.2/inst/geom3d/clipEdge3d.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/clipEdge3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/clipLine3d.m octave-matgeom-1.2.3/inst/geom3d/clipLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/clipLine3d.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/clipLine3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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. +%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 @@ -39,7 +39,7 @@ % edge coresponding to each line in a N-by-6 array. % % See also: -% lines3d, edges3d, createLine3d +% lines3d, edges3d, createLine3d, clipRay3d % % --------- diff -Nru octave-matgeom-1.2.2/inst/geom3d/clipPoints3d.m octave-matgeom-1.2.3/inst/geom3d/clipPoints3d.m --- octave-matgeom-1.2.2/inst/geom3d/clipPoints3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/clipPoints3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/clipPolygon3dHP.m octave-matgeom-1.2.3/inst/geom3d/clipPolygon3dHP.m --- octave-matgeom-1.2.2/inst/geom3d/clipPolygon3dHP.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/clipPolygon3dHP.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/clipRay3d.m octave-matgeom-1.2.3/inst/geom3d/clipRay3d.m --- octave-matgeom-1.2.2/inst/geom3d/clipRay3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/clipRay3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -0,0 +1,152 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-05-25, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + +% 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; diff -Nru octave-matgeom-1.2.2/inst/geom3d/composeTransforms3d.m octave-matgeom-1.2.3/inst/geom3d/composeTransforms3d.m --- octave-matgeom-1.2.2/inst/geom3d/composeTransforms3d.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/composeTransforms3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/Contents.m octave-matgeom-1.2.3/inst/geom3d/Contents.m --- octave-matgeom-1.2.2/inst/geom3d/Contents.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/Contents.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -95,7 +95,6 @@ % % 3D Lines and Edges % lines3d - Description of functions operating on 3D lines. -% edges3d - Description of functions operating on 3D edges. % 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. @@ -103,19 +102,25 @@ % 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. -% distancePointEdge3d - Minimum distance between a 3D point and a 3D edge. % 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. -% midPoint3d - Middle point of two 3D points or of a 3D edge. +% 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. -% clipLine3d - Clip a line with a box and return an edge. +% distancePointEdge3d - Minimum distance between a 3D point and a 3D edge. % drawEdge3d - Draw 3D edge in the current axes. -% drawLine3d - Draw a 3D line clipped by 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. @@ -162,16 +167,19 @@ % 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. % 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. % % 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. @@ -184,7 +192,7 @@ % % Smooth surfaces % equivalentEllipsoid - Equivalent ellipsoid of a set of 3D points. -% fitEllipse3d - Fit an ellipse to a set of 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. @@ -196,6 +204,8 @@ % 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 @@ -210,7 +220,7 @@ % % Geometric transforms % transforms3d - Conventions for manipulating 3D affine transforms. -% fitAffineTransform3d - Fit an affine transform using two point sets. +% 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. @@ -225,6 +235,7 @@ % 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. % @@ -236,6 +247,8 @@ % 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: @@ -261,8 +274,8 @@ % Deprecated: % vectorCross3d - Vector cross product faster than inbuilt MATLAB cross. -% inertiaEllipsoid - Inertia ellipsoid of a set of 3D points. % Others + diff -Nru octave-matgeom-1.2.2/inst/geom3d/createBasisTransform3d.m octave-matgeom-1.2.3/inst/geom3d/createBasisTransform3d.m --- octave-matgeom-1.2.2/inst/geom3d/createBasisTransform3d.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createBasisTransform3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function transfo = createBasisTransform3d(source, target) -%CREATEBASISTRANSFORM3D Compute matrix for transforming a basis into another basis. +%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 @@ -46,10 +46,10 @@ % matrices. % % Example: -% % Calculate local plane coords. of a point given in global coords -% Plane = [10 10 10 1 0 0 0 1 0]; -% Tform = createBasisTransform3d('global', Plane); -% PT_IN_PLANE = transformPoint3d([3 8 2], Tform) +% % 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 % diff -Nru octave-matgeom-1.2.2/inst/geom3d/createEdge3d.m octave-matgeom-1.2.3/inst/geom3d/createEdge3d.m --- octave-matgeom-1.2.2/inst/geom3d/createEdge3d.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createEdge3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createLine3d.m octave-matgeom-1.2.3/inst/geom3d/createLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/createLine3d.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createLine3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createPlane.m octave-matgeom-1.2.3/inst/geom3d/createPlane.m --- octave-matgeom-1.2.2/inst/geom3d/createPlane.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createPlane.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRay3d.m octave-matgeom-1.2.3/inst/geom3d/createRay3d.m --- octave-matgeom-1.2.2/inst/geom3d/createRay3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRay3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -0,0 +1,48 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-05-25, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + +ray = [p1 (p2-p1)]; diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRotation3dLineAngle.m octave-matgeom-1.2.3/inst/geom3d/createRotation3dLineAngle.m --- octave-matgeom-1.2.2/inst/geom3d/createRotation3dLineAngle.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRotation3dLineAngle.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRotationAboutPoint3d.m octave-matgeom-1.2.3/inst/geom3d/createRotationAboutPoint3d.m --- octave-matgeom-1.2.2/inst/geom3d/createRotationAboutPoint3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRotationAboutPoint3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -0,0 +1,52 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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 +% Created: 2021-01-31 +% Copyright 2021 + +% Extract only the rotation +ROT = [ROT(1:3,1:3), [0 0 0]'; [0 0 0 1]]; + +TFM = createTranslation3d(point) * ROT * createTranslation3d(-point); + +end + + diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRotationOx.m octave-matgeom-1.2.3/inst/geom3d/createRotationOx.m --- octave-matgeom-1.2.2/inst/geom3d/createRotationOx.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRotationOx.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRotationOy.m octave-matgeom-1.2.3/inst/geom3d/createRotationOy.m --- octave-matgeom-1.2.2/inst/geom3d/createRotationOy.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRotationOy.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRotationOz.m octave-matgeom-1.2.3/inst/geom3d/createRotationOz.m --- octave-matgeom-1.2.2/inst/geom3d/createRotationOz.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRotationOz.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRotationVector3d.m octave-matgeom-1.2.3/inst/geom3d/createRotationVector3d.m --- octave-matgeom-1.2.2/inst/geom3d/createRotationVector3d.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRotationVector3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createRotationVectorPoint3d.m octave-matgeom-1.2.3/inst/geom3d/createRotationVectorPoint3d.m --- octave-matgeom-1.2.2/inst/geom3d/createRotationVectorPoint3d.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createRotationVectorPoint3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createScaling3d.m octave-matgeom-1.2.3/inst/geom3d/createScaling3d.m --- octave-matgeom-1.2.2/inst/geom3d/createScaling3d.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createScaling3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createSphere.m octave-matgeom-1.2.3/inst/geom3d/createSphere.m --- octave-matgeom-1.2.2/inst/geom3d/createSphere.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createSphere.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/createTranslation3d.m octave-matgeom-1.2.3/inst/geom3d/createTranslation3d.m --- octave-matgeom-1.2.2/inst/geom3d/createTranslation3d.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/createTranslation3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/crossProduct3d.m octave-matgeom-1.2.3/inst/geom3d/crossProduct3d.m --- octave-matgeom-1.2.2/inst/geom3d/crossProduct3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/crossProduct3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/cyl2cart.m octave-matgeom-1.2.3/inst/geom3d/cyl2cart.m --- octave-matgeom-1.2.2/inst/geom3d/cyl2cart.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/cyl2cart.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/cylinderSurfaceArea.m octave-matgeom-1.2.3/inst/geom3d/cylinderSurfaceArea.m --- octave-matgeom-1.2.2/inst/geom3d/cylinderSurfaceArea.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/cylinderSurfaceArea.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/dihedralAngle.m octave-matgeom-1.2.3/inst/geom3d/dihedralAngle.m --- octave-matgeom-1.2.2/inst/geom3d/dihedralAngle.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/dihedralAngle.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/distanceLines3d.m octave-matgeom-1.2.3/inst/geom3d/distanceLines3d.m --- octave-matgeom-1.2.2/inst/geom3d/distanceLines3d.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/distanceLines3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/distancePointEdge3d.m octave-matgeom-1.2.3/inst/geom3d/distancePointEdge3d.m --- octave-matgeom-1.2.2/inst/geom3d/distancePointEdge3d.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/distancePointEdge3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/distancePointLine3d.m octave-matgeom-1.2.3/inst/geom3d/distancePointLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/distancePointLine3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/distancePointLine3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/distancePointPlane.m octave-matgeom-1.2.3/inst/geom3d/distancePointPlane.m --- octave-matgeom-1.2.2/inst/geom3d/distancePointPlane.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/distancePointPlane.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/distancePoints3d.m octave-matgeom-1.2.3/inst/geom3d/distancePoints3d.m --- octave-matgeom-1.2.2/inst/geom3d/distancePoints3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/distancePoints3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/distancePointTriangle3d.m octave-matgeom-1.2.3/inst/geom3d/distancePointTriangle3d.m --- octave-matgeom-1.2.2/inst/geom3d/distancePointTriangle3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/distancePointTriangle3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawAngleBetweenVectors3d.m octave-matgeom-1.2.3/inst/geom3d/drawAngleBetweenVectors3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawAngleBetweenVectors3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawAngleBetweenVectors3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -0,0 +1,99 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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(o, v1, v2, r, 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 +% Created: 2020-02-02 +% Copyright 2020 + +% parse axis handle +hAx = gca; +if isAxisHandle(o) + hAx = o; + o = v1; + v1 = v2; + v2 = r; + r = varargin{1}; + varargin(1) = []; +end + +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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawArrow3d.m octave-matgeom-1.2.3/inst/geom3d/drawArrow3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawArrow3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawArrow3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -0,0 +1,215 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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(pos, vec, 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.01 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 +% History: +% Created: 2006-09-14 by Shawn Arseneau +% Updated: 2020-02-08 by oqilipo + +% Check if first argument is an axes handle +if numel(pos) == 1 && ishghandle(pos, 'axes') + hAx = pos; + pos=vec; + vec=varargin{1}; + varargin(1)=[]; +else + hAx = gca; +end + +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.1}); +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; + +%% Loop through all arrows and plot in 3D +hold(hAx,'on') +qHandle=gobjects(numArrows,1); +for i=1:numArrows + qHandle(i) = drawSingleVector3d(hAx, pos(i,:), vec(i,:), color(i,:), ... + stemRatio(i),arrowRadius(i),drawOptions); +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 + +newEll = transformPoint3d([CX(:), CY(:), CZ(:)],createRotationVector3d([1 0 0],[0 0 -1])); +CX = reshape(newEll(:,1), row, col); +CY = reshape(newEll(:,2), row, col); +CZ = reshape(newEll(:,3), row, col); + +[row, col] = size(CX); +newEll = transformPoint3d([CX(:), CY(:), CZ(:)],createRotationVector3d([1 0 0],vec)); +stemX = reshape(newEll(:,1), row, col); +stemY = reshape(newEll(:,2), row, col); +stemZ = reshape(newEll(:,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); +newEll = transformPoint3d([coneX(:), coneY(:), coneZ(:)],createRotationVector3d([1 0 0],[0 0 -1])); +coneX = reshape(newEll(:,1), row, col); +coneY = reshape(newEll(:,2), row, col); +coneZ = reshape(newEll(:,3), row, col); + +newEll = transformPoint3d([coneX(:), coneY(:), coneZ(:)],createRotationVector3d([1 0 0],vec)); +headX = reshape(newEll(:,1), row, col); +headY = reshape(newEll(:,2), row, col); +headZ = reshape(newEll(:,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); +hold(hAx,'on') +hHead = patch(hAx, surf2patch(headX, headY, headZ), 'FaceColor', color, 'EdgeColor', 'none', drawOptions); +arrowHandle = hggroup(hAx); +set([hStem, hHead],'Parent',arrowHandle); + +end diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawAxis3d.m octave-matgeom-1.2.3/inst/geom3d/drawAxis3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawAxis3d.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawAxis3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,23 +25,30 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function drawAxis3d(varargin) -%DRAWAXIS3D Draw a coordinate system and an origin. +function varargout = drawAxis3d(varargin) +%DRAWAXIS3D Draw a coordinate system and an origin. % % drawAxis3d -% Adds 3 cylinders to the current axis, corresponding to the directions -% of the 3 basis vectors Ox, Oy and Oz. +% 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 -% drawAxis +% drawAxis3d % % figure; -% drawAxis(20, 1); +% drawAxis3d(20, 1); +% view([135,15]); lighting('phong'); camlight('head'); axis('equal') +% xlabel X; ylabel Y; zlabel Z % % See also % drawAxisCube @@ -52,28 +59,46 @@ % Created: 2007-08-14, using Matlab 7.4.0.287 (R2007a) % Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. -% geometrical data -origin = [0 0 0]; -v1 = [1 0 0]; -v2 = [0 1 0]; -v3 = [0 0 1]; - -% default parameters -L = 1; -r = L/10; - -% extract parameters from input +% Check if axes handle is specified +hAx = gca; if ~isempty(varargin) - L = varargin{1}; + if isAxisHandle(varargin{1}) + hAx = varargin{1}; + varargin(1)=[]; + end end -if length(varargin)>1 - r = varargin{2}; + +% 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 3 cylinders and a ball +% draw three arrows and a ball hold on; -drawCylinder([origin origin+v1*L r], 16, 'facecolor', 'r', 'edgecolor', 'none'); -drawCylinder([origin origin+v2*L r], 16, 'facecolor', 'g', 'edgecolor', 'none'); -drawCylinder([origin origin+v3*L r], 16, 'facecolor', 'b', 'edgecolor', 'none'); -drawSphere([origin 2*r], 'faceColor', 'black'); +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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawAxisCube.m octave-matgeom-1.2.3/inst/geom3d/drawAxisCube.m --- octave-matgeom-1.2.2/inst/geom3d/drawAxisCube.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawAxisCube.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawBox3d.m octave-matgeom-1.2.3/inst/geom3d/drawBox3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawBox3d.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawBox3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawBox3d(box, varargin) -%DRAWBOX3D Draw a 3D box defined by coordinate extents. +% Draw a 3D box defined by coordinate extents. % % drawBox3d(BOX); % Draw a box defined by its coordinate extents: @@ -45,20 +45,25 @@ % view(3) % % See Also: -% boxes3d, boundingBox3d -% -% --------- -% author : David Legland -% INRA - TPV URPOI - BIA IMASTE -% created the 10/12/2003. +% boxes3d, boundingBox3d % -% HISTORY -% 2010-02-22 creation +% --------- +% Author: David Legland +% e-mail: david.legland@inrae.fr +% INRA - TPV URPOI - BIA IMASTE +% created the 22/02/2010. +% +% 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{:}); -% default values +% box limits xmin = box(:,1); xmax = box(:,2); ymin = box(:,3); @@ -71,26 +76,26 @@ gh=zeros(nBoxes,1); for i=1:nBoxes % lower face (z=zmin) - sh(1)=drawEdge3d([xmin(i) ymin(i) zmin(i) xmax(i) ymin(i) zmin(i)], varargin{:}); - sh(2)=drawEdge3d([xmin(i) ymin(i) zmin(i) xmin(i) ymax(i) zmin(i)], varargin{:}); - sh(3)=drawEdge3d([xmax(i) ymin(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); - sh(4)=drawEdge3d([xmin(i) ymax(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); + 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([xmin(i) ymin(i) zmin(i) xmin(i) ymin(i) zmax(i)], varargin{:}); - sh(6)=drawEdge3d([xmax(i) ymin(i) zmin(i) xmax(i) ymin(i) zmax(i)], varargin{:}); - sh(7)=drawEdge3d([xmin(i) ymin(i) zmax(i) xmax(i) ymin(i) zmax(i)], varargin{:}); + 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([xmin(i) ymax(i) zmin(i) xmin(i) ymax(i) zmax(i)], varargin{:}); - sh(9)=drawEdge3d([xmin(i) ymin(i) zmax(i) xmin(i) ymax(i) zmax(i)], varargin{:}); + 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([xmin(i) ymax(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); - sh(11)=drawEdge3d([xmax(i) ymax(i) zmin(i) xmax(i) ymax(i) zmax(i)], varargin{:}); - sh(12)=drawEdge3d([xmax(i) ymin(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); + 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; + gh(i) = hggroup(hAx); set(sh,'Parent',gh(i)) end diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawCapsule.m octave-matgeom-1.2.3/inst/geom3d/drawCapsule.m --- octave-matgeom-1.2.2/inst/geom3d/drawCapsule.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawCapsule.m 2021-06-01 09:14:26.034813734 +0000 @@ -0,0 +1,200 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% created the 27/07/2013 +% + +% HISTORY +% 2013-07-27 initial version as copy of drawCylinder +% 2020-05-18 changes based on current version of geom3d + + +%% Input argument processing + +% parse axis handle +if isAxisHandle(varargin{1}) + hAx = varargin{1}; + varargin(1) = []; +else + hAx = gca; +end + +% 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 + +hold 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{:}); + +% return handles +if nargout == 1 + varargout{1} = [h1, h2, h3]; +end diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawCircle3d.m octave-matgeom-1.2.3/inst/geom3d/drawCircle3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawCircle3d.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawCircle3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawCircle3d(varargin) -%DRAWCIRCLE3D Draw a 3D circle. +% Draw a 3D circle. % % Possible calls for the function: % drawCircle3d([XC YC ZC R THETA PHI]) @@ -73,11 +73,12 @@ % axis equal; % % See also: -% circles3d, drawCircleArc3d, drawEllipse3d, drawSphere +% circles3d, drawCircleArc3d, drawEllipse3d, drawSphere + % % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inra.fr % Created: 2005-02-17 % Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). @@ -101,6 +102,12 @@ % drawCircle3d(XC, YC, ZC, R, THETA, PHI) 6 % drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) 7 +% parse axis handle +hAx = gca; +if isAxisHandle(varargin{1}) + hAx = varargin{1}; + varargin(1) = []; +end % extract drawing options if verLessThan('matlab', '7.8') @@ -251,7 +258,7 @@ circle = transformPoint3d(circle0, trans); % draw the curve of circle points - h(i) = drawPolyline3d(circle, options{:}); + h(i) = drawPolyline3d(hAx, circle, options{:}); end diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawCircleArc3d.m octave-matgeom-1.2.3/inst/geom3d/drawCircleArc3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawCircleArc3d.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawCircleArc3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawCircleArc3d(arc, varargin) -%DRAWCIRCLEARC3D Draw a 3D circle arc. +% Draw a 3D circle arc. % % drawCircleArc3d([XC YC ZC R THETA PHI PSI START EXTENT]) % [XC YC ZC] : coordinate of arc center @@ -39,13 +39,14 @@ % Drawing options can be specified, as for the plot command. % % See also -% angles3, circles3d, drawCircle3d, drawCircleArc +% angles3d, circles3d, drawCircle3d, drawCircleArc % -% -% --------- -% author : David Legland -% INRA - TPV URPOI - BIA IMASTE -% created the 21/02/2005 + +% ------ +% Author: David Legland +% e-mail: david.legland@inrae.fr +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005 % % HISTORY @@ -53,11 +54,18 @@ % 2010-03-08 use drawPolyline3d % 2011-06-21 use angles in degrees +% parse axis handle +hAx = gca; +if isAxisHandle(arc) + hAx = arc; + arc = varargin{1}; + varargin(1) = []; +end if iscell(arc) h = []; for i = 1:length(arc) - h = [h drawCircleArc3d(arc{i}, varargin{:})]; %#ok + h = [h drawCircleArc3d(hAx, arc{i}, varargin{:})]; %#ok end if nargout > 0 varargout = {h}; @@ -68,7 +76,7 @@ if size(arc, 1) > 1 h = []; for i = 1:size(arc, 1) - h = [h drawCircleArc3d(arc(i,:), varargin{:})]; %#ok + h = [h drawCircleArc3d(hAx, arc(i,:), varargin{:})]; %#ok end if nargout > 0 varargout = {h}; @@ -108,7 +116,7 @@ curve = transformPoint3d(curve, trans); % draw the curve with specified options -h = drawPolyline3d(curve, varargin{:}); +h = drawPolyline3d(hAx, curve, varargin{:}); if nargout > 0 varargout = {h}; diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawCube.m octave-matgeom-1.2.3/inst/geom3d/drawCube.m --- octave-matgeom-1.2.2/inst/geom3d/drawCube.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawCube.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawCube(cube, varargin) -%DRAWCUBE Draw a 3D centered cube, eventually rotated. +% Draw a 3D centered cube, eventually rotated. % % drawCube(CUBE) % Displays a 3D cube on current axis. CUBE is given by: @@ -34,7 +34,7 @@ % 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 longitude, and PSI is the rotation angle +% 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 @@ -57,37 +57,48 @@ % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. +% Parse and check inputs +hAx = gca; +if nargin > 0 + if isAxisHandle(cube) + hAx = cube; + if ~isempty(varargin) + cube = varargin{1}; + varargin(1) = []; + end + end +end % default values +xc = 0; +yc = 0; +zc = 0; +a = 1; theta = 0; phi = 0; psi = 0; %% Parses the input -if nargin == 0 - % no input: assumes cube with default shape - xc = 0; yc = 0; zc = 0; - a = 1; - -else +if nargin > 0 && ~isAxisHandle(cube) % one argument: parses elements xc = cube(:,1); yc = cube(:,2); zc = cube(:,3); - a = cube(:,4); - + % parses side length if present + if size(cube, 2) >= 4 + a = cube(:,4); + end % parses orientation if present - k = pi / 180; if size(cube, 2) >= 6 - theta = cube(:,5) * k; - phi = cube(:,6) * k; + theta = deg2rad(cube(:,5)); + phi = deg2rad(cube(:,6)); end if size(cube, 2) >= 7 - psi = cube(:,7) * k; + psi = deg2rad(cube(:,7)); end end @@ -109,22 +120,22 @@ trans = tra * rot3 * rot2 * rot1 * sca; % transform mesh vertices -[x, y, z] = transformPoint3d(v, trans); +v = transformPoint3d(v, trans); %% Process output if nargout == 0 % no output: draw the cube - drawMesh([x y z], f, varargin{:}); + drawMesh(hAx, v, f, varargin{:}); elseif nargout == 1 % one output: draw the cube and return handle - varargout{1} = drawMesh([x y z], f, varargin{:}); + varargout{1} = drawMesh(hAx, v, f, varargin{:}); elseif nargout == 3 % 3 outputs: return computed coordinates - varargout{1} = x; - varargout{2} = y; - varargout{3} = z; + varargout{1} = v(:,1); + varargout{2} = v(:,2); + varargout{3} = v(:,3); end diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawCuboid.m octave-matgeom-1.2.3/inst/geom3d/drawCuboid.m --- octave-matgeom-1.2.2/inst/geom3d/drawCuboid.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawCuboid.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawCuboid(cuboid, varargin) -%DRAWCUBOID Draw a 3D cuboid, eventually rotated. +% Draw a 3D cuboid, eventually rotated. % % drawCuboid(CUBOID) % Displays a 3D cuboid on current axis. CUBOID is given by: @@ -55,12 +55,12 @@ % set(gcf, 'renderer', 'opengl') % % See also -% meshes3d, polyhedra, createCube, drawEllipsoid, drawCube +% meshes3d, polyhedra, createCube, drawEllipsoid, drawCube % % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawCylinder.m octave-matgeom-1.2.3/inst/geom3d/drawCylinder.m --- octave-matgeom-1.2.2/inst/geom3d/drawCylinder.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawCylinder.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,20 +25,22 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function varargout = drawCylinder(cyl, varargin) -%DRAWCYLINDER Draw a cylinder. +function varargout = drawCylinder(varargin) +% Draw a cylinder. % % drawCylinder(CYL) -% where CYL is a cylinder defined by [x1 y1 z1 x2 y2 z2 r]: -% [x1 y2 z1] are coordinates of starting point, [x2 y2 z2] are -% coordinates of ending point, and R is the radius of the cylinder, -% draws the corresponding cylinder on the current axis. +% 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 discretisation of angle. Default value is 32. +% Uses N points for discretizating the circles of the cylinder. Default +% value is 32. % % drawCylinder(..., OPT) -% with OPT = 'open' (default) or 'closed', specify if bases of the +% with OPT = 'open' (default) or 'closed', specify if the bases of the % cylinder should be drawn. % % drawCylinder(..., 'FaceColor', COLOR) @@ -49,38 +51,51 @@ % 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. +% Returns a handle to the patch representing the cylinder. % % -% Example: -% figure;drawCylinder([0 0 0 10 20 30 5]); +% Examples: +% % basic example +% figure; drawCylinder([0 0 0 10 20 30 5]); % -% figure;drawCylinder([0 0 0 10 20 30 5], 'open'); +% % draw hollow cylinders +% figure; drawCylinder([0 0 0 10 20 30 5], 'open'); % -% figure;drawCylinder([0 0 0 10 20 30 5], 'FaceColor', 'r'); +% % change cylinder color +% figure; drawCylinder([0 0 0 10 20 30 5], 'FaceColor', 'r'); % -% figure; -% h = drawCylinder([0 0 0 10 20 30 5]); -% set(h, 'facecolor', 'b'); +% % 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 = [30 30 30]; -% p1 = [90 30 30]; -% p2 = [30 90 30]; -% p3 = [30 30 90]; -% figure; -% drawCylinder([p0 p1 25], 'FaceColor', 'r'); -% hold on -% drawCylinder([p0 p2 25], 'FaceColor', 'g'); -% drawCylinder([p0 p3 25], 'FaceColor', 'b'); +% 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]) +% 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 +% cylinderMesh, drawEllipseCylinder, drawSphere, drawLine3d, surf +% intersectLineCylinder, cylinderSurfaceArea % % --------- @@ -99,20 +114,42 @@ %% Input argument processing +% parse axis handle +if isAxisHandle(varargin{1}) + hAx = varargin{1}; + varargin(1) = []; +else + hAx = gca; +end + +% input argument representing cylinders +cyl = varargin{1}; +varargin(1) = []; + +% process the case of multiple cylinders if iscell(cyl) - res = zeros(length(cyl), 1); + hCyls = gobjects(length(cyl), 1); for i = 1:length(cyl) - res(i) = drawCylinder(cyl{i}, varargin{:}); + 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} = res; + varargout{1} = hCyls; end return; end % default values -N = 128; +N = 32; closed = true; % check number of discretization steps @@ -139,7 +176,7 @@ end faceColor = 'g'; -ind = find(strcmpi(varargin, 'facecolor'), 1, 'last'); +ind = find(strcmpi(varargin, 'FaceColor'), 1, 'last'); if ~isempty(ind) faceColor = varargin{ind+1}; varargin(ind:ind+1) = []; @@ -147,7 +184,7 @@ % extract transparency alpha = 1; -ind = find(strcmpi(varargin, 'faceAlpha'), 1, 'last'); +ind = find(strcmpi(varargin, 'FaceAlpha'), 1, 'last'); if ~isempty(ind) alpha = varargin{ind+1}; varargin(ind:ind+1) = []; @@ -188,15 +225,18 @@ %% Display cylinder mesh % plot the cylinder as a surface -hSurf = surf(x2, y2, z2, varargin{:}); +hCyl(1) = surf(hAx, x2, y2, z2, varargin{:}); % eventually plot the ends of the cylinder if closed - patch(x2(1,:)', y2(1,:)', z2(1,:)', faceColor, 'edgeColor', 'none', 'FaceAlpha', alpha); - patch(x2(2,:)', y2(2,:)', z2(2,:)', faceColor, 'edgeColor', 'none', 'FaceAlpha', alpha); + 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} = hSurf; + varargout{1} = hCyl; end diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawDome.m octave-matgeom-1.2.3/inst/geom3d/drawDome.m --- octave-matgeom-1.2.2/inst/geom3d/drawDome.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawDome.m 2021-06-01 09:14:26.038813720 +0000 @@ -0,0 +1,234 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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. +% +% drawdrawDome(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] = drawdrawDome(...) +% 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 +% created the 27/07/2013 +% + +% HISTORY +% 2013-07-27 initial version as copy of drawSphere with a few changes +% 2020-05-18 changes based on current version of geom3d + +% Check if axes handle is specified +if isAxisHandle(varargin{1}) + hAx = varargin{1}; + varargin(1)=[]; +elseif nargout ~= 3 + hAx = gca; +end + +% 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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawEdge3d.m octave-matgeom-1.2.3/inst/geom3d/drawEdge3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawEdge3d.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawEdge3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawEdge3d(varargin) -%DRAWEDGE3D Draw 3D edge in the current axes. +%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. @@ -35,6 +35,17 @@ % % 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 % @@ -48,7 +59,7 @@ % 15/12/2009 "reprecate", and add processing of input arguments % Parse and check inputs -if numel(varargin{1}) == 1 && ishandle(varargin{1}) +if isAxisHandle(varargin{1}) hAx = varargin{1}; varargin(1) = []; else @@ -60,30 +71,42 @@ if nCol == 6 % all parameters in a single array edges = varargin{1}; - options = varargin(2:end); - + varargin(1) = []; elseif nCol == 3 - % parameters are two points, or two arrays of points, of size N*3. - edges = [varargin{1} varargin{2}]; - options = varargin(3:end); - + 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}]; - options = varargin(7:end); + 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(:, 1) edges(:, 4)]', ... - [edges(:, 2) edges(:, 5)]', ... - [edges(:, 3) edges(:, 6)]', 'color', 'b', ... + [edges(inds, 1) edges(inds, 4)]', ... + [edges(inds, 2) edges(inds, 5)]', ... + [edges(inds, 3) edges(inds, 6)]', varargin{:}, ... 'Parent', hAx); - -% apply optional drawing style -if ~isempty(options) - set(h, options{:}); -end % return handle to created Edges if nargout > 0 diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawEllipse3d.m octave-matgeom-1.2.3/inst/geom3d/drawEllipse3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawEllipse3d.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawEllipse3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawEllipseCylinder.m octave-matgeom-1.2.3/inst/geom3d/drawEllipseCylinder.m --- octave-matgeom-1.2.2/inst/geom3d/drawEllipseCylinder.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawEllipseCylinder.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipseCylinder(cyl, varargin) -%DRAWELLIPSECYLINDER Draw a cylinder with ellipse cross-section. +%DRAWELLIPSECYLINDER Draw a cylinder with ellipse cross-section. % % drawEllipseCylinder(CYL) % draws the cylinder CYL on the current axis. @@ -54,17 +54,17 @@ % % % Example: -% figure;drawEllipseCylinder([0 0 0 10 20 30 5]); +% figure; drawEllipseCylinder([0 0 0 10 20 30 5 2]); % -% figure;drawEllipseCylinder([0 0 0 10 20 30 5], 'open'); +% figure; drawEllipseCylinder([0 0 0 10 20 30 5 2], 'open'); % -% figure;drawEllipseCylinder([0 0 0 10 20 30 5], 'FaceColor', 'r'); +% figure; drawEllipseCylinder([0 0 0 10 20 30 5 2], 'FaceColor', 'r'); % -% figure; -% h = drawEllipseCylinder([0 0 0 10 20 30 5]); -% set(h, 'facecolor', 'b'); +% figure; +% h = drawEllipseCylinder([0 0 0 10 20 30 5 2]); +% set(h, 'facecolor', 'b'); % -% % Draw three mutually intersecting elliptic cylinders +% % Draw three mutually intersecting elliptic cylinders % p1 = [30 0 0]; % p2 = [0 30 0]; % p3 = [0 0 30]; diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawEllipsoid.m octave-matgeom-1.2.3/inst/geom3d/drawEllipsoid.m --- octave-matgeom-1.2.2/inst/geom3d/drawEllipsoid.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawEllipsoid.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawEllipsoid(elli, varargin) -%DRAWELLIPSOID Draw a 3D ellipsoid. +%DRAWELLIPSOID Draw a 3D ellipsoid. % % drawEllipsoid(ELLI) % Displays a 3D ellipsoid on current axis. ELLI is given by: @@ -46,18 +46,19 @@ % axis equal; % % figure; hold on; -% elli = [[10 20 30 50 30 10 5 10 0]; +% 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, inertiaEllipsoid, ellipsoid, drawTorus, drawCuboid +% spheres, drawSphere, equivalentEllipsoid, ellipsoid, drawTorus, +% drawCuboid % % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawGrid3d.m octave-matgeom-1.2.3/inst/geom3d/drawGrid3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawGrid3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawGrid3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawLabels3d.m octave-matgeom-1.2.3/inst/geom3d/drawLabels3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawLabels3d.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawLabels3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -61,11 +61,11 @@ end % extract handle of axis to draw on -if isscalar(varargin{1}) && ishandle(varargin{1}) - ax = varargin{1}; +if isAxisHandle(varargin{1}) + axH = varargin{1}; varargin(1) = []; else - ax = gca; + axH = gca; end % process input parameters @@ -98,7 +98,10 @@ % parse format for displaying numeric values format = '%.2f'; if ~isempty(varargin) - format = varargin{1}; + 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); @@ -122,7 +125,7 @@ %% display the text -h = text(px, py, pz, labels, 'parent', ax); +h = text(axH, px, py, pz, labels, varargin{:}); %% format output diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawLine3d.m octave-matgeom-1.2.3/inst/geom3d/drawLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawLine3d.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawLine3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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 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. @@ -52,7 +52,7 @@ % % % See also: -% lines3d, createLine3d, clipLine3d +% lines3d, createLine3d, clipLine3d, drawRay3d, drawEdge3d % % --------- @@ -69,7 +69,7 @@ parseDrawInput(lin, isLine3d, 'line', defOpts, varargin{:}); % extract limits of the bounding box -box = [get(gca, 'xlim') get(gca, 'ylim') get(gca, 'zlim')]; +box = [get(hAx, 'xlim') get(hAx, 'ylim') get(hAx, 'zlim')]; % clip the line with the limits of the current axis edge = clipLine3d(lin, box); diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawPartialPatch.m octave-matgeom-1.2.3/inst/geom3d/drawPartialPatch.m --- octave-matgeom-1.2.2/inst/geom3d/drawPartialPatch.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawPartialPatch.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawPlane3d.m octave-matgeom-1.2.3/inst/geom3d/drawPlane3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawPlane3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawPlane3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawPlatform.m octave-matgeom-1.2.3/inst/geom3d/drawPlatform.m --- octave-matgeom-1.2.2/inst/geom3d/drawPlatform.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawPlatform.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -61,7 +61,7 @@ %% Parse inputs % extract axis handle -if numel(plane) == 1 && ishandle(plane) +if isAxisHandle(plane) hAx = plane; plane = siz; siz = varargin{1}; diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawPoint3d.m octave-matgeom-1.2.3/inst/geom3d/drawPoint3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawPoint3d.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawPoint3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -65,7 +65,7 @@ % 12/01/2018 added axes handle input % -if numel(varargin{1}) == 1 && ishghandle(varargin{1}, 'axes') +if isAxisHandle(varargin{1}) hAx = varargin{1}; varargin(1)=[]; else diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawPolygon3d.m octave-matgeom-1.2.3/inst/geom3d/drawPolygon3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawPolygon3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawPolygon3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawPolyline3d.m octave-matgeom-1.2.3/inst/geom3d/drawPolyline3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawPolyline3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawPolyline3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -58,26 +58,30 @@ % polygons3d, drawPolygon3d, fillPolygon3d % -% --------- -% author : David Legland +% --------- +% Author : David Legland % e-mail: david.legland@inra.fr -% INRA - TPV URPOI - BIA IMASTE -% created the 18/02/2005. -% +% Created: 2005-02-15 +% Copyright 2005 INRA - TPV URPOI - BIA IMASTE % HISTORY -% 2010-03-08 rename as drawPolyline3d +% 2010-03-08 rename to drawPolyline3d %% Process input arguments +hAx = gca; +if isAxisHandle(varargin{1}) + hAx = varargin{1}; + varargin(1) = []; +end % check case we want to draw several curves, stored in a cell array var = varargin{1}; if iscell(var) hold on; - h = []; + h = zeros(length(var(:)), 1); for i = 1:length(var(:)) - h = [h; drawPolyline3d(var{i}, varargin{2:end})]; %#ok + h(i) = drawPolyline3d(hAx, var{i}, varargin{2:end}); end if nargout > 0 varargout = {h}; @@ -94,16 +98,22 @@ if length(varargin) < 3 error('geom3d:drawPolyline3d:Wrong number of arguments in drawPolyline3d'); end - py = varargin{2}; - pz = varargin{3}; - varargin = varargin(4: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 = varargin(2:end); + varargin(1) = []; end % check if curve is closed or open (default is open) @@ -139,7 +149,7 @@ pz = [pz(:); pz(1)]; end -h = plot3(px, py, pz, varargin{:}); +h = plot3(hAx, px, py, pz, varargin{:}); if nargout > 0 varargout = {h}; diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawRay3d.m octave-matgeom-1.2.3/inst/geom3d/drawRay3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawRay3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawRay3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -0,0 +1,96 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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(ray, varargin) +% 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 handle on line object +% +% See also: +% rays2d, drawLine +% +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-05-25, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + +% extract handle of axis to draw in +if isAxisHandle(ray) + hAx = ray; + ray = varargin{1}; + varargin(1) = []; +else + hAx = gca; +end + +% 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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawSphere.m octave-matgeom-1.2.3/inst/geom3d/drawSphere.m --- octave-matgeom-1.2.2/inst/geom3d/drawSphere.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawSphere.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -96,10 +96,10 @@ % 2010-11-08 code cleanup, add doc % Check if axes handle is specified -if numel(varargin{1}) == 1 && ishghandle(varargin{1}, 'axes') +if isAxisHandle(varargin{1}) hAx = varargin{1}; varargin(1)=[]; -else +elseif nargout ~= 3 hAx = gca; end diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawSphericalEdge.m octave-matgeom-1.2.3/inst/geom3d/drawSphericalEdge.m --- octave-matgeom-1.2.2/inst/geom3d/drawSphericalEdge.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawSphericalEdge.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawSphericalPolygon.m octave-matgeom-1.2.3/inst/geom3d/drawSphericalPolygon.m --- octave-matgeom-1.2.2/inst/geom3d/drawSphericalPolygon.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawSphericalPolygon.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawSphericalTriangle.m octave-matgeom-1.2.3/inst/geom3d/drawSphericalTriangle.m --- octave-matgeom-1.2.2/inst/geom3d/drawSphericalTriangle.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawSphericalTriangle.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawSurfPatch.m octave-matgeom-1.2.3/inst/geom3d/drawSurfPatch.m --- octave-matgeom-1.2.2/inst/geom3d/drawSurfPatch.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawSurfPatch.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawTorus.m octave-matgeom-1.2.3/inst/geom3d/drawTorus.m --- octave-matgeom-1.2.2/inst/geom3d/drawTorus.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawTorus.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/drawVector3d.m octave-matgeom-1.2.3/inst/geom3d/drawVector3d.m --- octave-matgeom-1.2.2/inst/geom3d/drawVector3d.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/drawVector3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawVector3d(pos, vect, varargin) -%DRAWVECTOR3D Draw vector at a given position. +%DRAWVECTOR3D Draw vector at a given position. % % drawVector3d(POS, VECT) % Draws the vector VECT starting at the position POS. Both VECT and POS @@ -53,7 +53,16 @@ % Created: 2011-12-19, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. -h = quiver3(pos(:, 1), pos(:, 2), pos(:, 3), ... +if isAxisHandle(pos) + hAx = pos; + pos = vect; + vect = varargin{1}; + varargin(1) = []; +else + hAx = gca; +end + +h = quiver3(hAx, pos(:, 1), pos(:, 2), pos(:, 3), ... vect(:, 1), vect(:, 2), vect(:, 3), 0, varargin{:}); % format output diff -Nru octave-matgeom-1.2.2/inst/geom3d/edgeLength3d.m octave-matgeom-1.2.3/inst/geom3d/edgeLength3d.m --- octave-matgeom-1.2.2/inst/geom3d/edgeLength3d.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/edgeLength3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/edges3d.m octave-matgeom-1.2.3/inst/geom3d/edges3d.m --- octave-matgeom-1.2.2/inst/geom3d/edges3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/edges3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/edgeToLine3d.m octave-matgeom-1.2.3/inst/geom3d/edgeToLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/edgeToLine3d.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/edgeToLine3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/ellipsoidSurfaceArea.m octave-matgeom-1.2.3/inst/geom3d/ellipsoidSurfaceArea.m --- octave-matgeom-1.2.2/inst/geom3d/ellipsoidSurfaceArea.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/ellipsoidSurfaceArea.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/equivalentEllipsoid.m octave-matgeom-1.2.3/inst/geom3d/equivalentEllipsoid.m --- octave-matgeom-1.2.2/inst/geom3d/equivalentEllipsoid.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/equivalentEllipsoid.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -50,11 +50,11 @@ % % See also % spheres, drawEllipsoid, equivalentEllipse, principalAxes -% rotation3dToEulerAngles +% principalAxesTransform, rotation3dToEulerAngles % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. @@ -67,7 +67,7 @@ % compute the covariance matrix covPts = cov(points)/n; -% perform a principal component analysis with 2 variables, +% perform a principal component analysis with 3 variables, % to extract equivalent axes [U, S] = svd(covPts); diff -Nru octave-matgeom-1.2.2/inst/geom3d/eulerAnglesToRotation3d.m octave-matgeom-1.2.3/inst/geom3d/eulerAnglesToRotation3d.m --- octave-matgeom-1.2.2/inst/geom3d/eulerAnglesToRotation3d.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/eulerAnglesToRotation3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -53,8 +53,10 @@ % Concatenates all angles in a single 1-by-3 array. % % ... = eulerAnglesToRotation3d(ANGLES, CONVENTION) -% CONVENTION specifies the axis rotation sequence. -% Supported conventions are: 'ZYX', 'ZYZ'. Default is 'ZYX'. +% 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; @@ -79,20 +81,25 @@ % HISTORY % 2011-06-20 rename and use degrees -p = inputParser; -validStrings = {'ZYX','ZYZ'}; -addOptional(p,'convention','ZYX',@(x) any(validatestring(x,validStrings))); -parse(p,varargin{:}); -convention=p.Results.convention; - % 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; @@ -101,10 +108,50 @@ 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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/fillPolygon3d.m octave-matgeom-1.2.3/inst/geom3d/fillPolygon3d.m --- octave-matgeom-1.2.2/inst/geom3d/fillPolygon3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fillPolygon3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/fillSphericalPolygon.m octave-matgeom-1.2.3/inst/geom3d/fillSphericalPolygon.m --- octave-matgeom-1.2.2/inst/geom3d/fillSphericalPolygon.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fillSphericalPolygon.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/fillSphericalTriangle.m octave-matgeom-1.2.3/inst/geom3d/fillSphericalTriangle.m --- octave-matgeom-1.2.2/inst/geom3d/fillSphericalTriangle.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fillSphericalTriangle.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/fitAffineTransform3d.m octave-matgeom-1.2.3/inst/geom3d/fitAffineTransform3d.m --- octave-matgeom-1.2.2/inst/geom3d/fitAffineTransform3d.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fitAffineTransform3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,10 +25,16 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function trans = fitAffineTransform3d(pts1, pts2) -%FITAFFINETRANSFORM3D Fit an affine transform using two point sets. +function trans = fitAffineTransform3d(ref, src) +% Compute the affine transform that best register two 3D point sets. % -% TRANS = fitAffineTransform3d(PTS1, PTS2) +% 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; @@ -41,31 +47,31 @@ % % See also % transforms3d, transformPoint3d, transformVector3d, -% registerPoints3dAffine +% fitAffineTransform2d, registerPoints3dAffine % % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2009-07-31, using Matlab 7.7.0.471 (R2008b) -% Copyright 2009 INRA - Cepia Software Platform. +% Copyright 2009 INRAE - Cepia Software Platform. % number of points -N = size(pts1, 1); -if size(pts2, 1) ~= N +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 = [pts1(:,1) pts1(:,2) pts1(:,3) ones(N,1)]; +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 = [pts2(:,1) ; pts2(:,2) ; pts2(:,3)]; +B = [ref(:,1) ; ref(:,2) ; ref(:,3)]; % compute coefficients using least square coefs = A\B; diff -Nru octave-matgeom-1.2.2/inst/geom3d/fitCircle3d.m octave-matgeom-1.2.3/inst/geom3d/fitCircle3d.m --- octave-matgeom-1.2.2/inst/geom3d/fitCircle3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fitCircle3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/fitEllipse3d.m octave-matgeom-1.2.3/inst/geom3d/fitEllipse3d.m --- octave-matgeom-1.2.2/inst/geom3d/fitEllipse3d.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fitEllipse3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -55,8 +55,8 @@ % drawEllipse3d, ellipseToPolygon % % Source -% Nested functions are part of the quadfit toolbox of Levente Hunyadi -% https://de.mathworks.com/matlabcentral/fileexchange/45356 +% Nested functions are part of the quadfit toolbox by Levente Hunyadi +% https://mathworks.com/matlabcentral/fileexchange/45356 % % --------- % Author: oqilipo @@ -68,7 +68,6 @@ {'ncols',3,'real','finite','nonnan'})); addOptional(parser,'visualization',false,@islogical); parse(parser,points,varargin{:}); - points=parser.Results.points; % Mean of all points @@ -110,7 +109,7 @@ fittedEllipse3d=[center A B THETA PHI PSI]; %% Visualization -if parser.Results.visualization == true +if parser.Results.visualization figure('Color','w'); axis equal tight; hold on; view(3) xlabel('x'); ylabel('y'); zlabel('z'); diff -Nru octave-matgeom-1.2.2/inst/geom3d/fitLine3d.m octave-matgeom-1.2.3/inst/geom3d/fitLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/fitLine3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fitLine3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function line = fitLine3d(points) -%FITLINE3D Fit a 3D line to a set of points. +%FITLINE3D Fit a 3D line to a set of points. % % LINE = fitLine3d(PTS) % @@ -37,7 +37,7 @@ % pts = transformPoint3d(pts, createRotationOy(pi/4)); % pts = transformPoint3d(pts, createRotationOz(pi/3)); % pts = transformPoint3d(pts, createTranslation3d([5 4 3])); -% elli = inertiaEllipsoid(pts); +% elli = equivalentEllipsoid(pts); % figure; drawPoint3d(pts); axis equal; % hold on; drawEllipsoid(elli, ... % 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); @@ -45,7 +45,7 @@ % drawLine3d(line, 'color', 'm', 'LineWidth', 4); % % See also -% lines3d, inertiaEllipsoid, fitPlane +% lines3d, equivalentEllipsoid, fitPlane % % ------ diff -Nru octave-matgeom-1.2.2/inst/geom3d/fitPlane.m octave-matgeom-1.2.3/inst/geom3d/fitPlane.m --- octave-matgeom-1.2.2/inst/geom3d/fitPlane.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fitPlane.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function plane = fitPlane(points) -%FITPLANE Fit a 3D plane to a set of points. +%FITPLANE Fit a 3D plane to a set of points. % % PLANE = fitPlane(POINTS) % @@ -37,7 +37,7 @@ % pts = transformPoint3d(pts, createRotationOy(pi/4)); % pts = transformPoint3d(pts, createRotationOz(pi/3)); % pts = transformPoint3d(pts, createTranslation3d([5 4 3])); -% elli = inertiaEllipsoid(pts); +% elli = equivalentEllipsoid(pts); % figure; drawPoint3d(pts); axis equal; % hold on; drawEllipsoid(elli, ... % 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); @@ -45,7 +45,7 @@ % drawPlane3d(plane, 'm'); % % See also -% planes3d, inertiaEllipsoid, fitLine3d +% planes3d, equivalentEllipsoid, fitLine3d % % ------ diff -Nru octave-matgeom-1.2.2/inst/geom3d/fitSphere.m octave-matgeom-1.2.3/inst/geom3d/fitSphere.m --- octave-matgeom-1.2.2/inst/geom3d/fitSphere.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/fitSphere.m 2021-06-01 09:14:26.034813734 +0000 @@ -0,0 +1,104 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% Created: 2010 +% Copyright 2010 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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/geodesicCylinder.m octave-matgeom-1.2.3/inst/geom3d/geodesicCylinder.m --- octave-matgeom-1.2.2/inst/geom3d/geodesicCylinder.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/geodesicCylinder.m 2021-06-01 09:14:26.046813689 +0000 @@ -0,0 +1,127 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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 +% Created: 2021-04-17, using R2020b +% Copyright 2021 + +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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/hypot3.m octave-matgeom-1.2.3/inst/geom3d/hypot3.m --- octave-matgeom-1.2.2/inst/geom3d/hypot3.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/hypot3.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/inertiaEllipsoid.m octave-matgeom-1.2.3/inst/geom3d/inertiaEllipsoid.m --- octave-matgeom-1.2.2/inst/geom3d/inertiaEllipsoid.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/inertiaEllipsoid.m 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -## Copyright (C) 2019 David Legland -## All rights reserved. -## -## Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are met: -## -## 1 Redistributions of source code must retain the above copyright notice, -## this list of conditions and the following disclaimer. -## 2 Redistributions in binary form must reproduce the above copyright -## notice, this list of conditions and the following disclaimer in the -## documentation and/or other materials provided with the distribution. -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' -## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR -## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -## -## The views and conclusions contained in the software and 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 = inertiaEllipsoid(points) -%INERTIAELLIPSOID Inertia ellipsoid of a set of 3D points. -% -% Note: Deprecated! Use equivalentEllipsoid instead. -% -% -% ELL = inertiaEllipsoid(PTS) -% Compute the inertia 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 lengths of 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 = inertiaEllipsoid(pts); -% figure; drawPoint3d(pts); axis equal; -% hold on; drawEllipsoid(elli, ... -% 'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3); -% -% See also -% equivalentEllipsoid -% - -% ------ -% Author: David Legland -% e-mail: david.legland@inra.fr -% Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) -% Copyright 2011 INRA - Cepia Software Platform. - -% deprecation warning -warning('geom3d:deprecated', ... - [mfilename ' is deprecated, use ''equivalentEllipsoid'' instead']); - -% 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); - -% 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]; diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectBoxes3d.m octave-matgeom-1.2.3/inst/geom3d/intersectBoxes3d.m --- octave-matgeom-1.2.2/inst/geom3d/intersectBoxes3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectBoxes3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectEdgePlane.m octave-matgeom-1.2.3/inst/geom3d/intersectEdgePlane.m --- octave-matgeom-1.2.2/inst/geom3d/intersectEdgePlane.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectEdgePlane.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectEdgePolygon3d.m octave-matgeom-1.2.3/inst/geom3d/intersectEdgePolygon3d.m --- octave-matgeom-1.2.2/inst/geom3d/intersectEdgePolygon3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectEdgePolygon3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -0,0 +1,93 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 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; diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectLineCylinder.m octave-matgeom-1.2.3/inst/geom3d/intersectLineCylinder.m --- octave-matgeom-1.2.2/inst/geom3d/intersectLineCylinder.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectLineCylinder.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectLinePlane.m octave-matgeom-1.2.3/inst/geom3d/intersectLinePlane.m --- octave-matgeom-1.2.2/inst/geom3d/intersectLinePlane.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectLinePlane.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectLinePolygon3d.m octave-matgeom-1.2.3/inst/geom3d/intersectLinePolygon3d.m --- octave-matgeom-1.2.2/inst/geom3d/intersectLinePolygon3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectLinePolygon3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectLineSphere.m octave-matgeom-1.2.3/inst/geom3d/intersectLineSphere.m --- octave-matgeom-1.2.2/inst/geom3d/intersectLineSphere.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectLineSphere.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectLineTriangle3d.m octave-matgeom-1.2.3/inst/geom3d/intersectLineTriangle3d.m --- octave-matgeom-1.2.2/inst/geom3d/intersectLineTriangle3d.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectLineTriangle3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectPlanes.m octave-matgeom-1.2.3/inst/geom3d/intersectPlanes.m --- octave-matgeom-1.2.2/inst/geom3d/intersectPlanes.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectPlanes.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectPlaneSphere.m octave-matgeom-1.2.3/inst/geom3d/intersectPlaneSphere.m --- octave-matgeom-1.2.2/inst/geom3d/intersectPlaneSphere.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectPlaneSphere.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectRayPolygon3d.m octave-matgeom-1.2.3/inst/geom3d/intersectRayPolygon3d.m --- octave-matgeom-1.2.2/inst/geom3d/intersectRayPolygon3d.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectRayPolygon3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/intersectThreePlanes.m octave-matgeom-1.2.3/inst/geom3d/intersectThreePlanes.m --- octave-matgeom-1.2.2/inst/geom3d/intersectThreePlanes.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/intersectThreePlanes.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/isBelowPlane.m octave-matgeom-1.2.3/inst/geom3d/isBelowPlane.m --- octave-matgeom-1.2.2/inst/geom3d/isBelowPlane.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isBelowPlane.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/isCoplanar.m octave-matgeom-1.2.3/inst/geom3d/isCoplanar.m --- octave-matgeom-1.2.2/inst/geom3d/isCoplanar.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isCoplanar.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/isParallel3d.m octave-matgeom-1.2.3/inst/geom3d/isParallel3d.m --- octave-matgeom-1.2.2/inst/geom3d/isParallel3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isParallel3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/isPerpendicular3d.m octave-matgeom-1.2.3/inst/geom3d/isPerpendicular3d.m --- octave-matgeom-1.2.2/inst/geom3d/isPerpendicular3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isPerpendicular3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/isPlane.m octave-matgeom-1.2.3/inst/geom3d/isPlane.m --- octave-matgeom-1.2.2/inst/geom3d/isPlane.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isPlane.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ % createPlane3d % % ------ -% Author: oqilipo, David Legland +% Author: oqilipo % Created: 2017-07-09 % Copyright 2017 @@ -57,4 +57,6 @@ b = ~any(isinf(plane),2); c = ~isParallel3d(plane(:,4:6), plane(:,7:9)); -d=a & b & c; +d = a & b & c; + +end diff -Nru octave-matgeom-1.2.2/inst/geom3d/isPointInEllipsoid.m octave-matgeom-1.2.3/inst/geom3d/isPointInEllipsoid.m --- octave-matgeom-1.2.2/inst/geom3d/isPointInEllipsoid.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isPointInEllipsoid.m 2021-06-01 09:14:26.038813720 +0000 @@ -0,0 +1,81 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-11-19, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + +% 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; + diff -Nru octave-matgeom-1.2.2/inst/geom3d/isPointOnEdge3d.m octave-matgeom-1.2.3/inst/geom3d/isPointOnEdge3d.m --- octave-matgeom-1.2.2/inst/geom3d/isPointOnEdge3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isPointOnEdge3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -0,0 +1,116 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% + + + +% 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; diff -Nru octave-matgeom-1.2.2/inst/geom3d/isPointOnLine3d.m octave-matgeom-1.2.3/inst/geom3d/isPointOnLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/isPointOnLine3d.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isPointOnLine3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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. +%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]. @@ -59,8 +59,21 @@ tol = varargin{1}; end -% test if lines are colinear, using norm of the cross product -b = bsxfun(@rdivide, vectorNorm3d( ... +% 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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/isTransform3d.m octave-matgeom-1.2.3/inst/geom3d/isTransform3d.m --- octave-matgeom-1.2.2/inst/geom3d/isTransform3d.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/isTransform3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -56,12 +56,16 @@ % Created: 2018-07-08 % Copyright 2018 -narginchk(1,3) +narginchk(1,5) p = inputParser; -addParameter(p,'rotation',false,@islogical); +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 @@ -107,13 +111,13 @@ 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))) > eps*1e8) + 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)) > eps*1e8 + if abs(1-det(trans)) > tolerance a = false; return end diff -Nru octave-matgeom-1.2.2/inst/geom3d/linePosition3d.m octave-matgeom-1.2.3/inst/geom3d/linePosition3d.m --- octave-matgeom-1.2.2/inst/geom3d/linePosition3d.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/linePosition3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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. +% 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 @@ -59,19 +59,49 @@ % 28/10/2010 change to bsxfun calculation for arbitrary input sizes % (Thanks to Sven Holcombe) -% 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; +% 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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/lines3d.m octave-matgeom-1.2.3/inst/geom3d/lines3d.m --- octave-matgeom-1.2.2/inst/geom3d/lines3d.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/lines3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/lineToEdge3d.m octave-matgeom-1.2.3/inst/geom3d/lineToEdge3d.m --- octave-matgeom-1.2.2/inst/geom3d/lineToEdge3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/lineToEdge3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/medianPlane.m octave-matgeom-1.2.3/inst/geom3d/medianPlane.m --- octave-matgeom-1.2.2/inst/geom3d/medianPlane.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/medianPlane.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/mergeBoxes3d.m octave-matgeom-1.2.3/inst/geom3d/mergeBoxes3d.m --- octave-matgeom-1.2.2/inst/geom3d/mergeBoxes3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/mergeBoxes3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/midPoint3d.m octave-matgeom-1.2.3/inst/geom3d/midPoint3d.m --- octave-matgeom-1.2.2/inst/geom3d/midPoint3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/midPoint3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/normalizeLine3d.m octave-matgeom-1.2.3/inst/geom3d/normalizeLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/normalizeLine3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/normalizeLine3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -0,0 +1,56 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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 +% Created: 2020-03-13 +% Copyright 2020 + +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 + diff -Nru octave-matgeom-1.2.2/inst/geom3d/normalizePlane.m octave-matgeom-1.2.3/inst/geom3d/normalizePlane.m --- octave-matgeom-1.2.2/inst/geom3d/normalizePlane.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/normalizePlane.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/normalizeVector3d.m octave-matgeom-1.2.3/inst/geom3d/normalizeVector3d.m --- octave-matgeom-1.2.2/inst/geom3d/normalizeVector3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/normalizeVector3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function vn = normalizeVector3d(v) -%NORMALIZEVECTOR3D Normalize a 3D vector to have norm equal to 1. +%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 @@ -35,8 +35,11 @@ % 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 +% vectors3d, vectorNorm3d % % --------- @@ -50,4 +53,8 @@ % 2009-06-19 rename as normalizeVector3d % 2010-11-16 use bsxfun (Thanks to Sven Holcombe) -vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); +if ismatrix(v) + vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); +else + vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, ndims(v)))); +end diff -Nru octave-matgeom-1.2.2/inst/geom3d/oblateSurfaceArea.m octave-matgeom-1.2.3/inst/geom3d/oblateSurfaceArea.m --- octave-matgeom-1.2.2/inst/geom3d/oblateSurfaceArea.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/oblateSurfaceArea.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/orientedBox3d.m octave-matgeom-1.2.3/inst/geom3d/orientedBox3d.m --- octave-matgeom-1.2.2/inst/geom3d/orientedBox3d.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/orientedBox3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/parallelLine3d.m octave-matgeom-1.2.3/inst/geom3d/parallelLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/parallelLine3d.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/parallelLine3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/parallelPlane.m octave-matgeom-1.2.3/inst/geom3d/parallelPlane.m --- octave-matgeom-1.2.2/inst/geom3d/parallelPlane.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/parallelPlane.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/planeNormal.m octave-matgeom-1.2.3/inst/geom3d/planeNormal.m --- octave-matgeom-1.2.2/inst/geom3d/planeNormal.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/planeNormal.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/planePoint.m octave-matgeom-1.2.3/inst/geom3d/planePoint.m --- octave-matgeom-1.2.2/inst/geom3d/planePoint.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/planePoint.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/planePosition.m octave-matgeom-1.2.3/inst/geom3d/planePosition.m --- octave-matgeom-1.2.2/inst/geom3d/planePosition.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/planePosition.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/planes3d.m octave-matgeom-1.2.3/inst/geom3d/planes3d.m --- octave-matgeom-1.2.2/inst/geom3d/planes3d.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/planes3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/planesBisector.m octave-matgeom-1.2.3/inst/geom3d/planesBisector.m --- octave-matgeom-1.2.2/inst/geom3d/planesBisector.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/planesBisector.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/points3d.m octave-matgeom-1.2.3/inst/geom3d/points3d.m --- octave-matgeom-1.2.2/inst/geom3d/points3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/points3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/polygon3dNormalAngle.m octave-matgeom-1.2.3/inst/geom3d/polygon3dNormalAngle.m --- octave-matgeom-1.2.2/inst/geom3d/polygon3dNormalAngle.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/polygon3dNormalAngle.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/polygonArea3d.m octave-matgeom-1.2.3/inst/geom3d/polygonArea3d.m --- octave-matgeom-1.2.2/inst/geom3d/polygonArea3d.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/polygonArea3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/polygonCentroid3d.m octave-matgeom-1.2.3/inst/geom3d/polygonCentroid3d.m --- octave-matgeom-1.2.2/inst/geom3d/polygonCentroid3d.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/polygonCentroid3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/polygons3d.m octave-matgeom-1.2.3/inst/geom3d/polygons3d.m --- octave-matgeom-1.2.2/inst/geom3d/polygons3d.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/polygons3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/private/localToGlobal3d.m octave-matgeom-1.2.3/inst/geom3d/private/localToGlobal3d.m --- octave-matgeom-1.2.2/inst/geom3d/private/localToGlobal3d.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/private/localToGlobal3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function trans = localToGlobal3d(varargin) -%LOCALTOGLOBAL3D Transformation matrix from local to global coordinate system. +%LOCALTOGLOBAL3D Transformation matrix from local to global coordinate system. % % TRANS = localToGlobal3d(CENTER, THETA, PHI, PSI) % Compute the transformation matrix from a local (or modelling) @@ -34,7 +34,7 @@ % 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 +% - 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. @@ -44,7 +44,7 @@ % 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 PSI around the Z-axis % - Rotation by THETA around the Y-axis % - Rotation by PHI around the Z-axis % - Translation by vector CENTER @@ -58,7 +58,7 @@ % localToGlobal3d % % See also -% transforms3d, createEulerAnglesRotation +% transforms3d, eulerAnglesToRotation3d % % ------ % Author: David Legland diff -Nru octave-matgeom-1.2.2/inst/geom3d/private/parseDrawInput.m octave-matgeom-1.2.3/inst/geom3d/private/parseDrawInput.m --- octave-matgeom-1.2.2/inst/geom3d/private/parseDrawInput.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/private/parseDrawInput.m 2021-06-01 09:14:26.058813643 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ ## 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) +function [hAx, prim, varargin] = parseDrawInput(prim, valFun, type, defOpts, varargin) %PARSEDRAWINPUT Parse input arguments for drawing functions: draw*. % % INPUT: diff -Nru octave-matgeom-1.2.2/inst/geom3d/private/polygonCentroid.m octave-matgeom-1.2.3/inst/geom3d/private/polygonCentroid.m --- octave-matgeom-1.2.2/inst/geom3d/private/polygonCentroid.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/private/polygonCentroid.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/private/splitPolygons3d.m octave-matgeom-1.2.3/inst/geom3d/private/splitPolygons3d.m --- octave-matgeom-1.2.2/inst/geom3d/private/splitPolygons3d.m 2019-12-04 12:15:22.931633667 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/private/splitPolygons3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/projLineOnPlane.m octave-matgeom-1.2.3/inst/geom3d/projLineOnPlane.m --- octave-matgeom-1.2.2/inst/geom3d/projLineOnPlane.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/projLineOnPlane.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/projPointOnCircle3d.m octave-matgeom-1.2.3/inst/geom3d/projPointOnCircle3d.m --- octave-matgeom-1.2.2/inst/geom3d/projPointOnCircle3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/projPointOnCircle3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -0,0 +1,77 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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 +% Created: 2020-10-12 +% Copyright 2020 +% + +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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/projPointOnCylinder.m octave-matgeom-1.2.3/inst/geom3d/projPointOnCylinder.m --- octave-matgeom-1.2.2/inst/geom3d/projPointOnCylinder.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/projPointOnCylinder.m 2021-06-01 09:14:26.038813720 +0000 @@ -0,0 +1,128 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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 +% Created: 2021-04-17, using R2020b +% Copyright 2021 + +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 diff -Nru octave-matgeom-1.2.2/inst/geom3d/projPointOnLine3d.m octave-matgeom-1.2.3/inst/geom3d/projPointOnLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/projPointOnLine3d.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/projPointOnLine3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/projPointOnPlane.m octave-matgeom-1.2.3/inst/geom3d/projPointOnPlane.m --- octave-matgeom-1.2.2/inst/geom3d/projPointOnPlane.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/projPointOnPlane.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/prolateSurfaceArea.m octave-matgeom-1.2.3/inst/geom3d/prolateSurfaceArea.m --- octave-matgeom-1.2.2/inst/geom3d/prolateSurfaceArea.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/prolateSurfaceArea.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/randomAngle3d.m octave-matgeom-1.2.3/inst/geom3d/randomAngle3d.m --- octave-matgeom-1.2.2/inst/geom3d/randomAngle3d.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/randomAngle3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/randomPointInBox3d.m octave-matgeom-1.2.3/inst/geom3d/randomPointInBox3d.m --- octave-matgeom-1.2.2/inst/geom3d/randomPointInBox3d.m 2019-12-04 12:15:22.927633589 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/randomPointInBox3d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/recenterTransform3d.m octave-matgeom-1.2.3/inst/geom3d/recenterTransform3d.m --- octave-matgeom-1.2.2/inst/geom3d/recenterTransform3d.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/recenterTransform3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/registerPoints3dAffine.m octave-matgeom-1.2.3/inst/geom3d/registerPoints3dAffine.m --- octave-matgeom-1.2.2/inst/geom3d/registerPoints3dAffine.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/registerPoints3dAffine.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/reverseLine3d.m octave-matgeom-1.2.3/inst/geom3d/reverseLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/reverseLine3d.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/reverseLine3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/reversePlane.m octave-matgeom-1.2.3/inst/geom3d/reversePlane.m --- octave-matgeom-1.2.2/inst/geom3d/reversePlane.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/reversePlane.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/revolutionSurface.m octave-matgeom-1.2.3/inst/geom3d/revolutionSurface.m --- octave-matgeom-1.2.2/inst/geom3d/revolutionSurface.m 2019-12-04 12:15:22.899633043 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/revolutionSurface.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/rotation3dAxisAndAngle.m octave-matgeom-1.2.3/inst/geom3d/rotation3dAxisAndAngle.m --- octave-matgeom-1.2.2/inst/geom3d/rotation3dAxisAndAngle.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/rotation3dAxisAndAngle.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/rotation3dToEulerAngles.m octave-matgeom-1.2.3/inst/geom3d/rotation3dToEulerAngles.m --- octave-matgeom-1.2.2/inst/geom3d/rotation3dToEulerAngles.m 2019-12-04 12:15:22.919633433 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/rotation3dToEulerAngles.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = rotation3dToEulerAngles(mat, varargin) -%ROTATION3DTOEULERANGLES Extract Euler angles from a rotation matrix. +%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 @@ -37,17 +37,21 @@ % for representing some 3D shapes like ellipsoids. % % ... = rotation3dToEulerAngles(MAT, CONVENTION) -% CONVENTION specifies the axis rotation sequence. -% Supported conventions are: 'ZYX', 'ZYZ'. Default is 'ZYX' +% 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 Graphics Gems IV on euler angles -% http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/EulerAngles.c +% Code from '1994 - Shoemake - Graphics Gems IV: Euler Angle Conversion: +% http://webdocs.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiv/euler_angle/EulerAngles.c +% (see also rotm2eul, that is part of MATLAB's Robotics System Toolbox) % Modified using explanations in: -% http://www.gregslabaugh.name/publications/euler.pdf +% http://www.gregslabaugh.net/publications/euler.pdf +% https://www.geometrictools.com/Documentation/EulerAngles.pdf % % See also % transforms3d, rotation3dAxisAndAngle, createRotation3dLineAngle, @@ -55,19 +59,32 @@ % % % ------ -% Author: David Legland +% Authors: David Legland, oqilipo % e-mail: david.legland@grignon.inra.fr % Created: 2010-08-11, using Matlab 7.9.0.529 (R2009b) % Copyright 2010 INRA - Cepia Software Platform. p = inputParser; -validStrings = {'ZYX','ZYZ'}; +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; -% conversion from radians to degrees -k = 180 / pi; +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' @@ -76,33 +93,143 @@ % avoid dividing by 0 if cy > 16*eps % normal case: theta <> 0 - phi = k * atan2( mat(2,1), mat(1,1)); - theta = k * atan2(-mat(3,1), cy); - psi = k * atan2( mat(3,2), mat(3,3)); + 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 = k * atan2(-mat(3,1), cy); - psi = k * atan2(-mat(2,3), mat(2,2)); + 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 = k * -atan2(mat(2,3), -mat(1,3)); - theta = k * -atan2(cy, mat(3,3)); - psi = k * -atan2(mat(3,2), mat(3,1)); + 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 = k * atan2(cy, mat(3,3)); - psi = k * atan2(mat(2,1), mat(2,2)); + 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} = [phi theta psi]; + varargout{1} = rad2deg([phi theta psi]); else % three separate arrays - varargout = {phi, theta, psi}; + varargout = cellfun(@rad2deg, {phi theta psi},'uni',0); end diff -Nru octave-matgeom-1.2.2/inst/geom3d/sph2cart2d.m octave-matgeom-1.2.3/inst/geom3d/sph2cart2d.m --- octave-matgeom-1.2.2/inst/geom3d/sph2cart2d.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/sph2cart2d.m 2021-06-01 09:14:26.050813674 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/sph2cart2.m octave-matgeom-1.2.3/inst/geom3d/sph2cart2.m --- octave-matgeom-1.2.2/inst/geom3d/sph2cart2.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/sph2cart2.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/spheres.m octave-matgeom-1.2.3/inst/geom3d/spheres.m --- octave-matgeom-1.2.2/inst/geom3d/spheres.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/spheres.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/sphericalAngle.m octave-matgeom-1.2.3/inst/geom3d/sphericalAngle.m --- octave-matgeom-1.2.2/inst/geom3d/sphericalAngle.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/sphericalAngle.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/sphericalVoronoiDomain.m octave-matgeom-1.2.3/inst/geom3d/sphericalVoronoiDomain.m --- octave-matgeom-1.2.2/inst/geom3d/sphericalVoronoiDomain.m 2019-12-04 12:15:22.887632809 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/sphericalVoronoiDomain.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/surfaceCurvature.m octave-matgeom-1.2.3/inst/geom3d/surfaceCurvature.m --- octave-matgeom-1.2.2/inst/geom3d/surfaceCurvature.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/surfaceCurvature.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/transformLine3d.m octave-matgeom-1.2.3/inst/geom3d/transformLine3d.m --- octave-matgeom-1.2.2/inst/geom3d/transformLine3d.m 2019-12-04 12:15:22.895632965 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/transformLine3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/transformPlane3d.m octave-matgeom-1.2.3/inst/geom3d/transformPlane3d.m --- octave-matgeom-1.2.2/inst/geom3d/transformPlane3d.m 2019-12-04 12:15:22.907633199 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/transformPlane3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/transformPoint3d.m octave-matgeom-1.2.3/inst/geom3d/transformPoint3d.m --- octave-matgeom-1.2.2/inst/geom3d/transformPoint3d.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/transformPoint3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,16 +25,14 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function varargout = transformPoint3d(varargin) +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 [3x3], [3x4], [4x4] -% matrix, return the point transformed according to the affine transform -% specified by TRANS. -% -% Format of TRANS is a 4-by-4 matrix. +% 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] @@ -43,24 +41,28 @@ % [0 0 0 1] % % PT2 = transformPoint3d(PT1, TRANS) -% also work when PT1 is a [Nx3xMxPxETC] array of double. In this case, -% PT2 has the same size as PT1. +% 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(...); +% [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 +% 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, translation3d, meshgrid +% points3d, transforms3d, transformMesh, createTranslation3d +% createRotationOx, createRotationOy, createRotationOz, createScaling % + % --------- % author : David Legland % INRA - TPV URPOI - BIA IMASTE @@ -74,61 +76,74 @@ % 29/09/2010 fix bug in catch case % 12/03/2011 slightly reduce memory usage -% parse input arguments -meshStructSwitch = false; -if length(varargin) == 2 - if isstruct(varargin{1}) && isfield(varargin{1}, 'vertices') - % If first argument is a struct with the field 'vertices' the - % output will be the same struct, but with the transformed vertices - meshStructSwitch = true; - meshStruct = varargin{1}; - varargin{1}=varargin{1}.vertices; - end + +%% 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(varargin{1}); + dim = size(pts); dim(2) = 1; - [x, y, z] = deal(zeros(dim, class(varargin{1}))); - x(:) = varargin{1}(:,1,:); - y(:) = varargin{1}(:,2,:); - z(:) = varargin{1}(:,3,:); - trans = varargin{2}; -elseif length(varargin) == 4 + [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 = varargin{1}; - y = varargin{2}; - z = varargin{3}; + x = pts; + y = transfo; + z = varargin{1}; + transfo = varargin{2}; dim = size(x); - trans = varargin{4}; + +else + error('MatGeom:geom3d:WrongInputArgumentNumber', ... + 'Requires number of input arguments to be either 2 or 4'); end -% eventually add null translation -if size(trans, 2) == 3 - trans = [trans zeros(size(trans, 1), 1)]; -end -% eventually add normalization -if size(trans, 1) == 3 - trans = [trans;0 0 0 1]; +%% 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 -NP = numel(x); try - % vectorial processing, if there is enough memory - %res = (trans*[x(:) y(:) z(:) ones(NP, 1)]')'; - %res = [x(:) y(:) z(:) ones(NP, 1)]*trans'; - res = [x(:) y(:) z(:) ones(NP,1,class(x))] * trans'; + % 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) 1] * trans'; + res = [x(i) y(i) z(i)] * linear + trans; x(i) = res(1); y(i) = res(2); z(i) = res(3); @@ -143,16 +158,10 @@ '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 - if meshStructSwitch - meshStruct.vertices = [x y z]; - varargout{1}=meshStruct; - else - varargout{1} = [x y z]; - end + varargout{1} = [x y z]; end elseif nargout == 3 - varargout{1} = x; - varargout{2} = y; - varargout{3} = z; + % results are returned in three array with same size. + varargout = {x, y, z}; end diff -Nru octave-matgeom-1.2.2/inst/geom3d/transforms3d.m octave-matgeom-1.2.3/inst/geom3d/transforms3d.m --- octave-matgeom-1.2.2/inst/geom3d/transforms3d.m 2019-12-04 12:15:22.891632887 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/transforms3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/transformVector3d.m octave-matgeom-1.2.3/inst/geom3d/transformVector3d.m --- octave-matgeom-1.2.2/inst/geom3d/transformVector3d.m 2019-12-04 12:15:22.911633277 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/transformVector3d.m 2021-06-01 09:14:26.054813660 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -57,16 +57,14 @@ % created the 25/11/2008 from transformPoint3d % -if length(varargin)==2 % func(PTS_XYZ, PLANE) syntax - vIds = 1:2; -elseif length(varargin)==4 % func(X, Y, Z, PLANE) syntax - vIds = 1:3; +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{vIds(end)}; -trans(1:4, 4) = [0; 0; 0; 1]; +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{vIds(1:end-1)}, trans); +[varargout{:}] = transformPoint3d(varargin{1:end-1}, trans); diff -Nru octave-matgeom-1.2.2/inst/geom3d/triangleArea3d.m octave-matgeom-1.2.3/inst/geom3d/triangleArea3d.m --- octave-matgeom-1.2.2/inst/geom3d/triangleArea3d.m 2019-12-04 12:15:22.915633355 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/triangleArea3d.m 2021-06-01 09:14:26.034813734 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/vectorAngle3d.m octave-matgeom-1.2.3/inst/geom3d/vectorAngle3d.m --- octave-matgeom-1.2.2/inst/geom3d/vectorAngle3d.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/vectorAngle3d.m 2021-06-01 09:14:26.038813720 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/vectorCross3d.m octave-matgeom-1.2.3/inst/geom3d/vectorCross3d.m --- octave-matgeom-1.2.2/inst/geom3d/vectorCross3d.m 2019-12-04 12:15:22.903633121 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/vectorCross3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/geom3d/vectorNorm3d.m octave-matgeom-1.2.3/inst/geom3d/vectorNorm3d.m --- octave-matgeom-1.2.2/inst/geom3d/vectorNorm3d.m 2019-12-04 12:15:22.883632731 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/vectorNorm3d.m 2021-06-01 09:14:26.042813703 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,18 +26,18 @@ ## 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. +%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. -% Vector are given as rows. Result is then a N-by-1 array. +% Vectors are given as rows. Result is then a N-by-1 array. % -% NOTE: compute only euclidean norm. +% NOTE: Computes only the Euclidean norm. % -% See Also -% vectors3d, normalizeVector3d, vectorAngle3d, hypot3 +% See also: +% vectors3d, normalizeVector3d, vectorAngle3d, hypot3 % % --------- @@ -48,4 +48,4 @@ % HISTORY % 19/06/2009 rename as vectorNorm3d -n = sqrt(sum(v.*v, 2)); +n = sqrt(sum(v.*v, ndims(v))); diff -Nru octave-matgeom-1.2.2/inst/geom3d/vectors3d.m octave-matgeom-1.2.3/inst/geom3d/vectors3d.m --- octave-matgeom-1.2.2/inst/geom3d/vectors3d.m 2019-12-04 12:15:22.923633511 +0000 +++ octave-matgeom-1.2.3/inst/geom3d/vectors3d.m 2021-06-01 09:14:26.046813689 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/addSquareFace.m octave-matgeom-1.2.3/inst/graphs/addSquareFace.m --- octave-matgeom-1.2.2/inst/graphs/addSquareFace.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/addSquareFace.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/adjacencyListToEdges.m octave-matgeom-1.2.3/inst/graphs/adjacencyListToEdges.m --- octave-matgeom-1.2.2/inst/graphs/adjacencyListToEdges.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/graphs/adjacencyListToEdges.m 2021-06-01 09:14:26.110813447 +0000 @@ -0,0 +1,68 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-06-02, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + +% TODO: allocate memory + +% create the connectivity array +edges = zeros([0 2]); +for iVertex = 1:length(adjList) + neighs = adjList{iVertex}; + for iNeigh = 1:length(neighs) + edge = sort([iVertex neighs(iNeigh)]); + edges = [edges ; edge]; %#ok + end +end +edges = unique(edges, 'rows'); diff -Nru octave-matgeom-1.2.2/inst/graphs/boundaryGraph.m octave-matgeom-1.2.3/inst/graphs/boundaryGraph.m --- octave-matgeom-1.2.2/inst/graphs/boundaryGraph.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/boundaryGraph.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/boundedCentroidalVoronoi2d.m octave-matgeom-1.2.3/inst/graphs/boundedCentroidalVoronoi2d.m --- octave-matgeom-1.2.2/inst/graphs/boundedCentroidalVoronoi2d.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/boundedCentroidalVoronoi2d.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/boundedVoronoi2d.m octave-matgeom-1.2.3/inst/graphs/boundedVoronoi2d.m --- octave-matgeom-1.2.2/inst/graphs/boundedVoronoi2d.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/boundedVoronoi2d.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/centroidalVoronoi2d.m octave-matgeom-1.2.3/inst/graphs/centroidalVoronoi2d.m --- octave-matgeom-1.2.2/inst/graphs/centroidalVoronoi2d.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/centroidalVoronoi2d.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/centroidalVoronoi2d_MC.m octave-matgeom-1.2.3/inst/graphs/centroidalVoronoi2d_MC.m --- octave-matgeom-1.2.2/inst/graphs/centroidalVoronoi2d_MC.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/centroidalVoronoi2d_MC.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/clipGraph.m octave-matgeom-1.2.3/inst/graphs/clipGraph.m --- octave-matgeom-1.2.2/inst/graphs/clipGraph.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/clipGraph.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -151,7 +151,7 @@ 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))); + % disp(sprintf('clip edge n°%2d, from %2d to %2d', e, edges(e,1), edges(e,2))); % Node for first vertex if ~in1 diff -Nru octave-matgeom-1.2.2/inst/graphs/clipGraphPolygon.m octave-matgeom-1.2.3/inst/graphs/clipGraphPolygon.m --- octave-matgeom-1.2.2/inst/graphs/clipGraphPolygon.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/clipGraphPolygon.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/clipMesh2dPolygon.m octave-matgeom-1.2.3/inst/graphs/clipMesh2dPolygon.m --- octave-matgeom-1.2.2/inst/graphs/clipMesh2dPolygon.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/clipMesh2dPolygon.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/Contents.m octave-matgeom-1.2.3/inst/graphs/Contents.m --- octave-matgeom-1.2.2/inst/graphs/Contents.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/Contents.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -32,9 +32,11 @@ % modify and display geometric graphs (geometric in a sense position % nodes are associated to geometric position in 2D or 3D). % -% Graph structure is represented by at least two arrays: +% 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 @@ -56,95 +58,97 @@ % % % 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 +% 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 -% boundaryGraph - Get boundary of image as a graph +% imageGraph - Create equivalent graph of a binary image. +% 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. % % Voronoi Graphs -% voronoi2d - Compute a voronoi diagram as a graph structure -% boundedVoronoi2d - Return a bounded voronoi diagram as a graph structure -% centroidalVoronoi2d - Centroidal Voronoi tesselation within a polygon -% centroidalVoronoi2d_MC - Centroidal Voronoi tesselation by Monte-Carlo -% cvtUpdate - Update germs of a CVT with given points -% cvtIterate - Update germs of a CVT using random points with given density -% boundedCentroidalVoronoi2d - Create a 2D Centroidal Voronoi Tesselation in a box +% voronoi2d - Compute a voronoi diagram as a graph structure. +% boundedVoronoi2d - Return 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 +% 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) -% pruneGraph - Remove all edges with a terminal vertex -% mergeGraphs - Merge two graphs, by adding nodes, edges and faces lists. +% 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 +% 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 from neihgbours -% grMedian - Compute median from neihgbours -% grDilate - Morphological dilation on graph -% grErode - Morphological erosion on graph -% grClose - Morphological closing on graph -% grOpen - Morphological opening 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 +% 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 +% 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 +% 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 +% 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 +% 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 +% readGraph - Read a graph from a text file. +% writeGraph - Write a graph to an ascii file. % % ----- % Author: David Legland @@ -165,10 +169,12 @@ % 18/05/2011 code re-organisation, add to MatGeom library % Deprecated functions -% grSimplifyBranches_old - Replace branches of a graph by single edges -% grRemoveMultiplePoints - Remove groups of close nodes in a graph +% grSimplifyBranches_old - Replace branches of a graph by single edges. +% grRemoveMultiplePoints - Remove groups of close nodes in a graph. % Functions that requires further development -% quiverToGraph - Converts quiver data to quad mesh +% quiverToGraph - Converts quiver data to quad mesh. % Other functions +% polygonBoundedCVT2d - BOUNDEDCENTROIDALVORONOI2D Create a 2D Centroidal Voronoi Tesselation in a box + diff -Nru octave-matgeom-1.2.2/inst/graphs/cvtIterate.m octave-matgeom-1.2.3/inst/graphs/cvtIterate.m --- octave-matgeom-1.2.2/inst/graphs/cvtIterate.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/cvtIterate.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/cvtUpdate.m octave-matgeom-1.2.3/inst/graphs/cvtUpdate.m --- octave-matgeom-1.2.2/inst/graphs/cvtUpdate.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/cvtUpdate.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/delaunayGraph.m octave-matgeom-1.2.3/inst/graphs/delaunayGraph.m --- octave-matgeom-1.2.2/inst/graphs/delaunayGraph.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/delaunayGraph.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,9 +26,9 @@ ## policies, either expressed or implied, of the copyright holders. function [points, edges] = delaunayGraph(points, varargin) -%DELAUNAYGRAPH Graph associated to Delaunay triangulation of input points. +%DELAUNAYGRAPH Graph associated to Delaunay triangulation of input points. % -% [NODES EDGES] = delaunayGraph(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. @@ -36,13 +36,13 @@ % Example % % Draw a planar graph correpspionding to Delaunay triangulation % points = rand(30, 2) * 100; -% [nodes edges] = delaunayGraph(points); +% [nodes, edges] = delaunayGraph(points); % figure; % drawGraph(nodes, edges); % -% % Draw a 3Dgraph corresponding to Delaunay tetrahedrisation +% % Draw a 3D graph corresponding to Delaunay tetrahedrisation % points = rand(20, 3) * 100; -% [nodes edges] = delaunayGraph(points); +% [nodes, edges] = delaunayGraph(points); % figure; % drawGraph(nodes, edges); % view(3); @@ -53,7 +53,7 @@ % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2011-05-19, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. diff -Nru octave-matgeom-1.2.2/inst/graphs/drawDigraph.m octave-matgeom-1.2.3/inst/graphs/drawDigraph.m --- octave-matgeom-1.2.2/inst/graphs/drawDigraph.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/drawDigraph.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/drawDirectedEdges.m octave-matgeom-1.2.3/inst/graphs/drawDirectedEdges.m --- octave-matgeom-1.2.2/inst/graphs/drawDirectedEdges.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/drawDirectedEdges.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/drawEdgeLabels.m octave-matgeom-1.2.3/inst/graphs/drawEdgeLabels.m --- octave-matgeom-1.2.2/inst/graphs/drawEdgeLabels.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/drawEdgeLabels.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/drawGraphEdges.m octave-matgeom-1.2.3/inst/graphs/drawGraphEdges.m --- octave-matgeom-1.2.2/inst/graphs/drawGraphEdges.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/drawGraphEdges.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = drawGraphEdges(varargin) -%DRAWGRAPHEDGES Draw edges of a graph. +% 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, @@ -40,15 +40,15 @@ % % % H = drawGraphEdges(...) -% return handle to the set of edges. +% Returns handle to the set of edges. % % See also -% graphs, drawGraph, fillGraphFaces +% graphs, drawGraph, fillGraphFaces % % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2005-11-24 % Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). diff -Nru octave-matgeom-1.2.2/inst/graphs/drawGraph.m octave-matgeom-1.2.3/inst/graphs/drawGraph.m --- octave-matgeom-1.2.2/inst/graphs/drawGraph.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/drawGraph.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/drawNodeLabels.m octave-matgeom-1.2.3/inst/graphs/drawNodeLabels.m --- octave-matgeom-1.2.2/inst/graphs/drawNodeLabels.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/drawNodeLabels.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/drawSquareMesh.m octave-matgeom-1.2.3/inst/graphs/drawSquareMesh.m --- octave-matgeom-1.2.2/inst/graphs/drawSquareMesh.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/graphs/drawSquareMesh.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/euclideanMST.m octave-matgeom-1.2.3/inst/graphs/euclideanMST.m --- octave-matgeom-1.2.2/inst/graphs/euclideanMST.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/euclideanMST.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/fillGraphFaces.m octave-matgeom-1.2.3/inst/graphs/fillGraphFaces.m --- octave-matgeom-1.2.2/inst/graphs/fillGraphFaces.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/fillGraphFaces.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/gabrielGraph.m octave-matgeom-1.2.3/inst/graphs/gabrielGraph.m --- octave-matgeom-1.2.2/inst/graphs/gabrielGraph.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/gabrielGraph.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = gabrielGraph(pts) -%GABRIELGRAPH Gabriel Graph of a set of points. +%GABRIELGRAPH Gabriel Graph of a set of points. % % EDGES = gabrielGraph(PTS) % Computes the Gabriel graph of the input set of points PTS. The Gabriel @@ -34,7 +34,7 @@ % edges whose circumcircle does not contain any other input point than % the edge extremities. % -% [NODES EDGES] = gabrielGraph(PTS) +% [NODES, EDGES] = gabrielGraph(PTS) % Also returns the initial set of points; % % Example @@ -45,12 +45,12 @@ % drawGraph(pts, edges); % % See also -% drawGraph, delaunayGraph +% graphs, drawGraph, delaunayGraph % % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2012-01-22, using Matlab 7.9.0.529 (R2009b) % Copyright 2012 INRA - Cepia Software Platform. @@ -66,7 +66,7 @@ % extract edges (N-by-2 array) eds = dt.edges(); -% radius of the circule circumscribed to each edge +% radius of the circle circumscribed to each edge rads = edgeLength([pts(eds(:,1), :) pts(eds(:,2), :)]) / 2; % extract middle point of each edge @@ -83,6 +83,7 @@ keep = dists >= rads - tol; edges = eds(keep, :); +% format output depending on number of output arguments if nargout < 2 varargout = {edges}; else diff -Nru octave-matgeom-1.2.2/inst/graphs/gcontour2d.m octave-matgeom-1.2.3/inst/graphs/gcontour2d.m --- octave-matgeom-1.2.2/inst/graphs/gcontour2d.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/gcontour2d.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/gcontour3d.m octave-matgeom-1.2.3/inst/graphs/gcontour3d.m --- octave-matgeom-1.2.2/inst/graphs/gcontour3d.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/gcontour3d.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grAdjacentEdges.m octave-matgeom-1.2.3/inst/graphs/grAdjacentEdges.m --- octave-matgeom-1.2.2/inst/graphs/grAdjacentEdges.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grAdjacentEdges.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grAdjacentNodes.m octave-matgeom-1.2.3/inst/graphs/grAdjacentNodes.m --- octave-matgeom-1.2.2/inst/graphs/grAdjacentNodes.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grAdjacentNodes.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/graph2Contours.m octave-matgeom-1.2.3/inst/graphs/graph2Contours.m --- octave-matgeom-1.2.2/inst/graphs/graph2Contours.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/graph2Contours.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/graphCenter.m octave-matgeom-1.2.3/inst/graphs/graphCenter.m --- octave-matgeom-1.2.2/inst/graphs/graphCenter.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/graphCenter.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/graphDiameter.m octave-matgeom-1.2.3/inst/graphs/graphDiameter.m --- octave-matgeom-1.2.2/inst/graphs/graphDiameter.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/graphDiameter.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/graphPeripheralVertices.m octave-matgeom-1.2.3/inst/graphs/graphPeripheralVertices.m --- octave-matgeom-1.2.2/inst/graphs/graphPeripheralVertices.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/graphPeripheralVertices.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/graphRadius.m octave-matgeom-1.2.3/inst/graphs/graphRadius.m --- octave-matgeom-1.2.2/inst/graphs/graphRadius.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/graphRadius.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grClose.m octave-matgeom-1.2.3/inst/graphs/grClose.m --- octave-matgeom-1.2.2/inst/graphs/grClose.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grClose.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grDilate.m octave-matgeom-1.2.3/inst/graphs/grDilate.m --- octave-matgeom-1.2.2/inst/graphs/grDilate.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grDilate.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grEdgeLengths.m octave-matgeom-1.2.3/inst/graphs/grEdgeLengths.m --- octave-matgeom-1.2.2/inst/graphs/grEdgeLengths.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grEdgeLengths.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grErode.m octave-matgeom-1.2.3/inst/graphs/grErode.m --- octave-matgeom-1.2.2/inst/graphs/grErode.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grErode.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grFaceToPolygon.m octave-matgeom-1.2.3/inst/graphs/grFaceToPolygon.m --- octave-matgeom-1.2.2/inst/graphs/grFaceToPolygon.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grFaceToPolygon.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grFindGeodesicPath.m octave-matgeom-1.2.3/inst/graphs/grFindGeodesicPath.m --- octave-matgeom-1.2.2/inst/graphs/grFindGeodesicPath.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grFindGeodesicPath.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grFindMaximalLengthPath.m octave-matgeom-1.2.3/inst/graphs/grFindMaximalLengthPath.m --- octave-matgeom-1.2.2/inst/graphs/grFindMaximalLengthPath.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grFindMaximalLengthPath.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grLabel.m octave-matgeom-1.2.3/inst/graphs/grLabel.m --- octave-matgeom-1.2.2/inst/graphs/grLabel.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grLabel.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grMean.m octave-matgeom-1.2.3/inst/graphs/grMean.m --- octave-matgeom-1.2.2/inst/graphs/grMean.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grMean.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = grMean(varargin) -%GRMEAN Compute mean from neihgbours. +% 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 @@ -38,31 +38,31 @@ % See also % grMedian, grDilate, grErode % -% + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). if length(varargin) == 2 edges = varargin{1}; - lbl = varargin{2}; + values = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; - lbl = varargin{3}; + values = varargin{3}; else error('Wrong number of arguments in "grMean"'); end -lbl2 = zeros(size(lbl)); +res = zeros(size(values)); uni = unique(edges(:)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); - lbl2(uni(n)) = mean(lbl([uni(n); neigh])); + res(uni(n)) = mean(values([uni(n); neigh])); end -varargout{1} = lbl2; +varargout{1} = res; diff -Nru octave-matgeom-1.2.2/inst/graphs/grMedian.m octave-matgeom-1.2.3/inst/graphs/grMedian.m --- octave-matgeom-1.2.2/inst/graphs/grMedian.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grMedian.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,10 +26,10 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = grMedian(varargin) -%GRMEDIAN Compute median from neihgbours. +% Compute median value from neighbour nodes. % -% LBL2 = grMedian(EDGES, LBL1) -% new label for each node of the graph is computed as the median of the +% 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 @@ -38,31 +38,31 @@ % See also % grMean, grDilate, grErode % -% + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2006-01-20 % Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). if length(varargin) == 2 edges = varargin{1}; - lbl = varargin{2}; + values = varargin{2}; elseif length(varargin) == 3 edges = varargin{2}; - lbl = varargin{3}; + values = varargin{3}; else error('Wrong number of arguments in "grMedian"'); end -lbl2 = zeros(size(lbl)); +res = zeros(size(values)); uni = unique(edges(:)); for n = 1:length(uni) neigh = grAdjacentNodes(edges, uni(n)); - lbl2(uni(n)) = median(lbl([uni(n); neigh])); + res(uni(n)) = median(values([uni(n); neigh])); end -varargout{1} = lbl2; +varargout{1} = res; diff -Nru octave-matgeom-1.2.2/inst/graphs/grMergeMultipleEdges.m octave-matgeom-1.2.3/inst/graphs/grMergeMultipleEdges.m --- octave-matgeom-1.2.2/inst/graphs/grMergeMultipleEdges.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grMergeMultipleEdges.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grMergeMultipleNodes.m octave-matgeom-1.2.3/inst/graphs/grMergeMultipleNodes.m --- octave-matgeom-1.2.2/inst/graphs/grMergeMultipleNodes.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grMergeMultipleNodes.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grMergeNodeClusters.m octave-matgeom-1.2.3/inst/graphs/grMergeNodeClusters.m --- octave-matgeom-1.2.2/inst/graphs/grMergeNodeClusters.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grMergeNodeClusters.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grMergeNodes.m octave-matgeom-1.2.3/inst/graphs/grMergeNodes.m --- octave-matgeom-1.2.2/inst/graphs/grMergeNodes.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grMergeNodes.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grMergeNodesMedian.m octave-matgeom-1.2.3/inst/graphs/grMergeNodesMedian.m --- octave-matgeom-1.2.2/inst/graphs/grMergeNodesMedian.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grMergeNodesMedian.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grNodeDegree.m octave-matgeom-1.2.3/inst/graphs/grNodeDegree.m --- octave-matgeom-1.2.2/inst/graphs/grNodeDegree.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grNodeDegree.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grNodeInnerDegree.m octave-matgeom-1.2.3/inst/graphs/grNodeInnerDegree.m --- octave-matgeom-1.2.2/inst/graphs/grNodeInnerDegree.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grNodeInnerDegree.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grNodeOuterDegree.m octave-matgeom-1.2.3/inst/graphs/grNodeOuterDegree.m --- octave-matgeom-1.2.2/inst/graphs/grNodeOuterDegree.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grNodeOuterDegree.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grOpen.m octave-matgeom-1.2.3/inst/graphs/grOpen.m --- octave-matgeom-1.2.2/inst/graphs/grOpen.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grOpen.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grOppositeNode.m octave-matgeom-1.2.3/inst/graphs/grOppositeNode.m --- octave-matgeom-1.2.2/inst/graphs/grOppositeNode.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grOppositeNode.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grPropagateDistance.m octave-matgeom-1.2.3/inst/graphs/grPropagateDistance.m --- octave-matgeom-1.2.2/inst/graphs/grPropagateDistance.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grPropagateDistance.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grRemoveEdge.m octave-matgeom-1.2.3/inst/graphs/grRemoveEdge.m --- octave-matgeom-1.2.2/inst/graphs/grRemoveEdge.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grRemoveEdge.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grRemoveEdges.m octave-matgeom-1.2.3/inst/graphs/grRemoveEdges.m --- octave-matgeom-1.2.2/inst/graphs/grRemoveEdges.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grRemoveEdges.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grRemoveMultiplePoints.m octave-matgeom-1.2.3/inst/graphs/grRemoveMultiplePoints.m --- octave-matgeom-1.2.2/inst/graphs/grRemoveMultiplePoints.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grRemoveMultiplePoints.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grRemoveNode.m octave-matgeom-1.2.3/inst/graphs/grRemoveNode.m --- octave-matgeom-1.2.2/inst/graphs/grRemoveNode.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grRemoveNode.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grRemoveNodes.m octave-matgeom-1.2.3/inst/graphs/grRemoveNodes.m --- octave-matgeom-1.2.2/inst/graphs/grRemoveNodes.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grRemoveNodes.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grShortestPath.m octave-matgeom-1.2.3/inst/graphs/grShortestPath.m --- octave-matgeom-1.2.2/inst/graphs/grShortestPath.m 2019-12-04 12:15:22.975634525 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grShortestPath.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grSimplifyBranches.m octave-matgeom-1.2.3/inst/graphs/grSimplifyBranches.m --- octave-matgeom-1.2.2/inst/graphs/grSimplifyBranches.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grSimplifyBranches.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grSimplifyBranches_old.m octave-matgeom-1.2.3/inst/graphs/grSimplifyBranches_old.m --- octave-matgeom-1.2.2/inst/graphs/grSimplifyBranches_old.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grSimplifyBranches_old.m 2021-06-01 09:14:26.110813447 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/grVertexEccentricity.m octave-matgeom-1.2.3/inst/graphs/grVertexEccentricity.m --- octave-matgeom-1.2.2/inst/graphs/grVertexEccentricity.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/grVertexEccentricity.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/imageGraph.m octave-matgeom-1.2.3/inst/graphs/imageGraph.m --- octave-matgeom-1.2.2/inst/graphs/imageGraph.m 2019-12-04 12:15:23.003635071 +0000 +++ octave-matgeom-1.2.3/inst/graphs/imageGraph.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/knnGraph.m octave-matgeom-1.2.3/inst/graphs/knnGraph.m --- octave-matgeom-1.2.2/inst/graphs/knnGraph.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/knnGraph.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/mergeGraphs.m octave-matgeom-1.2.3/inst/graphs/mergeGraphs.m --- octave-matgeom-1.2.2/inst/graphs/mergeGraphs.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/mergeGraphs.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = mergeGraphs(varargin) -%MERGEGRAPHS Merge two graphs, by adding nodes, edges and faces lists. . +%MERGEGRAPHS Merge two graphs, by adding nodes, edges and faces lists. % % % @@ -47,7 +47,7 @@ % extract simplify tag var = varargin{nargin}; if ischar(var) - if strcmp(var, 'simplify'); + if strcmp(var, 'simplify') simplify = true; varargin = varargin(1:length(varargin)-1); end diff -Nru octave-matgeom-1.2.2/inst/graphs/meshEnergy.m octave-matgeom-1.2.3/inst/graphs/meshEnergy.m --- octave-matgeom-1.2.2/inst/graphs/meshEnergy.m 2019-12-04 12:15:22.983634681 +0000 +++ octave-matgeom-1.2.3/inst/graphs/meshEnergy.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,15 +26,21 @@ ## policies, either expressed or implied, of the copyright holders. function energy = meshEnergy(vertices, faces) -%MESHENERGY One-line description here, please. +% Computes the energy of a tesselation, as the sum of second area moments. % -% output = meshEnergy(input) +% 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 diff -Nru octave-matgeom-1.2.2/inst/graphs/patchGraph.m octave-matgeom-1.2.3/inst/graphs/patchGraph.m --- octave-matgeom-1.2.2/inst/graphs/patchGraph.m 2019-12-04 12:15:22.979634603 +0000 +++ octave-matgeom-1.2.3/inst/graphs/patchGraph.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/prim_mst.m octave-matgeom-1.2.3/inst/graphs/prim_mst.m --- octave-matgeom-1.2.2/inst/graphs/prim_mst.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/prim_mst.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/pruneGraph.m octave-matgeom-1.2.3/inst/graphs/pruneGraph.m --- octave-matgeom-1.2.2/inst/graphs/pruneGraph.m 2019-12-04 12:15:22.987634759 +0000 +++ octave-matgeom-1.2.3/inst/graphs/pruneGraph.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/quiverToGraph.m octave-matgeom-1.2.3/inst/graphs/quiverToGraph.m --- octave-matgeom-1.2.2/inst/graphs/quiverToGraph.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/quiverToGraph.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/readGraph.m octave-matgeom-1.2.3/inst/graphs/readGraph.m --- octave-matgeom-1.2.2/inst/graphs/readGraph.m 2019-12-04 12:15:22.999634993 +0000 +++ octave-matgeom-1.2.3/inst/graphs/readGraph.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/relativeNeighborhoodGraph.m octave-matgeom-1.2.3/inst/graphs/relativeNeighborhoodGraph.m --- octave-matgeom-1.2.2/inst/graphs/relativeNeighborhoodGraph.m 2019-12-04 12:15:22.995634915 +0000 +++ octave-matgeom-1.2.3/inst/graphs/relativeNeighborhoodGraph.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/voronoi2d.m octave-matgeom-1.2.3/inst/graphs/voronoi2d.m --- octave-matgeom-1.2.2/inst/graphs/voronoi2d.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/voronoi2d.m 2021-06-01 09:14:26.106813462 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/graphs/writeGraph.m octave-matgeom-1.2.3/inst/graphs/writeGraph.m --- octave-matgeom-1.2.2/inst/graphs/writeGraph.m 2019-12-04 12:15:22.991634837 +0000 +++ octave-matgeom-1.2.3/inst/graphs/writeGraph.m 2021-06-01 09:14:26.114813433 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/apple.ply octave-matgeom-1.2.3/inst/meshes3d/apple.ply --- octave-matgeom-1.2.2/inst/meshes3d/apple.ply 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/apple.ply 2021-06-01 09:14:25.998813871 +0000 @@ -0,0 +1,2580 @@ +ply +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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/averageMesh.m octave-matgeom-1.2.3/inst/meshes3d/averageMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/averageMesh.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/averageMesh.m 2021-06-01 09:14:26.094813507 +0000 @@ -0,0 +1,131 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and documentation are +## those of the authors and should not be interpreted as representing official +## policies, either expressed or implied, of the copyright holders. + +function [refMesh, distListIters, refVerticesIters] = averageMesh(meshList, varargin) +% Compute average mesh from a list of meshes. +% +% AVG = averageMesh(MESHLIST) +% +% Example +% averageMesh +% +% See also +% meshes3d + +% ------ +% Author: David Legland +% e-mail: david.legland@inrae.fr +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-01-31, using Matlab 9.7.0.1247435 (R2019b) Update 2 +% Copyright 2020 INRAE. + + +%% Parse input values + +% default values +nIters = 10; +verbose = false; + +% 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}; + 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 +refMesh = struct('vertices', meshList{1}.vertices, 'faces', meshList{1}.faces); + +refVerticesIters = cell(1, nIters); +distListIters = cell(1, nIters); + + +%% Main iteration + +for iIter = 1:nIters + if verbose + fprintf('iter %d/%d\n', iIter, nIters); + end + refMesh = smoothMesh(refMesh); + + % create new array for average vertices + newVerts = zeros(size(refMesh.vertices)); + distList = zeros(size(refMesh.vertices, 1), 1); + + % iterate over all meshes + for iMesh = 1:nMeshes + if verbose + fprintf(' mesh %d/%d\n', iMesh, nMeshes); + end + +% mesh = meshList{iMesh}; + inds = knnsearch(treeList{iMesh}, refMesh.vertices); + +% closest = mesh.vertices(inds,:); + closest = treeList{iMesh}.X(inds,:); + newVerts = newVerts + closest; + distList = distList + sum((closest - refMesh.vertices).^2, 2); + end + + % update new vertices + newVerts = newVerts / nMeshes; + refVerticesIters{iIter} = newVerts; + refMesh.vertices = newVerts; + + % keep list of distances + distList = sqrt(distList / nMeshes); + distListIters{iIter} = distList; +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'); + diff -Nru octave-matgeom-1.2.2/inst/meshes3d/boxToMesh.m octave-matgeom-1.2.3/inst/meshes3d/boxToMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/boxToMesh.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/boxToMesh.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -85,7 +85,7 @@ 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]; +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); diff -Nru octave-matgeom-1.2.2/inst/meshes3d/checkMeshAdjacentFaces.m octave-matgeom-1.2.3/inst/meshes3d/checkMeshAdjacentFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/checkMeshAdjacentFaces.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/checkMeshAdjacentFaces.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/clipConvexPolyhedronHP.m octave-matgeom-1.2.3/inst/meshes3d/clipConvexPolyhedronHP.m --- octave-matgeom-1.2.2/inst/meshes3d/clipConvexPolyhedronHP.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/clipConvexPolyhedronHP.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/clipMeshVertices.m octave-matgeom-1.2.3/inst/meshes3d/clipMeshVertices.m --- octave-matgeom-1.2.2/inst/meshes3d/clipMeshVertices.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/clipMeshVertices.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/collapseEdgesWithManyFaces.m octave-matgeom-1.2.3/inst/meshes3d/collapseEdgesWithManyFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/collapseEdgesWithManyFaces.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/collapseEdgesWithManyFaces.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/concatenateMeshes.m octave-matgeom-1.2.3/inst/meshes3d/concatenateMeshes.m --- octave-matgeom-1.2.2/inst/meshes3d/concatenateMeshes.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/concatenateMeshes.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/Contents.m octave-matgeom-1.2.3/inst/meshes3d/Contents.m --- octave-matgeom-1.2.2/inst/meshes3d/Contents.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/Contents.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -66,6 +66,9 @@ % 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. % % Intersections and clipping % intersectLineMesh3d - Intersection points of a 3D line with a mesh. @@ -81,7 +84,7 @@ % meshSurfaceArea - Surface area of a polyhedral mesh. % trimeshSurfaceArea - Surface area of a triangular mesh. % meshFaceAreas - Surface area of each face of a mesh. -% meshVolume - Volume of the space enclosed by a polygonal mesh. +% meshVolume - (Signed) volume of the space enclosed by a polygonal mesh. % 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. @@ -149,14 +152,19 @@ % steinerPolytope - Create a steiner polytope from a set of vectors. % % Drawing functions -% drawFaceNormals - Draw normal vector of each face in a mesh. % drawMesh - Draw a 3D mesh defined by vertex and face arrays. +% 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_ply - Read mesh data stored in PLY (Stanford triangle) format. -% writeMesh_off - Writes a mesh into a text file in OFF format. -% writeMesh_ply - Writes a mesh into a text file in PLY 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. % % ------ diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createCube.m octave-matgeom-1.2.3/inst/meshes3d/createCube.m --- octave-matgeom-1.2.2/inst/meshes3d/createCube.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createCube.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createCubeOctahedron.m octave-matgeom-1.2.3/inst/meshes3d/createCubeOctahedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createCubeOctahedron.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createCubeOctahedron.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createDodecahedron.m octave-matgeom-1.2.3/inst/meshes3d/createDodecahedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createDodecahedron.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createDodecahedron.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createDurerPolyhedron.m octave-matgeom-1.2.3/inst/meshes3d/createDurerPolyhedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createDurerPolyhedron.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createDurerPolyhedron.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = createDurerPolyhedron(varargin) -%CREATEDURERPOLYHEDRON Create a mesh representing Durer's polyhedron . +%CREATEDURERPOLYHEDRON Create a mesh representing Durer's polyhedron . % % [V, F] = createDurerPolyhedron % [V, E, F] = createDurerPolyhedron diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createIcosahedron.m octave-matgeom-1.2.3/inst/meshes3d/createIcosahedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createIcosahedron.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createIcosahedron.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createMengerSponge.m octave-matgeom-1.2.3/inst/meshes3d/createMengerSponge.m --- octave-matgeom-1.2.2/inst/meshes3d/createMengerSponge.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createMengerSponge.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createOctahedron.m octave-matgeom-1.2.3/inst/meshes3d/createOctahedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createOctahedron.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createOctahedron.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createRhombododecahedron.m octave-matgeom-1.2.3/inst/meshes3d/createRhombododecahedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createRhombododecahedron.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createRhombododecahedron.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createSoccerBall.m octave-matgeom-1.2.3/inst/meshes3d/createSoccerBall.m --- octave-matgeom-1.2.2/inst/meshes3d/createSoccerBall.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createSoccerBall.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createStellatedMesh.m octave-matgeom-1.2.3/inst/meshes3d/createStellatedMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/createStellatedMesh.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createStellatedMesh.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createTetrahedron.m octave-matgeom-1.2.3/inst/meshes3d/createTetrahedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createTetrahedron.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createTetrahedron.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/createTetrakaidecahedron.m octave-matgeom-1.2.3/inst/meshes3d/createTetrakaidecahedron.m --- octave-matgeom-1.2.2/inst/meshes3d/createTetrakaidecahedron.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/createTetrakaidecahedron.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/cube.ply octave-matgeom-1.2.3/inst/meshes3d/cube.ply --- octave-matgeom-1.2.2/inst/meshes3d/cube.ply 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/cube.ply 2021-06-01 09:14:25.998813871 +0000 @@ -0,0 +1,24 @@ +ply +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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/curveToMesh.m octave-matgeom-1.2.3/inst/meshes3d/curveToMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/curveToMesh.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/curveToMesh.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function [vertices, faces] = curveToMesh(curve, varargin) -%CURVETOMESH Create a mesh surrounding a 3D curve. +% Create a mesh surrounding a 3D curve. % % [V, F] = curveToMesh(CURVE) % Computes the vertices and the faces of the mesh surrounding the diff -Nru octave-matgeom-1.2.2/inst/meshes3d/cutMeshByPlane.m octave-matgeom-1.2.3/inst/meshes3d/cutMeshByPlane.m --- octave-matgeom-1.2.2/inst/meshes3d/cutMeshByPlane.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/cutMeshByPlane.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/cylinderMesh.m octave-matgeom-1.2.3/inst/meshes3d/cylinderMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/cylinderMesh.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/cylinderMesh.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,16 +26,26 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = cylinderMesh(cyl, varargin) -%CYLINDERMESH Create a 3D mesh representing a cylinder. +% Create a 3D mesh representing a cylinder. % -% [V F] = cylinderMesh(CYL) +% [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 circles 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); +% [v, f] = cylinderMesh(cyl); % figure;drawMesh(v, f, 'FaceColor', 'r'); % view(3); axis equal; % @@ -46,7 +56,7 @@ % p3 = [30 30 90]; % [v1 f1] = cylinderMesh([p0 p1 25]); % [v2 f2] = cylinderMesh([p0 p2 25]); -% [v3 f3] = cylinderMesh([p0 p3 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'); @@ -59,10 +69,26 @@ % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inra.fr % Created: 2012-10-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2012 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); @@ -72,12 +98,12 @@ [theta, phi, rho] = cart2sph2d(p2 - p1); % parametrisation on x -t = linspace(0, 2*pi, 20); +t = linspace(0, 2*pi, NoPP); lx = r * cos(t); ly = r * sin(t); % parametrisation on z -lz = linspace(0, rho, 10); +lz = linspace(0, rho, nRho); % generate surface grids x = repmat(lx, [length(lz) 1]); @@ -85,11 +111,25 @@ z = repmat(lz', [1 length(t)]); % transform points -trans = localToGlobal3d(p1, theta, phi, 0); +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 + toe.vertices = [x(1,1:NoPP-1); y(1,1:NoPP-1); z(1,1:NoPP-1)]'; + toe.vertices(NoPP,:) = transformPoint3d([0 0 0], trans); + toe.faces = [repmat(NoPP, 1, NoPP-1); [2:NoPP-1 1]; 1:NoPP-1]'; + + top.vertices = [x(end,1:NoPP-1); y(end,1:NoPP-1); z(end,1:NoPP-1)]'; + top.vertices(NoPP,:) = transformPoint3d([0 0 rho], trans); + top.faces = fliplr(toe.faces); + + [vertices, faces] = concatenateMeshes(vertices, triangulateFaces(faces), ... + toe.vertices, toe.faces, top.vertices, top.faces); +end + % format output varargout = formatMeshOutput(nargout, vertices, faces); diff -Nru octave-matgeom-1.2.2/inst/meshes3d/distancePointMesh.m octave-matgeom-1.2.3/inst/meshes3d/distancePointMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/distancePointMesh.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/distancePointMesh.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/dodecahedron.ply octave-matgeom-1.2.3/inst/meshes3d/dodecahedron.ply --- octave-matgeom-1.2.2/inst/meshes3d/dodecahedron.ply 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/dodecahedron.ply 2021-06-01 09:14:25.998813871 +0000 @@ -0,0 +1,42 @@ +ply +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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/drawFaceNormals.m octave-matgeom-1.2.3/inst/meshes3d/drawFaceNormals.m --- octave-matgeom-1.2.2/inst/meshes3d/drawFaceNormals.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/drawFaceNormals.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/drawMesh.m octave-matgeom-1.2.3/inst/meshes3d/drawMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/drawMesh.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/drawMesh.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/drawPolyhedron.m octave-matgeom-1.2.3/inst/meshes3d/drawPolyhedron.m --- octave-matgeom-1.2.2/inst/meshes3d/drawPolyhedron.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/drawPolyhedron.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/ellipsoidMesh.m octave-matgeom-1.2.3/inst/meshes3d/ellipsoidMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/ellipsoidMesh.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/ellipsoidMesh.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -37,7 +37,7 @@ % % % See also -% meshes3d, drawEllipsoid, sphereMesh, inertiaEllipsoid +% meshes3d, drawEllipsoid, sphereMesh, equivalentEllipsoid % % ------ diff -Nru octave-matgeom-1.2.2/inst/meshes3d/ensureManifoldMesh.m octave-matgeom-1.2.3/inst/meshes3d/ensureManifoldMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/ensureManifoldMesh.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/ensureManifoldMesh.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/fillMeshFaces.m octave-matgeom-1.2.3/inst/meshes3d/fillMeshFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/fillMeshFaces.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/fillMeshFaces.m 2021-06-01 09:14:26.102813479 +0000 @@ -0,0 +1,117 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-04-16, using Matlab 9.7.0.1247435 (R2019b) Update 2 +% Copyright 2020 INRAE. + +%% 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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/icosahedron.ply octave-matgeom-1.2.3/inst/meshes3d/icosahedron.ply --- octave-matgeom-1.2.2/inst/meshes3d/icosahedron.ply 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/icosahedron.ply 2021-06-01 09:14:25.998813871 +0000 @@ -0,0 +1,42 @@ +ply +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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/intersectEdgeMesh3d.m octave-matgeom-1.2.3/inst/meshes3d/intersectEdgeMesh3d.m --- octave-matgeom-1.2.2/inst/meshes3d/intersectEdgeMesh3d.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/intersectEdgeMesh3d.m 2021-06-01 09:14:26.090813524 +0000 @@ -0,0 +1,67 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 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, :); diff -Nru octave-matgeom-1.2.2/inst/meshes3d/intersectLineMesh3d.m octave-matgeom-1.2.3/inst/meshes3d/intersectLineMesh3d.m --- octave-matgeom-1.2.2/inst/meshes3d/intersectLineMesh3d.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/intersectLineMesh3d.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,8 +25,8 @@ ## 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] = intersectLineMesh3d(line, vertices, faces, varargin) -%INTERSECTLINEMESH3D Intersection points of a 3D line with a mesh. +function [points, pos, faceInds] = intersectLineMesh3d(line, vertices, varargin) +% 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 @@ -51,17 +51,29 @@ % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2011-12-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. -% tolerance for detecting if a point is +% tolerance for detecting if a point is on line or within edge bounds tol = 1e-12; + +% parsing if ~isempty(varargin) - tol = varargin{1}; + 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 @@ -77,13 +89,13 @@ n = normalizeVector3d(crossProduct3d(u, v)); % direction vector of line -dir = line(4:6); +dv = line(4:6); % vector between triangle origin and line origin w0 = bsxfun(@minus, line(1:3), t0); a = -dot(n, w0, 2); -b = dot(n, repmat(dir, size(n, 1), 1), 2); +b = dot(n, repmat(dv, size(n, 1), 1), 2); valid = abs(b) > tol & vectorNorm3d(n) > tol; @@ -93,7 +105,7 @@ pos = a ./ b; % coordinates of intersection point -points = bsxfun(@plus, line(1:3), bsxfun(@times, pos, dir)); +points = bsxfun(@plus, line(1:3), bsxfun(@times, pos, dv)); %% test if intersection point is inside triangle @@ -113,14 +125,12 @@ % test first coordinate s = (uv .* wv - vv .* wu) ./ D; -% ind1 = s < 0.0 | s > 1.0; ind1 = s < -tol | s > (1.0 + tol); points(ind1, :) = NaN; pos(ind1) = NaN; % test second coordinate, and third triangle edge t = (uv .* wu - uu .* wv) ./ D; -% ind2 = t < 0.0 | (s + t) > 1.0; ind2 = t < -tol | (s + t) > (1.0 + tol); points(ind2, :) = NaN; pos(ind2) = NaN; @@ -129,10 +139,12 @@ inds = ~ind1 & ~ind2 & valid; points = points(inds, :); -pos = pos(inds); -faceInds = find(inds); - -% convert to face indices of original mesh -if ~isempty(tri2Face) - faceInds = tri2Face(faceInds); -end +if nargout > 1 + pos = pos(inds); + faceInds = find(inds); + + % convert to face indices of original mesh + if ~isempty(tri2Face) + faceInds = tri2Face(faceInds); + end +end diff -Nru octave-matgeom-1.2.2/inst/meshes3d/intersectPlaneMesh.m octave-matgeom-1.2.3/inst/meshes3d/intersectPlaneMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/intersectPlaneMesh.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/intersectPlaneMesh.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/isManifoldMesh.m octave-matgeom-1.2.3/inst/meshes3d/isManifoldMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/isManifoldMesh.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/isManifoldMesh.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/isPointInMesh.m octave-matgeom-1.2.3/inst/meshes3d/isPointInMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/isPointInMesh.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/isPointInMesh.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/mergeCoplanarFaces.m octave-matgeom-1.2.3/inst/meshes3d/mergeCoplanarFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/mergeCoplanarFaces.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/mergeCoplanarFaces.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/mergeMeshVertices.m octave-matgeom-1.2.3/inst/meshes3d/mergeMeshVertices.m --- octave-matgeom-1.2.2/inst/meshes3d/mergeMeshVertices.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/mergeMeshVertices.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshAdjacencyMatrix.m octave-matgeom-1.2.3/inst/meshes3d/meshAdjacencyMatrix.m --- octave-matgeom-1.2.2/inst/meshes3d/meshAdjacencyMatrix.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshAdjacencyMatrix.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshBoundaryEdgeIndices.m octave-matgeom-1.2.3/inst/meshes3d/meshBoundaryEdgeIndices.m --- octave-matgeom-1.2.2/inst/meshes3d/meshBoundaryEdgeIndices.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshBoundaryEdgeIndices.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshBoundary.m octave-matgeom-1.2.3/inst/meshes3d/meshBoundary.m --- octave-matgeom-1.2.2/inst/meshes3d/meshBoundary.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshBoundary.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshBoundaryVertexIndices.m octave-matgeom-1.2.3/inst/meshes3d/meshBoundaryVertexIndices.m --- octave-matgeom-1.2.2/inst/meshes3d/meshBoundaryVertexIndices.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshBoundaryVertexIndices.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshComplement.m octave-matgeom-1.2.3/inst/meshes3d/meshComplement.m --- octave-matgeom-1.2.2/inst/meshes3d/meshComplement.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshComplement.m 2021-06-01 09:14:26.094813507 +0000 @@ -0,0 +1,69 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-01-22, using Matlab 9.7.0.1247435 (R2019b) Update 2 +% Copyright 2020 INRAE. + +% 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); diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshDihedralAngles.m octave-matgeom-1.2.3/inst/meshes3d/meshDihedralAngles.m --- octave-matgeom-1.2.2/inst/meshes3d/meshDihedralAngles.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshDihedralAngles.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshEdgeFaces.m octave-matgeom-1.2.3/inst/meshes3d/meshEdgeFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/meshEdgeFaces.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshEdgeFaces.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshEdgeLength.m octave-matgeom-1.2.3/inst/meshes3d/meshEdgeLength.m --- octave-matgeom-1.2.2/inst/meshes3d/meshEdgeLength.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshEdgeLength.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshEdges.m octave-matgeom-1.2.3/inst/meshes3d/meshEdges.m --- octave-matgeom-1.2.2/inst/meshes3d/meshEdges.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshEdges.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFaceAdjacency.m octave-matgeom-1.2.3/inst/meshes3d/meshFaceAdjacency.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFaceAdjacency.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFaceAdjacency.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFaceAreas.m octave-matgeom-1.2.3/inst/meshes3d/meshFaceAreas.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFaceAreas.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFaceAreas.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFaceCentroids.m octave-matgeom-1.2.3/inst/meshes3d/meshFaceCentroids.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFaceCentroids.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFaceCentroids.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFaceEdges.m octave-matgeom-1.2.3/inst/meshes3d/meshFaceEdges.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFaceEdges.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFaceEdges.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFace.m octave-matgeom-1.2.3/inst/meshes3d/meshFace.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFace.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFace.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFaceNormals.m octave-matgeom-1.2.3/inst/meshes3d/meshFaceNormals.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFaceNormals.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFaceNormals.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFaceNumber.m octave-matgeom-1.2.3/inst/meshes3d/meshFaceNumber.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFaceNumber.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFaceNumber.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshFacePolygons.m octave-matgeom-1.2.3/inst/meshes3d/meshFacePolygons.m --- octave-matgeom-1.2.2/inst/meshes3d/meshFacePolygons.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshFacePolygons.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshSilhouette.m octave-matgeom-1.2.3/inst/meshes3d/meshSilhouette.m --- octave-matgeom-1.2.2/inst/meshes3d/meshSilhouette.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshSilhouette.m 2021-06-01 09:14:26.098813493 +0000 @@ -0,0 +1,113 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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 + +% --------- +% Authors: oqilipo +% Created: 2020-07-29 +% Copyright 2020 + +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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshSurfaceArea.m octave-matgeom-1.2.3/inst/meshes3d/meshSurfaceArea.m --- octave-matgeom-1.2.2/inst/meshes3d/meshSurfaceArea.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshSurfaceArea.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,8 +25,8 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function area = meshSurfaceArea(vertices, edges, faces) -%MESHSURFACEAREA Surface area of a polyhedral mesh. +function area = meshSurfaceArea(varargin) +% Surface area of a polyhedral mesh. % % S = meshSurfaceArea(V, F) % S = meshSurfaceArea(V, E, F) @@ -56,15 +56,12 @@ % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2010-10-13, using Matlab 7.9.0.529 (R2009b) % Copyright 2010 INRA - Cepia Software Platform. - -% check input number -if nargin == 2 - faces = edges; -end +% parse input arguments +[vertices, faces] = parseMeshData(varargin{:}); % pre-compute normals normals = normalizeVector3d(meshFaceNormals(vertices, faces)); diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshVertexClustering.m octave-matgeom-1.2.3/inst/meshes3d/meshVertexClustering.m --- octave-matgeom-1.2.2/inst/meshes3d/meshVertexClustering.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshVertexClustering.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshVertexNormals.m octave-matgeom-1.2.3/inst/meshes3d/meshVertexNormals.m --- octave-matgeom-1.2.2/inst/meshes3d/meshVertexNormals.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshVertexNormals.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/meshVolume.m octave-matgeom-1.2.3/inst/meshes3d/meshVolume.m --- octave-matgeom-1.2.2/inst/meshes3d/meshVolume.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/meshVolume.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,8 +25,8 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function vol = meshVolume(vertices, edges, faces) -%MESHVOLUME Volume of the space enclosed by a polygonal mesh. +function vol = meshVolume(varargin) +% (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 @@ -47,21 +47,19 @@ % 1 % % See also -% meshes3d, meshSurfaceArea, tetrahedronVolume +% meshes3d, meshSurfaceArea, tetrahedronVolume, meshComplement % ------ % Author: David Legland -% e-mail: david.legland@nantes.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2012-10-01, using Matlab 7.9.0.529 (R2009b) % Copyright 2012 INRA - Cepia Software Platform. % HISTORY % 2013-08-16 speed improvement by Sven Holcombe -% check input number -if nargin == 2 - faces = edges; -end +% parse input +[vertices, faces] = parseMeshData(varargin{:}); % ensure mesh has triangle faces faces = triangulateFaces(faces); diff -Nru octave-matgeom-1.2.2/inst/meshes3d/minConvexHull.m octave-matgeom-1.2.3/inst/meshes3d/minConvexHull.m --- octave-matgeom-1.2.2/inst/meshes3d/minConvexHull.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/minConvexHull.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/polyhedra.m octave-matgeom-1.2.3/inst/meshes3d/polyhedra.m --- octave-matgeom-1.2.2/inst/meshes3d/polyhedra.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/polyhedra.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/polyhedronCentroid.m octave-matgeom-1.2.3/inst/meshes3d/polyhedronCentroid.m --- octave-matgeom-1.2.2/inst/meshes3d/polyhedronCentroid.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/polyhedronCentroid.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/polyhedronMeanBreadth.m octave-matgeom-1.2.3/inst/meshes3d/polyhedronMeanBreadth.m --- octave-matgeom-1.2.2/inst/meshes3d/polyhedronMeanBreadth.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/polyhedronMeanBreadth.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/polyhedronNormalAngle.m octave-matgeom-1.2.3/inst/meshes3d/polyhedronNormalAngle.m --- octave-matgeom-1.2.2/inst/meshes3d/polyhedronNormalAngle.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/polyhedronNormalAngle.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/polyhedronSlice.m octave-matgeom-1.2.3/inst/meshes3d/polyhedronSlice.m --- octave-matgeom-1.2.2/inst/meshes3d/polyhedronSlice.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/polyhedronSlice.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/private/formatMeshOutput.m octave-matgeom-1.2.3/inst/meshes3d/private/formatMeshOutput.m --- octave-matgeom-1.2.2/inst/meshes3d/private/formatMeshOutput.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/private/formatMeshOutput.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/private/localToGlobal3d.m octave-matgeom-1.2.3/inst/meshes3d/private/localToGlobal3d.m --- octave-matgeom-1.2.2/inst/meshes3d/private/localToGlobal3d.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/private/localToGlobal3d.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/private/parseMeshData.m octave-matgeom-1.2.3/inst/meshes3d/private/parseMeshData.m --- octave-matgeom-1.2.2/inst/meshes3d/private/parseMeshData.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/private/parseMeshData.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/private/progressbar.m octave-matgeom-1.2.3/inst/meshes3d/private/progressbar.m --- octave-matgeom-1.2.2/inst/meshes3d/private/progressbar.m 2019-12-04 12:15:22.879632653 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/private/progressbar.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/readMesh.m octave-matgeom-1.2.3/inst/meshes3d/readMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/readMesh.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/readMesh.m 2021-06-01 09:14:26.102813479 +0000 @@ -0,0 +1,74 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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(fileName) +% 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'. +% +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-11-20, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + +[~, ~, ext] = fileparts(fileName); +switch lower(ext) + case '.off' + mesh = readMesh_off(fileName); + case '.ply' + mesh = readMesh_ply(fileName); + case '.stl' + mesh = readMesh_stl(fileName); + otherwise + error('Unrecognized file format for rezading mesh: %s', ext); +end + +% format output arguments +if nargout < 2 + varargout = {mesh}; +else + varargout = {mesh.vertices, mesh.faces}; +end diff -Nru octave-matgeom-1.2.2/inst/meshes3d/readMesh_off.m octave-matgeom-1.2.3/inst/meshes3d/readMesh_off.m --- octave-matgeom-1.2.2/inst/meshes3d/readMesh_off.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/readMesh_off.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,9 +26,16 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = readMesh_off(fileName) -%READMESH_OFF Read mesh data stored in OFF format. +% Read mesh data stored in OFF format. % -% [VERTICES FACES] = readMesh_off(FILNAME) +% [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'); @@ -36,7 +43,8 @@ % view([5 80]); light; lighting gouraud % % See also -% meshes3d, writeMesh_off, drawMesh +% meshes3d, readMesh, writeMesh_off, drawMesh +% % ------ % Author: David Legland @@ -44,6 +52,9 @@ % Created: 2011-12-20, using Matlab 7.9.0.529 (R2009b) % Copyright 2011 INRA - Cepia Software Platform. + +%% Read header + % open file f = fopen(fileName, 'r'); if f == -1 @@ -65,7 +76,7 @@ nFaces = vals(2); -% read vertex data +%% Read vertex data [vertices, count] = fscanf(f, '%f ', [3 nVertices]); if count ~= nVertices * 3 error('matGeom:readMesh_off:FileFormatError', ... @@ -73,50 +84,68 @@ end vertices = vertices'; -% % read face data (face start by index) -% [faces, count] = fscanf(f, '%d %d %d %d\n', [4 nf]); -% if count ~= nf * 4 -% error('matGeom:readMesh_off:FileFormatError', ... -% ['Could not read all the ' num2str(nf) ' faces']); -% end - -% allocate memory -faces = cell(1, nFaces); - -% iterate over faces -for iFace = 1:nFaces - % read next line - line = fgetl(f); - if line == -1 + +%% 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 + % attenpt 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', ... - 'Unexpected end of file'); + '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'); - % parse vertex indices for current face - tokens = split(line); - nv = str2double(tokens{1}); - face = zeros(1,nv); - for iv = 1:nv - face(iv) = str2double(tokens{iv+1}) + 1; + 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 - faces{iFace} = face; end -% close the file -fclose(f); - -%% Post-process faces - -% % clean up: remove index, and use 1-indexing -% faces = faces(2:4, :)' + 1; - -% if faces all have same number of vertices, convert to Nf-by-N array -nVertices = cellfun(@length, faces); -if all(nVertices == nVertices(1)) - faces = cell2mat(faces(:)); -end +%% Post-processing +% close the file +fclose(f); % format output arguments if nargout < 2 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/readMesh_ply.m octave-matgeom-1.2.3/inst/meshes3d/readMesh_ply.m --- octave-matgeom-1.2.2/inst/meshes3d/readMesh_ply.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/readMesh_ply.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## 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. +% Read mesh data stored in PLY (Stanford triangle) format. % % [V, F] = readMesh_ply(FNAME) % @@ -34,173 +34,503 @@ % readMesh_ply % % References -% * http://paulbourke.net/dataformats/ply/ +% Wrapper function for Gabriel Peyré's read_ply that is a wrapper +% function of Pascal Getreuer's plyread. % % See also -% meshes3d, readMesh_off - +% meshes3d, readMesh, readMesh_off, readMesh_stl + % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2018-04-26, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018 INRA - Cepia Software Platform. %% open file f = fopen(fileName, 'r'); -if f == -1 +if f == -1 error('matGeom:readMesh_ply:FileNotFound', ... ['Could not find file: ' fileName]); end -%% Read Header +[vertices, faces] = read_ply(fileName); +varargout = formatMeshOutput(nargout, vertices, faces); -% check file format -line = fgetl(f); % -1 if eof -if ~strcmpi(strtrim(line), 'PLY') - error('matGeom:readMesh_ply:FileFormatError', ... - 'Not a valid PLY file'); end -% one line for ascii / binary -line = fgetl(f); -tokens = split(line); -if ~strcmpi(tokens{1}, 'format') - error('matGeom:readMesh_ply:FileFormatError', ... - 'Second line must specify PLY format'); +function [vertex,face,d,c] = read_ply(filename) +% read_ply - read data from PLY file. +% +% [vertex,face] = read_ply(filename); +% +% 'vertex' is a 'nb.vert x 3' array specifying the position of the vertices. +% 'face' is a 'nb.face x 3' array specifying the connectivity of the mesh. +% +% Copyright (c) 2003 Gabriel Peyré + +possibleFacePropertyNames = ... + {'vertex_indices','vertex_indexes','vertex_index','indices','indexes'}; + +[d,c] = plyread(filename); +facePropertyNameIdx = find(matches(possibleFacePropertyNames, fieldnames(d.face))); +assert(length(facePropertyNameIdx) == 1) +vi = d.face.(possibleFacePropertyNames{facePropertyNameIdx}); +lengths = cellfun('length',vi); +maxLength = max(lengths); +if all(maxLength == lengths) + face = cell2mat(vi)+1; +else + face = cellfun(@(x) x+1, vi, 'uni',0); end -if ~strcmpi(tokens{2}, 'ascii') - error('matGeom:readMesh_ply:FileFormatError', ... - 'Does not support binary PLY file'); +vertex = [d.vertex.x, d.vertex.y, d.vertex.z]; + end -% initialize element types -typeCount = 0; -elementNames = {}; -elementNumbers = []; -elementProperties = {}; -elementPropertyNames = {}; -elementPropertyTypes = {}; -% read the header elements -while true - % read next line - line = fgetl(f); - if line == -1 - error('matGeom:readMesh_ply:FileFormatError', ... - 'Unexpected end of file'); +function [Elements,varargout] = plyread(Path,Str) +%PLYREAD Read a PLY 3D data file. +% [DATA,COMMENTS] = PLYREAD(FILENAME) reads a version 1.0 PLY file +% FILENAME and returns a structure DATA. The fields in this structure +% are defined by the PLY header; each element type is a field and each +% element property is a subfield. If the file contains any comments, +% they are returned in a cell string array COMMENTS. +% +% [TRI,PTS] = PLYREAD(FILENAME,'tri') or +% [TRI,PTS,DATA,COMMENTS] = PLYREAD(FILENAME,'tri') converts vertex +% and face data into triangular connectivity and vertex arrays. The +% mesh can then be displayed using the TRISURF command. +% +% Note: This function is slow for large mesh files (+50K faces), +% especially when reading data with list type properties. +% +% Example: +% [Tri,Pts] = PLYREAD('cow.ply','tri'); +% trisurf(Tri,Pts(:,1),Pts(:,2),Pts(:,3)); +% colormap(gray); axis equal; +% +% See also: PLYWRITE + +% Pascal Getreuer 2004 + +[fid,Msg] = fopen(Path,'rt'); % open file in read text mode + +if fid == -1, error(Msg); end + +Buf = fscanf(fid,'%s',1); +if ~strcmp(Buf,'ply') + fclose(fid); + error('Not a PLY file.'); +end + +%% read header +ftell(fid); +Format = ''; +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 + +while 1 + Buf = fgetl(fid); % read one line from file + Token = split(Buf); % split line into tokens + Count = length(Token); % count tokens + + if Count % parse line + switch lower(Token{1}) + case 'format' % read data format + if Count >= 2 + Format = lower(Token{2}); + if Count == 3 && ~strcmp(Token{3},'1.0') + fclose(fid); + error('Only PLY format version 1.0 supported.'); + end + end + case 'comment' % read file comment + NumComments = NumComments + 1; + Comments{NumComments} = ''; %#ok + for i = 2:Count + Comments{NumComments} = [Comments{NumComments},Token{i},' ']; + end + case 'element' % element name + if Count >= 3 + if isfield(Elements,Token{2}) + fclose(fid); + error(['Duplicate element name, ''',Token{2},'''.']); + end + + NumElements = NumElements + 1; + NumProperties = 0; + Elements.(Token{2}) = []; + PropertyTypes.(Token{2}) =[]; + ElementNames{NumElements} = Token{2}; %#ok + PropertyNames.(Token{2}) = {}; + CurElement = Token{2}; + ElementCount(NumElements) = str2double(Token{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) && Count >= 3 + NumProperties = NumProperties + 1; + + if isfield(Elements.(CurElement),Token{Count}) + fclose(fid); + error(['Duplicate property name, ''',CurElement,'.',Token{2},'''.']); + end + + % add property subfield to Elements + Elements.(CurElement).(Token{Count}) = []; + % add property subfield to PropertyTypes and save type + PropertyTypes.(CurElement).(Token{Count}) = Token(2:Count-1); + % record property name order + PropertyNames.(CurElement){NumProperties} = Token{Count}; + 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 from while loop + break; + end + end +end + +%% set reading for specified data format +if isempty(Format) + warning('Data format unspecified, assuming ASCII.'); + Format = 'ascii'; +end + +switch Format + case 'ascii' + Format = 0; + case 'binary_little_endian' + Format = 1; + case 'binary_big_endian' + Format = 2; + otherwise + fclose(fid); + error(['Data format ''',Format,''' not supported.']); +end + +if ~Format + Buf = fscanf(fid,'%f'); % read the rest of the file as ASCII data + BufOff = 1; +else + % reopen the file in read binary mode + fclose(fid); + + if Format == 1 + fid = fopen(Path,'r','ieee-le.l64'); % little endian + else + fid = fopen(Path,'r','ieee-be.l64'); % big endian end - % check end of header items - if strcmpi(strtrim(line), 'end_header') - break; + % 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 - % extract tokens - tokens = split(line); + +%% 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'}; +SizeOf = [1,1,2,2,4,4,4,8]; % size in bytes of each type + +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}); - % switch processing depending on first token - switch lower(tokens{1}) - case 'comment' - % nothing to do... - continue; + %% read ASCII data + if ~Format + Type = zeros(1,NumProperties); + for j = 1:NumProperties + Token = CurPropertyTypes.(CurPropertyNames{j}); - case 'element' - % switch to the definition of a new element - typeCount = typeCount + 1; - elementNames = [elementNames tokens(2)]; %#ok - count = str2double(tokens{3}); - elementNumbers = [elementNumbers count]; %#ok - elementProperties{typeCount} = {}; %#ok - elementPropertyNames{typeCount} = {}; %#ok - elementPropertyTypes{typeCount} = {}; %#ok + if strcmpi(Token{1},'list') + Type(j) = 1; + end + end + + % parse buffer + if ~any(Type) + % no list types + Data = reshape(Buf(BufOff:BufOff+ElementCount(i)*NumProperties-1),NumProperties,ElementCount(i))'; + BufOff = BufOff + ElementCount(i)*NumProperties; + else + ListData = cell(NumProperties,1); - case 'property' - % add a property to the current element - if typeCount < 1 - error('matGeom:readMesh_ply:FileFormatError', ... - 'No element was defined before specifying a property'); + for k = 1:NumProperties + ListData{k} = cell(ElementCount(i),1); end - % nale is the last token - names = elementPropertyNames{typeCount}; - names = [names tokens(end)]; %#ok - elementPropertyNames{typeCount} = names; %#ok + % list type + for j = 1:ElementCount(i) + for k = 1:NumProperties + if ~Type(k) + Data(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 + Token = CurPropertyTypes.(CurPropertyNames{j}); - types = elementPropertyTypes{typeCount}; - typeString = tokens{2}; - for i = 3:length(tokens)-1 - typeString = [typeString ' ' tokens{i}]; %#ok + if ~strcmp(Token{1},'list') % non-list type + tmp = rem(find(matches(PlyTypeNames,Token{1}))-1,8)+1; + + if ~isempty(tmp) + TypeSize(j) = SizeOf(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, ''',Token{1},''', in ', ... + ElementNames{i},'.',CurPropertyNames{j},'.']); + end + else % list type + if length(Token) == 3 + ListFlag = 1; + SameFlag = 0; + tmp = rem(find(matches(PlyTypeNames,Token{2}))-1,8)+1; + tmp2 = rem(find(matches(PlyTypeNames,Token{3}))-1,8)+1; + + if ~isempty(tmp) && ~isempty(tmp2) + TypeSize(j) = SizeOf(tmp); + Type{j} = MatlabTypeNames{tmp}; + TypeSize2(j) = SizeOf(tmp2); + Type2{j} = MatlabTypeNames{tmp2}; + else + fclose(fid); + error(['Unknown property data type, ''list ',Token{2},' ',Token{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) + Data = fread(fid,[NumProperties,ElementCount(i)],Type{1})'; + else + % no list types, mixed type + Data = zeros(ElementCount(i),NumProperties); + + for j = 1:ElementCount(i) + for k = 1:NumProperties + Data(j,k) = fread(fid,1,Type{k}); + end + end end - types = [types {typeString}]; %#ok - elementPropertyTypes{typeCount} = types; %#ok + else + ListData = cell(NumProperties,1); - otherwise - error('matGeom:readMesh_ply:FileFormatError', ... - ['Unknown keyword: ' tokens{1}]); + for k = 1:NumProperties + ListData{k} = cell(ElementCount(i),1); + end + if NumProperties == 1 + BufSize = 512; + SkipNum = 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},SkipNum*TypeSize2(1)); + Miss = find(Buf ~= SkipNum); % 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,[SkipNum,BufSize],[int2str(SkipNum),'*',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 SkipNum + Buf2 = fread(fid,[SkipNum,Miss(1)-1],[int2str(SkipNum),'*',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 + SkipNum = Buf(Miss(1)); + j = j + 1; + ListData{1}{j} = fread(fid,[1,SkipNum],Type2{1}); + BufSize = ceil(0.6*BufSize); + end + end + else + % list type(s), multiple properties (slow) + Data = zeros(ElementCount(i),NumProperties); + + for j = 1:ElementCount(i) + for k = 1:NumProperties + if isempty(Type2{k}) + Data(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 (~Format && ~Type(k)) || (Format && isempty(Type2{k})) + Elements.(ElementNames{i}).(CurPropertyNames{k}) = Data(:,k); + else + Elements.(ElementNames{i}).(CurPropertyNames{k}) = ListData{k}; + end end - -end - - -%% Read Vertices - -% read vertex data -nVertices = elementNumbers(1); -[vertices, count] = fscanf(f, '%f ', [3 nVertices]); -if count ~= nVertices * 3 - error('matGeom:readMesh_ply:FileFormatError', ... - ['Could not read all the ' num2str(nVertices) ' vertices']); end -vertices = vertices'; - -%% Read Faces +clear Data ListData; +fclose(fid); -% allocate memory -nFaces = elementNumbers(2); -faces = cell(1, nFaces); - -% iterate over faces -for iFace = 1:nFaces - % read next line - line = fgetl(f); - if line == -1 - error('matGeom:readMesh_ply:FileFormatError', ... - 'Unexpected end of file'); +if (nargin > 1 && strcmpi(Str,'Tri')) || nargout > 2 + % find vertex element field + Name = {'vertex','Vertex','point','Point','pts','Pts'}; + Names = []; + + for i = 1:length(Name) + if any(strcmp(ElementNames,Name{i})) + Names = PropertyNames.(Name{i}); + Name = Name{i}; + break; + end end - % parse vertex indices for current face - tokens = split(line); - nv = str2double(tokens{1}); - face = zeros(1,nv); - for iv = 1:nv - face(iv) = str2double(tokens{iv+1}) + 1; + if any(strcmp(Names,'x')) && any(strcmp(Names,'y')) && any(strcmp(Names,'z')) + varargout{1} = [Elements.(Name).x, Elements.(Name).y, Elements.(Name).z]; + else + varargout{1} = zeros(1,3); end - faces{iFace} = face; -end - -% close the file -fclose(f); - - -%% Post-process faces - -% if faces all have same number of vertices, convert to Nf-by-N array -nv = cellfun(@length, faces); -if all(nv == nv(1)) - faces = cell2mat(faces(:)); + + varargout{2} = Elements; + varargout{3} = Comments; + Elements = []; + + % find face element field + Name = {'face','Face','poly','Poly','tri','Tri'}; + Names = []; + + for i = 1:length(Name) + if any(strcmp(ElementNames,Name{i})) + Names = PropertyNames.(Name{i}); + Name = Name{i}; + break; + end + end + + if ~isempty(Names) + % find vertex indices property subfield + PropertyName = {'vertex_indices','vertex_indexes','vertex_index','indices','indexes'}; + + for i = 1:length(PropertyName) + if any(strcmp(Names,PropertyName{i})) + PropertyName = PropertyName{i}; + break; + end + end + + if ~iscell(PropertyName) + % convert face index lists to triangular connectivity + FaceIndices = varargout{2}.(Name).PropertyName; + N = length(FaceIndices); + Elements = zeros(N*2,3); + Extra = 0; + + for k = 1:N + Elements(k,:) = FaceIndices{k}(1:3); + + for j = 4:length(FaceIndices{k}) + Extra = Extra + 1; + Elements(N + Extra,:) = [Elements(k,[1,j-1]),FaceIndices{k}(j)]; + end + end + Elements = Elements(1:N+Extra,:) + 1; + end + end +else + varargout{1} = Comments; end - -%% Format mesh output - -% format output arguments -if nargout < 2 - mesh.vertices = vertices; - mesh.faces = faces; - varargout = {mesh}; -else - varargout = {vertices, faces}; end diff -Nru octave-matgeom-1.2.2/inst/meshes3d/readMesh_stl.m octave-matgeom-1.2.3/inst/meshes3d/readMesh_stl.m --- octave-matgeom-1.2.2/inst/meshes3d/readMesh_stl.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/readMesh_stl.m 2021-06-01 09:14:26.090813524 +0000 @@ -0,0 +1,55 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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(fileName) +%READMESH_STL Read mesh data stored in STL format. +% +% [VERTICES, FACES] = readMesh_stl(FNAME) +% +% MESH = readMesh_stl(FNAME) +% +% Example +% readMesh_stl +% +% References +% Wrapper function for MATLAB's build-in stlread. +% +% See also +% meshes3d, readMesh, readMesh_off, readMesh_ply + +% ------ +% Author: oqilipo +% Created: 2021-02-12, using Matlab 9.9.0.1538559 (R2020b) +% Copyright 2021 + +TR = stlread(fileName); +vertices = TR.Points; +faces = TR.ConnectivityList; + +varargout = formatMeshOutput(nargout, vertices, faces); + +end diff -Nru octave-matgeom-1.2.2/inst/meshes3d/removeDuplicateFaces.m octave-matgeom-1.2.3/inst/meshes3d/removeDuplicateFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/removeDuplicateFaces.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/removeDuplicateFaces.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/removeInvalidBorderFaces.m octave-matgeom-1.2.3/inst/meshes3d/removeInvalidBorderFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/removeInvalidBorderFaces.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/removeInvalidBorderFaces.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/removeMeshEars.m octave-matgeom-1.2.3/inst/meshes3d/removeMeshEars.m --- octave-matgeom-1.2.2/inst/meshes3d/removeMeshEars.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/removeMeshEars.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/removeMeshFaces.m octave-matgeom-1.2.3/inst/meshes3d/removeMeshFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/removeMeshFaces.m 2019-12-04 12:15:22.859632263 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/removeMeshFaces.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -70,7 +70,7 @@ p = inputParser; isIndexToFaces = @(x) ... - (islogical(x) && isequal(length(fI), size(f,1))) || ... + (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); diff -Nru octave-matgeom-1.2.2/inst/meshes3d/removeMeshVertices.m octave-matgeom-1.2.3/inst/meshes3d/removeMeshVertices.m --- octave-matgeom-1.2.2/inst/meshes3d/removeMeshVertices.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/removeMeshVertices.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/smoothMesh.m octave-matgeom-1.2.3/inst/meshes3d/smoothMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/smoothMesh.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/smoothMesh.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/sphereMesh.m octave-matgeom-1.2.3/inst/meshes3d/sphereMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/sphereMesh.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/sphereMesh.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = sphereMesh(sphere, varargin) -%SPHEREMESH Create a 3D mesh representing a sphere. +% 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]. diff -Nru octave-matgeom-1.2.2/inst/meshes3d/splitMesh.m octave-matgeom-1.2.3/inst/meshes3d/splitMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/splitMesh.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/splitMesh.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -36,7 +36,10 @@ % possible % % ... = splitMesh(..., 'mostVertices') returns only the component with -% the most vertices +% 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]); @@ -72,9 +75,10 @@ end parser = inputParser; -validStrings = {'all','mostVertices'}; +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); @@ -86,9 +90,15 @@ end % output parsing -switch parser.Results.components +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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/steinerPolytope.m octave-matgeom-1.2.3/inst/meshes3d/steinerPolytope.m --- octave-matgeom-1.2.2/inst/meshes3d/steinerPolytope.m 2019-12-04 12:15:22.875632575 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/steinerPolytope.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/subdivideMesh.m octave-matgeom-1.2.3/inst/meshes3d/subdivideMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/subdivideMesh.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/subdivideMesh.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -33,9 +33,9 @@ % into N^2 smaller faces. % % Example -% [v f] = createOctahedron; +% [v, f] = createOctahedron; % figure; drawMesh(v, f); view(3); -% [v2 f2] = subdivideMesh(v, f, 4); +% [v2, f2] = subdivideMesh(v, f, 4); % figure; drawMesh(v2, f2); view(3) % % See also @@ -51,16 +51,40 @@ %% Initialisations +edges = []; +faceEdgeIndices = []; + +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 + 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 -edges = meshEdges(faces); +if isempty(edges) + edges = meshEdges(faces); +end nEdges = size(edges, 1); % index of edges around each face -faceEdgeIndices = meshFaceEdges(vertices, edges, faces); +if isempty(faceEdgeIndices) + faceEdgeIndices = meshFaceEdges(vertices, edges, faces); +end %% Create new vertices on edges diff -Nru octave-matgeom-1.2.2/inst/meshes3d/surfToMesh.m octave-matgeom-1.2.3/inst/meshes3d/surfToMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/surfToMesh.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/surfToMesh.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,24 +26,24 @@ ## policies, either expressed or implied, of the copyright holders. function varargout = surfToMesh(x, y, varargin) -%SURFTOMESH Convert surface grids into face-vertex mesh. +% Convert surface grids into face-vertex mesh. % -% [V F] = surfToMesh(X, Y) -% [V F] = surfToMesh(X, Y, Z) +% [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); +% [X, Y] = meshgrid(-2:.2:2, -2:.2:2); % Z = X .* exp(-X.^2 - Y.^2); -% [V F] = surfToMesh(X, Y, Z); +% [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); +% [x, y, z] = cylinder(5*ones(1, 10)); +% [v, f] = surfToMesh(x, y, z, 'xPeriodic', true); % figure; % drawMesh(v, f); % view(3); axis equal; @@ -53,7 +53,7 @@ % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inra.fr % Created: 2012-10-25, using Matlab 7.9.0.529 (R2009b) % Copyright 2012 INRA - Cepia Software Platform. @@ -86,7 +86,6 @@ end - %% Compute vertex indices % size along each direction (arrays are (y,x)-indexed) diff -Nru octave-matgeom-1.2.2/inst/meshes3d/tetrahedronVolume.m octave-matgeom-1.2.3/inst/meshes3d/tetrahedronVolume.m --- octave-matgeom-1.2.2/inst/meshes3d/tetrahedronVolume.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/tetrahedronVolume.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/torusMesh.m octave-matgeom-1.2.3/inst/meshes3d/torusMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/torusMesh.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/torusMesh.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/transformMesh.m octave-matgeom-1.2.3/inst/meshes3d/transformMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/transformMesh.m 2019-12-04 12:15:22.863632341 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/transformMesh.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/triangulateCurvePair.m octave-matgeom-1.2.3/inst/meshes3d/triangulateCurvePair.m --- octave-matgeom-1.2.2/inst/meshes3d/triangulateCurvePair.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/triangulateCurvePair.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/triangulateFaces.m octave-matgeom-1.2.3/inst/meshes3d/triangulateFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/triangulateFaces.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/triangulateFaces.m 2021-06-01 09:14:26.094813507 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/triangulatePolygonPair.m octave-matgeom-1.2.3/inst/meshes3d/triangulatePolygonPair.m --- octave-matgeom-1.2.2/inst/meshes3d/triangulatePolygonPair.m 2019-12-04 12:15:22.871632497 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/triangulatePolygonPair.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/trimeshEdgeFaces.m octave-matgeom-1.2.3/inst/meshes3d/trimeshEdgeFaces.m --- octave-matgeom-1.2.2/inst/meshes3d/trimeshEdgeFaces.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/trimeshEdgeFaces.m 2021-06-01 09:14:26.098813493 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/trimeshMeanBreadth.m octave-matgeom-1.2.3/inst/meshes3d/trimeshMeanBreadth.m --- octave-matgeom-1.2.2/inst/meshes3d/trimeshMeanBreadth.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/trimeshMeanBreadth.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/trimeshSurfaceArea.m octave-matgeom-1.2.3/inst/meshes3d/trimeshSurfaceArea.m --- octave-matgeom-1.2.2/inst/meshes3d/trimeshSurfaceArea.m 2019-12-04 12:15:22.851632108 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/trimeshSurfaceArea.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/trimMesh.m octave-matgeom-1.2.3/inst/meshes3d/trimMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/trimMesh.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/trimMesh.m 2021-06-01 09:14:26.102813479 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ % % [V2, F2] = trimMesh(V, F) % Unreferenced vertices are removed. -% Following functions are implemented for only numeric faces: +% Following functions are implemented only for numeric faces: % Duplicate vertices are removed. % Duplicate faces are removed. % diff -Nru octave-matgeom-1.2.2/inst/meshes3d/vertexNormal.m octave-matgeom-1.2.3/inst/meshes3d/vertexNormal.m --- octave-matgeom-1.2.2/inst/meshes3d/vertexNormal.m 2019-12-04 12:15:22.867632419 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/vertexNormal.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/meshes3d/writeMesh.m octave-matgeom-1.2.3/inst/meshes3d/writeMesh.m --- octave-matgeom-1.2.2/inst/meshes3d/writeMesh.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/writeMesh.m 2021-06-01 09:14:26.102813479 +0000 @@ -0,0 +1,73 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-11-20, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + +% 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 + +[~, ~, 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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/writeMesh_off.m octave-matgeom-1.2.3/inst/meshes3d/writeMesh_off.m --- octave-matgeom-1.2.2/inst/meshes3d/writeMesh_off.m 2019-12-04 12:15:22.855632185 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/writeMesh_off.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function writeMesh_off(fileName, vertices, faces) -%WRITEMESH_OFF Writes a mesh into a text file in OFF format. +%WRITEMESH_OFF Write a mesh into a text file in OFF format. % % writeMesh_off(FNAME, V, F) % @@ -34,11 +34,11 @@ % writeMesh_off % % See also -% meshes3d, readMesh_off, writeMesh_ply +% meshes3d, writeMesh, readMesh_off, writeMesh_ply % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2018-04-26, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018 INRA - Cepia Software Platform. @@ -67,7 +67,7 @@ if iscell(faces) nFaces = length(faces); end -fprintf(f, '%d %d\n', nVertices, nFaces); +fprintf(f, '%d %d 0\n', nVertices, nFaces); % Write vertex info format = '%g %g %g\n'; diff -Nru octave-matgeom-1.2.2/inst/meshes3d/writeMesh_ply.m octave-matgeom-1.2.3/inst/meshes3d/writeMesh_ply.m --- octave-matgeom-1.2.2/inst/meshes3d/writeMesh_ply.m 2019-12-04 12:15:22.847632029 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/writeMesh_ply.m 2021-06-01 09:14:26.090813524 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,36 +25,52 @@ ## 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) -%WRITEMESH_PLY Writes a mesh into a text file in PLY format. +function writeMesh_ply(fileName, vertices, faces, varargin) +%WRITEMESH_PLY Write a mesh into a file in PLY format. % -% writeMesh_ply(FNAME, VERTS, FACES) +% 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 -% writeMesh_ply +% mesh = createSoccerBall; +% fileName = 'SoccerBall.ply'; +% writeMesh_ply(fileName, mesh, 'Bin'); +% mesh2 = readMesh(fileName); +% drawMesh(mesh2); axis equal % % See also -% meshes3d, readMesh_ply, writeMesh_off - +% meshes3d, writeMesh, readMesh_ply, writeMesh_off, writeMesh_stl + % ------ -% Author: David Legland -% e-mail: david.legland@inra.fr +% Author: David Legland, oqilipo +% e-mail: david.legland@inrae.fr % Created: 2018-04-26, using Matlab 9.4.0.813654 (R2018a) % Copyright 2018 INRA - Cepia Software Platform. %% 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 +% 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 @@ -68,59 +84,83 @@ % open file for writing text f = fopen(fileName, 'wt'); if (f == -1) - error('Couldn''t open the file %s', fileName); + error('Couldn''t open the file %s', fileName); end -%% Write Header +%% Write Header % write the header line fprintf(f, 'ply\n'); % write format (only ASCII supported) -fprintf(f, 'format ascii 1.0\n'); +fprintf(f, 'format %s 1.0\n', mode); % some comments -fprintf(f, 'comment created by MatGeom for Matlab\n'); +fprintf(f, 'comment Created by MatGeom for MATLAB\n'); % write declaration for vertices fprintf(f, 'element vertex %d\n', nVertices); -fprintf(f, 'property float x\n'); -fprintf(f, 'property float y\n'); -fprintf(f, 'property float z\n'); +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 uchar int vertex_index\n'); +fprintf(f, 'property list int int vertex_index\n'); % end of header fprintf(f, 'end_header\n'); -%% Write vertex info +%% Write data -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 +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 diff -Nru octave-matgeom-1.2.2/inst/meshes3d/writeMesh_stl.m octave-matgeom-1.2.3/inst/meshes3d/writeMesh_stl.m --- octave-matgeom-1.2.2/inst/meshes3d/writeMesh_stl.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/meshes3d/writeMesh_stl.m 2021-06-01 09:14:26.086813538 +0000 @@ -0,0 +1,71 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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 + +% ------ +% Author: oqilipo +% Created: 2021-02-13, using Matlab 9.9.0.1538559 (R2020b) +% Copyright 2021 + +%% 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 diff -Nru octave-matgeom-1.2.2/inst/polygons2d/cart2geod.m octave-matgeom-1.2.3/inst/polygons2d/cart2geod.m --- octave-matgeom-1.2.2/inst/polygons2d/cart2geod.m 2019-12-04 12:15:22.811631327 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/cart2geod.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/clipPolygonHP.m octave-matgeom-1.2.3/inst/polygons2d/clipPolygonHP.m --- octave-matgeom-1.2.2/inst/polygons2d/clipPolygonHP.m 2019-12-04 12:15:22.831631717 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/clipPolygonHP.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/clipPolygon.m octave-matgeom-1.2.3/inst/polygons2d/clipPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/clipPolygon.m 2019-12-04 12:15:22.827631639 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/clipPolygon.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/clipPolyline.m octave-matgeom-1.2.3/inst/polygons2d/clipPolyline.m --- octave-matgeom-1.2.2/inst/polygons2d/clipPolyline.m 2019-12-04 12:15:22.827631639 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/clipPolyline.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/Contents.m octave-matgeom-1.2.3/inst/polygons2d/Contents.m --- octave-matgeom-1.2.2/inst/polygons2d/Contents.m 2019-12-04 12:15:22.827631639 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/Contents.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -130,7 +130,7 @@ % 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 - Compute the normal angle at a vertex of the polygon. +% polygonNormalAngle - Normal angle at each vertex of a polygon. % polygonBounds - Compute the bounding box of a polygon. % polygonOuterNormal - Outer normal vector for a given vertex(ices). % distancePointPolygon - Shortest distance between a point and a polygon. @@ -147,6 +147,7 @@ % expandPolygon - Expand a polygon by a given (signed) distance. % triangulatePolygon - Compute a triangulation of the 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) diff -Nru octave-matgeom-1.2.2/inst/polygons2d/contourMatrixToPolylines.m octave-matgeom-1.2.3/inst/polygons2d/contourMatrixToPolylines.m --- octave-matgeom-1.2.2/inst/polygons2d/contourMatrixToPolylines.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/contourMatrixToPolylines.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/convexHull.m octave-matgeom-1.2.3/inst/polygons2d/convexHull.m --- octave-matgeom-1.2.2/inst/polygons2d/convexHull.m 2019-12-04 12:15:22.811631327 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/convexHull.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/convexification.m octave-matgeom-1.2.3/inst/polygons2d/convexification.m --- octave-matgeom-1.2.2/inst/polygons2d/convexification.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/convexification.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/curvature.m octave-matgeom-1.2.3/inst/polygons2d/curvature.m --- octave-matgeom-1.2.2/inst/polygons2d/curvature.m 2019-12-04 12:15:22.835631795 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/curvature.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/curveCMoment.m octave-matgeom-1.2.3/inst/polygons2d/curveCMoment.m --- octave-matgeom-1.2.2/inst/polygons2d/curveCMoment.m 2019-12-04 12:15:22.811631327 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/curveCMoment.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/curveCSMoment.m octave-matgeom-1.2.3/inst/polygons2d/curveCSMoment.m --- octave-matgeom-1.2.2/inst/polygons2d/curveCSMoment.m 2019-12-04 12:15:22.835631795 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/curveCSMoment.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/curveMoment.m octave-matgeom-1.2.3/inst/polygons2d/curveMoment.m --- octave-matgeom-1.2.2/inst/polygons2d/curveMoment.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/curveMoment.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/densifyPolygon.m octave-matgeom-1.2.3/inst/polygons2d/densifyPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/densifyPolygon.m 2019-12-04 12:15:22.819631483 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/densifyPolygon.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/distancePointPolygon.m octave-matgeom-1.2.3/inst/polygons2d/distancePointPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/distancePointPolygon.m 2019-12-04 12:15:22.827631639 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/distancePointPolygon.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/distancePointPolyline.m octave-matgeom-1.2.3/inst/polygons2d/distancePointPolyline.m --- octave-matgeom-1.2.2/inst/polygons2d/distancePointPolyline.m 2019-12-04 12:15:22.839631873 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/distancePointPolyline.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/distancePolygons.m octave-matgeom-1.2.3/inst/polygons2d/distancePolygons.m --- octave-matgeom-1.2.2/inst/polygons2d/distancePolygons.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/distancePolygons.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/distancePolygonsNoCross.m octave-matgeom-1.2.3/inst/polygons2d/distancePolygonsNoCross.m --- octave-matgeom-1.2.2/inst/polygons2d/distancePolygonsNoCross.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/distancePolygonsNoCross.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/distancePolylines.m octave-matgeom-1.2.3/inst/polygons2d/distancePolylines.m --- octave-matgeom-1.2.2/inst/polygons2d/distancePolylines.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/distancePolylines.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/drawPolygon.m octave-matgeom-1.2.3/inst/polygons2d/drawPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/drawPolygon.m 2019-12-04 12:15:22.811631327 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/drawPolygon.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/drawPolyline.m octave-matgeom-1.2.3/inst/polygons2d/drawPolyline.m --- octave-matgeom-1.2.2/inst/polygons2d/drawPolyline.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/drawPolyline.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/drawVertices.m octave-matgeom-1.2.3/inst/polygons2d/drawVertices.m --- octave-matgeom-1.2.2/inst/polygons2d/drawVertices.m 2019-12-04 12:15:22.831631717 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/drawVertices.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/expandPolygon.m octave-matgeom-1.2.3/inst/polygons2d/expandPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/expandPolygon.m 2019-12-04 12:15:22.835631795 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/expandPolygon.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/fillPolygon.m octave-matgeom-1.2.3/inst/polygons2d/fillPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/fillPolygon.m 2019-12-04 12:15:22.831631717 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/fillPolygon.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/findPoint.m octave-matgeom-1.2.3/inst/polygons2d/findPoint.m --- octave-matgeom-1.2.2/inst/polygons2d/findPoint.m 2019-12-04 12:15:22.835631795 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/findPoint.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/geod2cart.m octave-matgeom-1.2.3/inst/polygons2d/geod2cart.m --- octave-matgeom-1.2.2/inst/polygons2d/geod2cart.m 2019-12-04 12:15:22.819631483 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/geod2cart.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/intersectEdgePolygon.m octave-matgeom-1.2.3/inst/polygons2d/intersectEdgePolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/intersectEdgePolygon.m 2019-12-04 12:15:22.819631483 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/intersectEdgePolygon.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/intersectLinePolygon.m octave-matgeom-1.2.3/inst/polygons2d/intersectLinePolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/intersectLinePolygon.m 2019-12-04 12:15:22.835631795 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/intersectLinePolygon.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/intersectLinePolyline.m octave-matgeom-1.2.3/inst/polygons2d/intersectLinePolyline.m --- octave-matgeom-1.2.2/inst/polygons2d/intersectLinePolyline.m 2019-12-04 12:15:22.839631873 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/intersectLinePolyline.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/intersectPolylines.m octave-matgeom-1.2.3/inst/polygons2d/intersectPolylines.m --- octave-matgeom-1.2.2/inst/polygons2d/intersectPolylines.m 2019-12-04 12:15:22.819631483 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/intersectPolylines.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/intersectRayPolygon.m octave-matgeom-1.2.3/inst/polygons2d/intersectRayPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/intersectRayPolygon.m 2019-12-04 12:15:22.835631795 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/intersectRayPolygon.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/isPointInPolygon.m octave-matgeom-1.2.3/inst/polygons2d/isPointInPolygon.m --- octave-matgeom-1.2.2/inst/polygons2d/isPointInPolygon.m 2019-12-04 12:15:22.819631483 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/isPointInPolygon.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/isPointOnPolyline.m octave-matgeom-1.2.3/inst/polygons2d/isPointOnPolyline.m --- octave-matgeom-1.2.2/inst/polygons2d/isPointOnPolyline.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/isPointOnPolyline.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/medialAxisConvex.m octave-matgeom-1.2.3/inst/polygons2d/medialAxisConvex.m --- octave-matgeom-1.2.2/inst/polygons2d/medialAxisConvex.m 2019-12-04 12:15:22.819631483 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/medialAxisConvex.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/minimumCaliperDiameter.m octave-matgeom-1.2.3/inst/polygons2d/minimumCaliperDiameter.m --- octave-matgeom-1.2.2/inst/polygons2d/minimumCaliperDiameter.m 2019-12-04 12:15:22.831631717 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/minimumCaliperDiameter.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/parametrize.m octave-matgeom-1.2.3/inst/polygons2d/parametrize.m --- octave-matgeom-1.2.2/inst/polygons2d/parametrize.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/parametrize.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/pointSetsAverage.m octave-matgeom-1.2.3/inst/polygons2d/pointSetsAverage.m --- octave-matgeom-1.2.2/inst/polygons2d/pointSetsAverage.m 2019-12-04 12:15:22.819631483 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/pointSetsAverage.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonArea.m octave-matgeom-1.2.3/inst/polygons2d/polygonArea.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonArea.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonArea.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ ## policies, either expressed or implied, of the copyright holders. function area = polygonArea(poly, varargin) -%POLYGONAREA Compute the signed area of a polygon. +% 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 diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonBounds.m octave-matgeom-1.2.3/inst/polygons2d/polygonBounds.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonBounds.m 2019-12-04 12:15:22.831631717 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonBounds.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonCentroid.m octave-matgeom-1.2.3/inst/polygons2d/polygonCentroid.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonCentroid.m 2019-12-04 12:15:22.827631639 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonCentroid.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonContains.m octave-matgeom-1.2.3/inst/polygons2d/polygonContains.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonContains.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonContains.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonCurvature.m octave-matgeom-1.2.3/inst/polygons2d/polygonCurvature.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonCurvature.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonCurvature.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonEdges.m octave-matgeom-1.2.3/inst/polygons2d/polygonEdges.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonEdges.m 2019-12-04 12:15:22.827631639 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonEdges.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonEquivalentEllipse.m octave-matgeom-1.2.3/inst/polygons2d/polygonEquivalentEllipse.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonEquivalentEllipse.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonEquivalentEllipse.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonInertiaEllipse.m octave-matgeom-1.2.3/inst/polygons2d/polygonInertiaEllipse.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonInertiaEllipse.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonInertiaEllipse.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonLength.m octave-matgeom-1.2.3/inst/polygons2d/polygonLength.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonLength.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonLength.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonLoops.m octave-matgeom-1.2.3/inst/polygons2d/polygonLoops.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonLoops.m 2019-12-04 12:15:22.835631795 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonLoops.m 2021-06-01 09:14:26.086813538 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonNormalAngle.m octave-matgeom-1.2.3/inst/polygons2d/polygonNormalAngle.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonNormalAngle.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonNormalAngle.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,27 +25,42 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function theta = polygonNormalAngle(points, ind) -%POLYGONNORMALANGLE Compute the normal angle at a vertex of the polygon. +function theta = polygonNormalAngle(poly, inds) +% 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. % -% THETA = polygonNormalAngle(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 -% % creates a simple polygon -% poly = [0 0;0 1;-1 1;0 -1;1 0]; -% % compute normal angle at each vertex -% theta = polygonNormalAngle(poly, 1:size(poly, 1)); -% % sum of all normal angle of a non-intersecting polygon equals 2xpi -% % (can be -2xpi if polygon is oriented clockwise) -% sum(theta) +% % 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 +% polygons2d, polygonOuterNormal, normalizeAngle % % ------ @@ -54,22 +69,25 @@ % Created: 2005-11-30 % Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). +% number of polygon vertices +np = size(poly, 1); -% number of points -np = size(points, 1); +if nargin == 1 + inds = 1:np; +end % number of angles to compute -nv = length(ind); +nv = length(inds); theta = zeros(nv, 1); for i = 1:nv % current vertex - curr = points(ind(i), :); + curr = poly(inds(i), :); % previous and next vertices - prev = points(mod(ind(i)-2, np)+1, :); - next = points(mod(ind(i), np)+1, :); + prev = poly(mod(inds(i)-2, np)+1, :); + next = poly(mod(inds(i), np)+1, :); theta(i) = angle3Points(prev, curr, next) - pi; end diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonOuterNormal.m octave-matgeom-1.2.3/inst/polygons2d/polygonOuterNormal.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonOuterNormal.m 2019-12-04 12:15:22.831631717 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonOuterNormal.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -26,12 +26,20 @@ ## policies, either expressed or implied, of the copyright holders. function vect = polygonOuterNormal(poly, iVertex) -%POLYGONOUTERNORMAL Outer normal vector for a given vertex(ices). +% Outer normal vector for a given vertex(ices). % -% VECT = polygonOuterNormal(POLY, VIND) -% Where POLY is a polygon and VIND is index of a vertex, returns the -% outer normal as a vector. +% 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]; @@ -43,21 +51,30 @@ % drawVector(pts, vect*10, 'b'); % % See also -% polygons2d, polygonPoint, polygonNormalAngle +% polygons2d, polygonPoint, polygonNormalAngle % % ------ % Author: David Legland -% e-mail: david.legland@inra.fr +% e-mail: david.legland@inrae.fr % Created: 2017-11-23, using Matlab 8.6.0.267246 (R2015b) % Copyright 2017 INRA - Cepia Software Platform. -n = size(poly, 1); +% 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), n) + 1; - iPrev = mod(iVertex(i)-2, n) + 1; + 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 diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonPoint.m octave-matgeom-1.2.3/inst/polygons2d/polygonPoint.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonPoint.m 2019-12-04 12:15:22.823631561 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonPoint.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonSecondAreaMoments.m octave-matgeom-1.2.3/inst/polygons2d/polygonSecondAreaMoments.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonSecondAreaMoments.m 2019-12-04 12:15:22.815631405 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonSecondAreaMoments.m 2021-06-01 09:14:26.082813553 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonSelfIntersections.m octave-matgeom-1.2.3/inst/polygons2d/polygonSelfIntersections.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonSelfIntersections.m 2019-12-04 12:15:22.827631639 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonSelfIntersections.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonSignature.m octave-matgeom-1.2.3/inst/polygons2d/polygonSignature.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonSignature.m 2019-12-04 12:15:22.839631873 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonSignature.m 2021-06-01 09:14:26.078813569 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonSkeleton.m octave-matgeom-1.2.3/inst/polygons2d/polygonSkeleton.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonSkeleton.m 1970-01-01 00:00:00.000000000 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonSkeleton.m 2021-06-01 09:14:26.086813538 +0000 @@ -0,0 +1,173 @@ +## Copyright (C) 2021 David Legland +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are met: +## +## 1 Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## 2 Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' +## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR +## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## The views and conclusions contained in the software and 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) +% 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 +% INRAE - BIA Research Unit - BIBS Platform (Nantes) +% Created: 2020-05-29, using Matlab 9.8.0.1323502 (R2020a) +% Copyright 2020 INRAE. + + +%% 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 diff -Nru octave-matgeom-1.2.2/inst/polygons2d/polygonSubcurve.m octave-matgeom-1.2.3/inst/polygons2d/polygonSubcurve.m --- octave-matgeom-1.2.2/inst/polygons2d/polygonSubcurve.m 2019-12-04 12:15:22.831631717 +0000 +++ octave-matgeom-1.2.3/inst/polygons2d/polygonSubcurve.m 2021-06-01 09:14:26.074813583 +0000 @@ -1,4 +1,4 @@ -## Copyright (C) 2019 David Legland +## Copyright (C) 2021 David Legland ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without @@ -25,33 +25,42 @@ ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. -function res = polygonSubcurve(poly, t0, t1) -%POLYGONSUBCURVE Extract a portion of a polygon. +function [res, inds] = polygonSubcurve(poly, t0, t1) +% 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 = circleAsPolygon([10 20 30], Nv); -% poly2 = polygonSubcurve(poly, 15, 65); -% drawCurve(poly2); +% 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 +% polygons2d, polylineSubcurve, projPointOnPolygon, polygonPoint % + % ------ % Author: David Legland -% e-mail: david.legland@grignon.inra.fr +% e-mail: david.legland@inrae.fr % Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) -% Copyright 2009 INRA - Cepia Software Platform. +% Copyright 2009 INRAE - Cepia Software Platform. % number of vertices Nv = size(poly, 1); -if t0