-
Notifications
You must be signed in to change notification settings - Fork 0
/
Plane.m
132 lines (104 loc) · 4.46 KB
/
Plane.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
classdef Plane
properties
name
vertexs
normal
centroid
distance_to_origin
area
end
methods
function obj = Plane(corners)
% The plane object is defined by the vertices, and the normal
% direction, distance to the origin, centroid, area are all
% calculated. A random name is also assigned.
if nargin > 0
obj.vertexs = corners;
L1 = obj.vertexs(2,:) - obj.vertexs(1,:);
L2 = obj.vertexs(3,:) - obj.vertexs(1,:);
n = cross(L1,L2);
obj.normal = n/norm(n);
obj.centroid = mean(corners);
obj.distance_to_origin = abs(dot(obj.normal, obj.vertexs(1,:)));
obj.area = 0.5 * norm( cross(L1,L2) );
obj.name = obj.GenerateRandomPlaneName(4);
end
end
function points_class = samplePlane(obj, numPoints)
% points = obj.samplePlane(numPoints)
% This function takes an argument of the number of points that
% the plane is to have sampled from it. The sampling is done in
% a grid pattern, evenly spaced along the largest axis and
% sampled orthogonally to it. The number of points in the
% sample is not exact, so the actual number of points returned
% may nat exactly correspond to the number of points specified
% in the input.
point_spacing = sqrt(obj.area/numPoints);
vert = obj.vertexs;
v1 = vert(1,:);
v2 = vert(2,:);
v3 = vert(3,:);
[~, index] = max( [norm(v2-v1),norm(v3-v1),norm(v3-v2)]);
if index==1
base = v1;
vec1 = v2-base;
vec2 = v3-base;
elseif index == 2
base = v3;
vec1 = v1-base;
vec2 = v2-base;
else
base = v2;
vec1 = v3-base;
vec2 = v1-base;
end
len = norm(vec1);
dir = (vec1)/len ;
% cross_vec = vec2-dot(vec2,dir);
cross_dir1 = cross(obj.normal, vec1);
cross_dir = cross_dir1/norm(cross_dir1);
cross_len = sqrt(norm(vec2)^2 - dot(vec2,dir)^2);
cross_vec = cross_dir*cross_len;
a= [0:point_spacing:len]';
linear_samples = [dir(1)*a,dir(2)*a,dir(3)*a]+repmat(base,length(a),1);
numCross = ceil(cross_len/point_spacing);
all_samples = [];
for i = 0:numCross
new_samples = linear_samples + repmat(cross_dir*point_spacing*i,size(linear_samples,1),1);
all_samples = [all_samples;new_samples];
end
v0 = repmat(vec1, size(all_samples,1),1);
v1 = repmat(vec2, size(all_samples,1),1);
v2 = all_samples - repmat(base, size(all_samples,1),1);
dot00 = dot(v0,v0,2);
dot01 = dot(v0,v1,2);
dot11 = dot(v1,v1,2);
dot02 = dot(v0,v2,2);
dot12 = dot(v1,v2,2);
invDenom = 1./((dot00.*dot11) - (dot01.*dot01));
u = ((dot11.*dot02)-(dot01.*dot12)).*invDenom;
v = ((dot00.*dot12)-(dot01.*dot02)).*invDenom;
key1 = u>-0.001;
key2 = v>-0.001;
key3 = (u+v)<1.0001;
key = key1.*key2.*key3;
points = deleteRowKey(all_samples,key);
points_class = Point(size(points,1));
for i = 1:size(points,1)
points_class(i) = Point(points(i,:),obj);
end
end
end
methods (Static)
function name = GenerateRandomPlaneName(lengthOfName)
setOfValidChars = char(['a':'z','0':'9']);
num = length(setOfValidChars );
randIndexs = ceil( num*rand(1,lengthOfName) );
name = char(zeros(size(1,lengthOfName)));
for i = 1:lengthOfName
name(i) = setOfValidChars(randIndexs(i));
end
name = ['Plane',name];
end
end
end