itaInfiniteWedge.m 9.77 KB
Newer Older
1
2
3
4
5
classdef itaInfiniteWedge
    
    properties (Access = protected)
        n1 % 3-dim normal vector of main face (internal)
        n2 % 3-dim normal vector of opposite face (internal)
6
        ed % 3-dim edge direction vector (internal)
7
        l % Internal location variable
8
        et % type of edge (internal)
9
10
11
12
13
14
        bc_hard % Internal boundary condition (hard = true)
    end
    
    properties (Dependent)
        main_face_normal % 3-dim normal vector of main face (normalized)
        opposite_face_normal % 3-dim normal vector of opposite face (normalized)
15
16
17
        aperture_direction % 3-dim normal vector of aperture direction (normalized) LEGACY
        edge_direction % 3-dim normal vector of edge direction (normalized)
        location % Location of wedge (somewhere along edge)
18
19
        opening_angle % Angle from main to opposite face in propagation medium / air (radiants)
        wedge_angle % Angle from main to opposite face in solid medium of wedge (radiants)
20
        edge_type % 'wedge' for opening angles > pi or 'corner' for opening angles < pi
21
22
23
24
        boundary_condition % boundary condition of the wedge faces (hard or soft)
    end
    
    methods
25
        function obj = itaInfiniteWedge( main_face_normal, opposite_face_normal, location, edge_type, edge_direction )
26
27
28
29
            % Create a wedge by a main face normal and an opposite face
            % normal
            %   main_face_normal:       Main face normal (3-dim)
            %   opposite_face_normal:   Opposite face normal (3-dim)
30
            %   location:               Point on edge which defines
31
            %                           location of the wedge in 3_dim sapce
32
33
            %   edge_type:              use 'outer_edge' for opening angles > pi (default) and
            %                           'inner_edge' for opening angles < pi
34
            %   edge_direction          Edge direction vector (3-dim)
35
36
37
            % Note: 3-dim direction vectors will be normalized automatically
            % 
            if nargin < 4
38
                edge_type = 'outer_edge';
39
            end
40
41
            if ~isequal( edge_type, 'inner_edge' ) && ~isequal( edge_type, 'outer_edge' )
                error( 'Invalid edge type. Use either ''inner_edge'' or ''outer_edge''' )
42
43
44
45
46
47
48
49
50
51
52
53
54
55
            end
            if numel( main_face_normal ) ~= 3
                error 'Main face normal has to be a 3-dim vector'
            end
            if numel( opposite_face_normal ) ~= 3
                error 'Opposite face normal has to be a 3-dim vector'
            end
            if numel(location) ~= 3
                error( 'Location must be of dimension 3')
            end
            
            obj.n1 = main_face_normal;
            obj.n2 = opposite_face_normal;
            obj.l = location;
56
            obj.et = edge_type;
57
58
59
60
61
62
63
64
            obj.bc_hard = true;
            
            if ~obj.validate_normals
                warning 'Normalized face normals'
                obj.n1 = main_face_normal ./ norm( main_face_normal );
                obj.n2 = opposite_face_normal ./ norm( opposite_face_normal );
            end
            
Dipl.-Ing. Jonas Stienen's avatar
WIP    
Dipl.-Ing. Jonas Stienen committed
65
66
67
            if nargin < 5
                n_scaled = cross( obj.main_face_normal, obj.opposite_face_normal );
                if ~norm( n_scaled )
68
                    warning 'Normals are linear dependent and edge direction could not be determined. Please set edge direction manually.'
Dipl.-Ing. Jonas Stienen's avatar
WIP    
Dipl.-Ing. Jonas Stienen committed
69
                else
70
                    obj.ed = n_scaled ./ norm( n_scaled );
Dipl.-Ing. Jonas Stienen's avatar
WIP    
Dipl.-Ing. Jonas Stienen committed
71
                end
72
            else
73
                obj.ed = edge_direction;
74
75
76
77
78
79
80
81
82
83
84
            end
        end
        
        function n = get.main_face_normal( obj )
            n = obj.n1;
        end
                
        function n = get.opposite_face_normal( obj )
            n = obj.n2;
        end
        
85
86
        function n = get.edge_direction( obj )
            % Returns normalized direction of edge. Vectors main face normal, opposite face normal and edge direction 
87
            % form a clockwise system.
88
89
            if isempty( obj.ed )
                error 'Invalid wedge, edge direction not set and face normals are linear dependent'
90
            end
91
            n = obj.ed;
92
93
        end
        
94
95
        function obj = set.edge_direction( obj, edge_direction )
            % Sets edge direction manually (in case of linear
96
97
            % dependent normals)
            if norm( cross( obj.n1, obj.n2 ) )
98
                error 'Edge of linear independent normals is fixed can not be modified'
99
            end
100
101
            if ~norm( edge_direction )
                error 'Edge vector must be a valid direction'
102
            end
103
104
105
            if norm( edge_direction ) ~= 1
                warning ' Normalizing edge direction'
                edge_direction = edge_direction / norm( edge_direction );
106
            end
107
108
            if ~( dot( edge_direction, obj.n1 ) == 0 && dot( edge_direction, obj.n2 ) == 0 )
                error 'Invalid edge direction, vector must be perpendicular to face normals'
109
            end
110
            obj.ed = edge_direction;
111
112
113
114
115
        end
        
        function beta = get.wedge_angle( obj )
            % Returns angle from main to opposite face through solid medium
            % of the wedge (radiant)
116
            if isequal( obj.et, 'outer_edge' )
117
                s = 1;
118
            elseif isequal( obj.et, 'inner_edge' )
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
                s = -1;
            end
            beta = pi - s * acos(dot(obj.main_face_normal, obj.opposite_face_normal));
        end
        
        function beta_deg = wedge_angle_deg( obj )
            % Get the wedge angle angle in degree
            beta_deg = rad2deg( obj.wedge_angle );
        end  
        
        function theta = get.opening_angle( obj )
            % Returns angle from main face to opposite face through propagation medium /
            % air (radiant)
            theta = 2 * pi - obj.wedge_angle;
        end
                
        function theta_deg = opening_angle_deg( obj )
            % Get the wedge opening angle in degree
            theta_deg = rad2deg( obj.opening_angle );
        end
        
        function l = get.location( obj )
            l = obj.l;
        end
        
144
145
146
147
148
149
150
        function obj =  set.location( obj, location )
            if numel( location ) ~= 3
                error( 'Location must be of dimension 3')
            end
            obj.l = location;
        end
        
151
152
        function b = validate_normals( obj )
            % Returns true, if the normals of the faces are both normalized
153
154
155
            b = false;
            if ( norm( obj.main_face_normal ) - 1 ) < eps && ( norm( obj.opposite_face_normal ) -1 ) < eps
               b = true;
156
157
158
            end
        end
        
159
        function et = wedge_type( obj )
160
            et = obj.edge_type;
161
            warning 'Function ''wedge_type'' is deprecated, use ''edge_type'' instead.'
162
163
164
165
        end
        
        function et = get.edge_type( obj )
            et = obj.et;
166
167
168
169
170
171
172
173
174
        end
        
        function bc = get.boundary_condition( obj )
            if obj.bc_hard
                bc = 'hard';
            else
                bc = 'soft';
            end
        end
175
                
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
        function obj = set.boundary_condition( obj, bc )
            if ischar(bc)
                if strcmpi('hard', bc)
                    obj.bc_hard = true;
                elseif strcmpi('soft', bc)
                    obj.bc_hard = false;
                else
                    error('boundary condition must be "hard" or "soft"!');
                end
            else
                error('boundary condtion must be of type character!');
            end
        end
        
        function obj = set.bc_hard( obj, b )
            obj.bc_hard = b;
        end
        
        function bc = is_boundary_condition_hard( obj )
            bc = obj.bc_hard;
        end
        
        function bc = is_boundary_condition_soft( obj )
            bc = ~obj.bc_hard;
200
201
202
203
        end
        
        % Legacy support (before renaming aperture to apex)
        
204
205
206
207
208
209
210
        function apx = approx_aperture_point( obj, source_pos, receiver_pos, varargin )
            if nargin == 3
                apx = obj.apex_point_approx( source_pos, receiver_pos );
            else
                spatial_precision = varargin;
                apx = obj.apex_point_approx( source_pos, receiver_pos, spatial_precision );
            end
211
212
213
        end
        
        function ap = get_aperture_point_far_field( obj, source_pos, receiver_pos )
214
            ap = obj.apex_point( source_pos, receiver_pos );
215
216
217
        end
        
        function b = point_on_aperture( obj, point )
218
            b = obj.point_on_edge( point );
219
220
221
        end
        
        function alpha_rad = get_angle_from_point_to_aperture( obj, field_point, point_on_edge )
222
            alpha_rad = obj.get_angle_from_point_to_apex( field_point, point_on_edge );
223
224
225
        end
                
        function ap = get_aperture_point( obj, source_pos, receiver_pos )
226
            ap = obj.apex_point( source_pos, receiver_pos );
227
228
229
230
231
232
233
234
235
236
        end
        
        function n = get.aperture_direction( obj )
            n = obj.edge_direction;
        end
        
        function obj = set.aperture_direction( obj, edge_direction_ )
            obj.edge_direction = edge_direction_;
        end
        
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    end
    
    
    methods (Static)
        function current_eps = set_get_geo_eps( new_eps )
            % Controls and returns the geometrical calculation precision value for
            % deciding e.g. if a point is inside or outside a wedge
            % (defaults to Matlab eps, but should be set for instance to
            % millimeter (1e-3) or micrometer (1e-6).
            persistent geo_eps;
            if nargin > 0
                geo_eps = new_eps;
            end
            if isempty( geo_eps )
                geo_eps = eps; % Default eps from Matlab double precision
            end
            current_eps = geo_eps;
        end
    end
end