Skip to content

Commit ac3087d

Browse files
committed
[point] add pt2surf, add facedihedral, circumradius, removenode
1 parent 04adeda commit ac3087d

File tree

8 files changed

+762
-3
lines changed

8 files changed

+762
-3
lines changed

circumradius.m

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
function [r, cc] = circumradius(p, t)
2+
%
3+
% [r, cc] = circumradius(p, t)
4+
% Compute circumradius and circumcenter for triangles/tets
5+
%
6+
% Input:
7+
% p - Nx3 vertex coordinates
8+
% t - Mx3 (triangles) or Mx4 (tetrahedra) element connectivity
9+
%
10+
% Output:
11+
% r - Mx1 circumradius
12+
% cc - Mx3 circumcenter coordinates
13+
14+
if size(t, 2) == 3 % Triangular mesh
15+
% Get triangle vertices
16+
v1 = p(t(:, 1), :);
17+
v2 = p(t(:, 2), :);
18+
v3 = p(t(:, 3), :);
19+
20+
% Edge vectors
21+
d1 = v2 - v1;
22+
d2 = v3 - v1;
23+
24+
% Cross product (2 * triangle area vector)
25+
n = cross(d1, d2, 2);
26+
n_len_sq = sum(n.^2, 2);
27+
28+
if nargout > 1
29+
% Circumcenter (needed for radius anyway if requested)
30+
alpha = sum(d2.^2, 2) .* dot(d1, d1 - d2, 2) ./ (2 * n_len_sq);
31+
beta = sum(d1.^2, 2) .* dot(d2, d2 - d1, 2) ./ (2 * n_len_sq);
32+
cc = v1 + alpha .* d1 + beta .* d2;
33+
34+
% Circumradius from center
35+
r = sqrt(sum((v1 - cc).^2, 2));
36+
else
37+
% Circumradius without computing center
38+
a = sqrt(sum((v2 - v3).^2, 2));
39+
b = sqrt(sum(d2.^2, 2));
40+
c = sqrt(sum(d1.^2, 2));
41+
area = sqrt(n_len_sq) / 2;
42+
r = (a .* b .* c) ./ (4 * area);
43+
end
44+
45+
else % Tetrahedral mesh
46+
% Get tet vertices
47+
v1 = p(t(:, 1), :);
48+
v2 = p(t(:, 2), :);
49+
v3 = p(t(:, 3), :);
50+
v4 = p(t(:, 4), :);
51+
52+
% Edge vectors from v1
53+
a = v2 - v1;
54+
b = v3 - v1;
55+
c = v4 - v1;
56+
57+
if nargout > 1
58+
% Circumcenter using Cramer's rule
59+
d1 = sum(c .* (v1 + v4) * 0.5, 2);
60+
d2 = sum(a .* (v1 + v2) * 0.5, 2);
61+
d3 = sum(b .* (v1 + v3) * 0.5, 2);
62+
63+
det23 = a(:, 2) .* b(:, 3) - a(:, 3) .* b(:, 2);
64+
det13 = a(:, 3) .* b(:, 1) - a(:, 1) .* b(:, 3);
65+
det12 = a(:, 1) .* b(:, 2) - a(:, 2) .* b(:, 1);
66+
67+
Det = c(:, 1) .* det23 + c(:, 2) .* det13 + c(:, 3) .* det12;
68+
69+
detx = d1 .* det23 + c(:, 2) .* (-(d2 .* b(:, 3)) + (a(:, 3) .* d3)) + ...
70+
c(:, 3) .* ((d2 .* b(:, 2)) - (a(:, 2) .* d3));
71+
dety = c(:, 1) .* ((d2 .* b(:, 3)) - (a(:, 3) .* d3)) + d1 .* det13 + ...
72+
c(:, 3) .* ((d3 .* a(:, 1)) - (b(:, 1) .* d2));
73+
detz = c(:, 1) .* ((a(:, 2) .* d3) - (d2 .* b(:, 2))) + ...
74+
c(:, 2) .* (d2 .* b(:, 1) - a(:, 1) .* d3) + d1 .* det12;
75+
76+
cc = [detx ./ Det, dety ./ Det, detz ./ Det];
77+
78+
% Circumradius from center
79+
r = sqrt(sum((v2 - cc).^2, 2));
80+
else
81+
% Circumradius without computing center
82+
V = abs(dot(a, cross(b, c, 2), 2)) / 6;
83+
A = [sqrt(sum(cross(b, c, 2).^2, 2)), ...
84+
sqrt(sum(cross(c, a, 2).^2, 2)), ...
85+
sqrt(sum(cross(a, b, 2).^2, 2)), ...
86+
sqrt(sum(cross(v3 - v2, v4 - v2, 2).^2, 2))] / 2;
87+
r = sqrt(sum(A.^2, 2)) ./ (4 * V);
88+
end
89+
end

facedihedral.m

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
function ang = facedihedral(node, face, varargin)
2+
%
3+
% ang = facedihedral(node, face)
4+
% ang = facedihedral(node, face)
5+
%
6+
% for every triangle in a triangular mesh, compute its dihedral angle
7+
% with its edge neighbor
8+
%
9+
% author: Qianqian Fang, <q.fang at neu.edu>
10+
%
11+
% input:
12+
% node: node coordinates of the input mesh
13+
% face: triangle list
14+
%
15+
% output:
16+
% ang: 3 dihedral angles of each triangle, with order set by edgeneighbors
17+
%
18+
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
19+
%
20+
21+
opt = struct();
22+
opt.type = '';
23+
if (length(varargin) == 1)
24+
opt.type = 'general';
25+
end
26+
27+
edgenb = edgeneighbors(face(:, 1:3), opt.type);
28+
surfnorm = surfacenorm(node, face(:, 1:3));
29+
ang = nan(size(face, 1), 3);
30+
if (~iscell(edgenb))
31+
for i = 1:size(edgenb, 2)
32+
idx = edgenb(:, i);
33+
ang(idx > 0, i) = dot(surfnorm(idx > 0, :), surfnorm(edgenb(idx > 0, i), :), 2);
34+
end
35+
else
36+
for i = 1:size(edgenb, 1)
37+
dihe = sort(abs(dot(repmat(surfnorm(i, :), length(edgenb{i}), 1), surfnorm(edgenb{i}, :), 2)));
38+
dihe = max(min(dihe, 1), 0);
39+
if (length(dihe) < 3)
40+
ang(i, 1:length(dihe)) = dihe;
41+
else
42+
ang(i, :) = dihe(end - 2:end);
43+
end
44+
end
45+
end
46+
if (~iscell(edgenb))
47+
ang = max(min(ang, 1), -1);
48+
ang(edgenb == 0) = nan;
49+
end
50+
ang = acos(ang);

layersurf.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
innermost = jsonopt('innermost', 0, opt);
5050
occurence = jsonopt('occurence', 'first', opt);
5151

52+
if (size(elem, 2) < 5)
53+
elem(:, 5) = 1;
54+
end
5255
labels = sort(unique(elem(:, 5)));
5356
face = [];
5457
for i = 1:length(labels)

0 commit comments

Comments
 (0)