-
Notifications
You must be signed in to change notification settings - Fork 1
/
vt_centricEllipticalContourGeneration.m
182 lines (140 loc) · 9.06 KB
/
vt_centricEllipticalContourGeneration.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
function [PV_N, currTubeSectionDiameterCells_SegmentCounter] = vt_centricEllipticalContourGeneration(PV_N, numSections, totalTubeLengthInCells, tubeCummSectionLength, ellipseAxisLenInfo, boundaryInterpolation, tubeStart, gridCellTypes, ds)
% Set a counter to traverse through tubeCummSectionLength
tubeSegmentCounter = 1;
cellHalfLen = ds/2;
% Define currTubeSectionDiameterCells
% For ellptical cross-section, we will use this array to store the minor
% axis tube diamaters.
currTubeSectionDiameterCells_SegmentCounter = zeros(2, totalTubeLengthInCells);
tubeSemiMinorAxisRadiusInCells = zeros(1, totalTubeLengthInCells);
tubeSemiMajorAxisRadiusInCells = zeros(1, totalTubeLengthInCells);
% Set starting coordinte of tube mid-sagittal axis
startX = tubeStart.startX;
startY = tubeStart.startY;
startZ = tubeStart.startZ;
% STEP1: Each tube segment consists of number of yz-planes. We first store the
% tube semi-minor axis radius/length for each of those planes.
for tubeLenCellsCount = 1:totalTubeLengthInCells
% Check the current tube length
currTubeLength = tubeLenCellsCount*ds;
% Verify if the currTubeLength is more than the tubeCummSectionLength
% for the current sectionCounter
% if small or equal then set the tube wall as expected-normal Case
if currTubeLength <= tubeCummSectionLength(tubeSegmentCounter)
% Get the tube Radius
% We are subtracting 1 as we'll assume that there is a middle
% row of cells which will act like a mirror/centerline.
currSemiMajorAxisRadius = (ellipseAxisLenInfo(1, tubeSegmentCounter)-1)/2;
currSemiMinorAxisRadius = (ellipseAxisLenInfo(2, tubeSegmentCounter)-1)/2;
% store the current cross-section tube segment counter
currTubeSectionDiameterCells_SegmentCounter(2,tubeLenCellsCount) = tubeSegmentCounter;
else
% If the currTubeLength is greater than the actual tubeCummSectionLength
% Find the difference between currTubeLength and tubeCummSectionLength
diffLength = currTubeLength - tubeCummSectionLength(tubeSegmentCounter);
if diffLength>cellHalfLen && tubeSegmentCounter~=numSections
% Increase the tubeSegmentCounter
tubeSegmentCounter = tubeSegmentCounter+1;
% Get the radius for that cross-section [-1: each segment consist of odd number of cells]
currSemiMajorAxisRadius = (ellipseAxisLenInfo(1, tubeSegmentCounter)-1)/2;
currSemiMinorAxisRadius = (ellipseAxisLenInfo(2, tubeSegmentCounter)-1)/2;
% store the current cross-section tube segment counter
currTubeSectionDiameterCells_SegmentCounter(2,tubeLenCellsCount) = tubeSegmentCounter;
else
% Get the radius for that cross-section [-1: each segment consist of odd number of cells]
currSemiMajorAxisRadius = (ellipseAxisLenInfo(1, tubeSegmentCounter)-1)/2;
currSemiMinorAxisRadius = (ellipseAxisLenInfo(2, tubeSegmentCounter)-1)/2;
% store the current cross-section tube segment counter
currTubeSectionDiameterCells_SegmentCounter(2,tubeLenCellsCount) = tubeSegmentCounter;
% And then increase the tubeSegmentCounter
tubeSegmentCounter = tubeSegmentCounter+1;
end
end
tubeSemiMinorAxisRadiusInCells(tubeLenCellsCount) = currSemiMinorAxisRadius;
tubeSemiMajorAxisRadiusInCells(tubeLenCellsCount) = currSemiMajorAxisRadius;
end
if boundaryInterpolation == 1
% TODO: Deb - Think of what's the correct method to interpolate
% between two tube segmnts.
end
% Store the current cross-section tube segment semi-minor axis diameter
currTubeSectionDiameterCells_SegmentCounter(1,:) = tubeSemiMinorAxisRadiusInCells.*2+1;
% STEP2: Now as we have tubeRadius for each yz-plane, draw the vocal tract
% contour starting from the tubeStart.startX
for tubeLenCellsCount = 1:totalTubeLengthInCells
currSemiMajorAxisRadius = tubeSemiMajorAxisRadiusInCells(tubeLenCellsCount);
currSemiMinorAxisRadius = tubeSemiMinorAxisRadiusInCells(tubeLenCellsCount);
% The Y and Z coordinate of the tube central axis is not gonna
% change. Only the X axis will change as we move away from the
% glottal-end. We need to draw an ellipse in the yz-plane
% [-1 to start constructing tube exactly from the tubeStart.startX
% position]
% Deb: You mean tubeUpperY and tubeLowerY in yz-plane
tubeX = startX + (tubeLenCellsCount-1); %[For each iteration tubeX remains fix]
tubeUpperY = startY-currSemiMinorAxisRadius-1;
tubeLowerY = startY+currSemiMinorAxisRadius+1;
% Deb: tubeRightZ and tubeLeftZ mean the right and left side of
% the center in yz-plane.
tubeRightZ = startZ;
tubeLeftZ = startZ;
PV_N(tubeUpperY, tubeX, tubeRightZ, 5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY, tubeX, tubeLeftZ, 5) = gridCellTypes.cell_wall;
% Store the yCoordinate to close if there are any gaps
prevtubeUpperY = tubeUpperY;
prevtubeLowerY = tubeLowerY;
for semiMajorAxisRadiusCounter = 1:currSemiMajorAxisRadius
% Ellipse equation: z^2/a^2 + y^2/b^2 = 1 [Note: I have mentioned
% z^2 becasuse the semi-major axis is along the z-axis]
% a = (currSemiMajorAxisRadius+0.5)*ds [Length of semiMaorAxisRadius]
% b = (currSemiMinorAxisRadius+0.5)*ds [Length of semiMinorAxisRadius]
% z = semiMajorAxisRadiusCounter*ds
% Determine y (ellipse_height) = ? using Ellipse equation [i.e., height of the ellipse along y-axis]
a = (currSemiMajorAxisRadius+0.5)*ds;
b = (currSemiMinorAxisRadius+0.5)*ds;
z = semiMajorAxisRadiusCounter*ds;
currEllipseHeightFromCentralAxis = b*sqrt(1- (z^2/a^2));
currHeightFromTopOfCentralAxisRowCell = currEllipseHeightFromCentralAxis-(ds/2);
currHeightInCells = round(currHeightFromTopOfCentralAxisRowCell/ds);
% Define tube cross-section coordinates in the yz plane
tubeRightZ = startZ+semiMajorAxisRadiusCounter;
tubeLeftZ = startZ-semiMajorAxisRadiusCounter;
% Define tubeUpperY and tubeLowerY
tubeUpperY = startY-currHeightInCells-1;
tubeLowerY = startY+currHeightInCells+1;
PV_N(tubeUpperY,tubeX,tubeRightZ,5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY,tubeX,tubeRightZ,5) = gridCellTypes.cell_wall;
PV_N(tubeUpperY,tubeX,tubeLeftZ,5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY,tubeX,tubeLeftZ,5) = gridCellTypes.cell_wall;
% Connect grid cells in yz-plane if there are any gaps
if tubeUpperY-prevtubeUpperY > 1
PV_N(prevtubeUpperY+1:tubeUpperY,tubeX,tubeRightZ,5) = gridCellTypes.cell_wall;
PV_N(prevtubeUpperY+1:tubeUpperY,tubeX,tubeLeftZ,5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY:prevtubeLowerY-1,tubeX,tubeRightZ,5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY:prevtubeLowerY-1,tubeX,tubeLeftZ,5) = gridCellTypes.cell_wall;
end
prevtubeUpperY = tubeUpperY;
prevtubeLowerY = tubeLowerY;
end
% In the end close the circle by using walls at the complete right
% and left side of the yz-plane [as per the tube radius]
tubeUpperY = startY;
tubeLowerY = startY;
tubeRightZ = startZ+semiMajorAxisRadiusCounter+1;
tubeLeftZ = startZ-semiMajorAxisRadiusCounter-1;
PV_N(tubeUpperY, tubeX, tubeRightZ, 5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY, tubeX, tubeLeftZ, 5) = gridCellTypes.cell_wall;
if tubeUpperY-prevtubeUpperY > 1
PV_N(prevtubeUpperY+1:tubeUpperY,tubeX,tubeRightZ,5) = gridCellTypes.cell_wall;
PV_N(prevtubeUpperY+1:tubeUpperY,tubeX,tubeLeftZ,5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY:prevtubeLowerY-1,tubeX,tubeRightZ,5) = gridCellTypes.cell_wall;
PV_N(tubeLowerY:prevtubeLowerY-1,tubeX,tubeLeftZ,5) = gridCellTypes.cell_wall;
end
% Connect grid cells between two adjacent yz-planes if there are
% any gaps
if tubeX ~= startX && prevSemiMajorAxisRadius ~= currSemiMajorAxisRadius
PV_N = vt_tubeSegmentConnector(PV_N, prevSemiMajorAxisRadius, currSemiMajorAxisRadius, gridCellTypes, tubeX);
end
% Store the gridRadius for the current yz-plane
prevSemiMajorAxisRadius = currSemiMajorAxisRadius;
end
end