triangulateVrep

PURPOSE ^

triangulate a polytope in V-representattion into simplices

SYNOPSIS ^

function [vrepList, volumeVector] = triangulateVrep(vrep, zerotol, isCone)

DESCRIPTION ^

 triangulate a polytope in V-representattion into simplices

 THIS FUNCTION IS PUBLISHED BUT TESTED AND MAINTAINED ONLY IN SCOPE 
   OF APPLICATIONS (decomposition case study; technical reports)

 Syntax: vrepList = triangulateVrep(vrep)

 Generates a cell array of simplices in V-representation that presents a
   triangulation of the input polytope. To obtain this, the polytope is
   scaled and projected into an (n+1)-dimensional space to use qhulln.

 triangulateVrep(.., zerotol) lets you specify the zerotol that is used to 
   identify values that are close to zero by zero. Default: elkZerotol.

 triangulateVrep(.., zerotol, isCone) is a specific logical parameter that
   identifies the input as a convex cone that contains the origin as one
   point. All other points must be at a hyperplane. In this case 
   (isCone=1), the polytope is not elevated to a higher dimension. The
   polytope is also not scaled.

 See also: identifyPolytopeList, subtractPolytope

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [vrepList, volumeVector] = triangulateVrep(vrep, zerotol, isCone)
0002 % triangulate a polytope in V-representattion into simplices
0003 %
0004 % THIS FUNCTION IS PUBLISHED BUT TESTED AND MAINTAINED ONLY IN SCOPE
0005 %   OF APPLICATIONS (decomposition case study; technical reports)
0006 %
0007 % Syntax: vrepList = triangulateVrep(vrep)
0008 %
0009 % Generates a cell array of simplices in V-representation that presents a
0010 %   triangulation of the input polytope. To obtain this, the polytope is
0011 %   scaled and projected into an (n+1)-dimensional space to use qhulln.
0012 %
0013 % triangulateVrep(.., zerotol) lets you specify the zerotol that is used to
0014 %   identify values that are close to zero by zero. Default: elkZerotol.
0015 %
0016 % triangulateVrep(.., zerotol, isCone) is a specific logical parameter that
0017 %   identifies the input as a convex cone that contains the origin as one
0018 %   point. All other points must be at a hyperplane. In this case
0019 %   (isCone=1), the polytope is not elevated to a higher dimension. The
0020 %   polytope is also not scaled.
0021 %
0022 % See also: identifyPolytopeList, subtractPolytope
0023 
0024 % The elk-library: convex geometry applied to crystallization modeling.
0025 %   Copyright (C) 2012 Alexander Reinhold
0026 %
0027 % This program is free software: you can redistribute it and/or modify it
0028 %   under the terms of the GNU General Public License as published by the
0029 %   Free Software Foundation, either version 3 of the License, or (at your
0030 %   option) any later version.
0031 %
0032 % This program is distributed in the hope that it will be useful, but
0033 %   WITHOUT ANY WARRANTY; without even the implied warranty of
0034 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0035 %   General Public License for more details.
0036 %
0037 % You should have received a copy of the GNU General Public License along
0038 %   with this program.  If not, see <http://www.gnu.org/licenses/>.
0039 
0040 %% Input handling
0041 if ~exist('zerotol', 'var') || isempty(zerotol)
0042     zerotol = elkZerotol;
0043 end
0044 if ~exist('isCone', 'var') || isempty(isCone)
0045     isCone = 0;
0046 end
0047 
0048 %% reduce dimension if necessary
0049 %! ToDo: the following does only make sense for cones, for polytopes one
0050 %    might look to computeVolumeVrep where this is done properly.
0051 reduce_dim = 0;
0052 if rank(vrep.V, zerotol) ~= size(vrep.V, 2), reduce_dim = 1; end
0053 
0054 % NOTE: DEGENERATED POLYTOPE
0055 % This part was once here but no function should call triangulateVrep with
0056 %   a degtenerated polytope. This is problematic when the polytope is
0057 %   accidently degenerate. In this case, the lines below assign the volume
0058 %   calculated in the lower-dimensional space. These are unpredictable
0059 %   results. Therefore, we trigger an error here to see which function
0060 %   actually might input such polytopes to this function.
0061 if reduce_dim
0062     vrepList = {};
0063     volumeVector = [];
0064     return
0065 %     error('elk:triangulation:wrongInput', ['The input polytope is ' ...
0066 %         'degenerate  it can only be triangulated, if it is provided ' ...
0067 %         ' as in a projected version into the appropriate subspace']);
0068 end
0069 % old code:
0070 % if reduce_dim
0071 %     vrep_old = vrep;
0072 %     [vrep, rot, x0] = reduceVrepDimension(vrep, zerotol);
0073 % end
0074 %/
0075 
0076 nDim = size(vrep.V, 2);
0077 
0078 %% Catch trivial examples
0079 if nDim <= 1
0080     vrepList = {vrep};
0081     volumeVector = computeVolumeVrep(vrep);
0082     return
0083 end
0084 
0085 %% Vrep preparation
0086 if isCone
0087     % find origin
0088     originIndex = find(all(abs(vrep.V) < zerotol, 2));
0089     if numel(originIndex) ~= 1 || isempty(originIndex)
0090         error('elk:decomposition:numericalProblem', ...
0091             'The cone does contain no or more than one origin. This should not happen!');
0092     end
0093     vrepCone = vrep;
0094 else
0095     % scale polytope
0096     [vrepScaled, ~, ~] = scaleVrep(vrep, zerotol);
0097 
0098     % elevate to cone
0099     vrepCone.V = [ones([size(vrepScaled.V, 1), 1]), vrepScaled.V; ...
0100                   zeros([1, 1+size(vrepScaled.V, 2)])...
0101                  ];
0102 end
0103 
0104 %% Triangulate cone
0105 patchIndexMatrix = convhulln(vrepCone.V, {'Qt', 'Qs'});
0106 
0107 %% Throw away patches that contain the origin
0108 if isCone
0109     patchIndexMatrix(sum(patchIndexMatrix == originIndex, 2) > 0 , :) = [];
0110 else
0111     filter = sum(patchIndexMatrix == max(patchIndexMatrix(:)), 2) > 0;
0112     patchIndexMatrix(filter, :) = [];
0113 end
0114 
0115 %% Generate vrep of simplices
0116 vrepList = cell([1, size(patchIndexMatrix, 1)]);
0117 for iSimplex = 1:length(vrepList)
0118     if isCone   
0119         vrepList{iSimplex} = struct('V', ...
0120             [vrepCone.V(patchIndexMatrix(iSimplex, :), :); ...
0121             zeros([1 size(vrepCone.V, 2)])...
0122             ]);
0123     else
0124         vrepList{iSimplex} = struct('V', ...
0125             vrep.V(patchIndexMatrix(iSimplex, :), :)...
0126             );
0127     end
0128 end
0129 
0130 %% Generate simplex volumes
0131 volumeVector = zeros([1, length(vrepList)]);
0132 for iSimplex = 1:length(vrepList)
0133     volumeVector(iSimplex) = computeVolumeVrep(vrepList{iSimplex}, zerotol);
0134 end
0135 
0136 %% Throw away empty polytopes
0137 % .. that happens for convhulln
0138 % .. I don't want to mess with the implementation for cones, but the
0139 %    implementation for polytopes seems to require some zerotol, here
0140 if isCone
0141     vrepList(volumeVector == 0) = [];
0142     volumeVector(volumeVector == 0) = [];
0143 else
0144     vrepList(volumeVector < zerotol) = [];
0145     volumeVector(volumeVector < zerotol) = [];
0146 end
0147 
0148 %% Put back coordinates that were deleted through dimension reduction
0149 % Following lines are commented out, see note "DEGENERATED POLYTOPE",
0150 %   above.
0151 % if reduce_dim
0152 %     disp('.. done (reduced dimension).')
0153 %     for iSimplex = 1:length(vrepList)
0154 %         removedCoordinates = zeros(size(vrepList{iSimplex}.V, 1), size(vrep_old.V, 2) - size(vrep.V, 2));
0155 %         vrepList{iSimplex}.V = [vrepList{iSimplex}.V, removedCoordinates]*rot';
0156 %         vrepList{iSimplex} = moveVrep(vrepList{iSimplex}, x0);
0157 %     end
0158 % end
0159 %/
0160 
0161 %% Output handling
0162 varagout{1} = vrepList;
0163 if nargout >= 2
0164     varargout{2} = volumeVector;
0165 end

Generated on Sat 18-Jul-2015 16:45:31 by m2html © 2005