1 | #include "molecules.hpp"
|
---|
2 | #include "boundary.hpp"
|
---|
3 |
|
---|
4 |
|
---|
5 |
|
---|
6 |
|
---|
7 |
|
---|
8 |
|
---|
9 | void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule mol)
|
---|
10 | {
|
---|
11 | /* d2 ist der Normalenvektor auf dem Dreieck,
|
---|
12 | * d1 ist der Vektor, der normal auf der Kante und d2 steht.
|
---|
13 | */
|
---|
14 | Vector *dif_a;
|
---|
15 | Vector *dif_b;
|
---|
16 | Vector *Chord;
|
---|
17 | Vector *AngleCheck;
|
---|
18 | atom *Walker;
|
---|
19 |
|
---|
20 | dif_a.CopyVector(a.x);
|
---|
21 | dif_a.SubtractVector(Candidate->x);
|
---|
22 | dif_b.CopyVector(b.x);
|
---|
23 | dif.b.SubtractVector(Candidate->x);
|
---|
24 | Chord.CopyVector(a.x);
|
---|
25 | Chord.SubtractVector(b.x);
|
---|
26 | AngleCheck.CopyVector(dif_a);
|
---|
27 | AngleCheck.ProjectOntoPlane(Chord);
|
---|
28 |
|
---|
29 | //Storage eintrag fuer aktuelles Atom
|
---|
30 | if (Chord.Norm/(2*sin(dif_a.Angle(dif.b)))<RADIUS) //Using Formula for relation of chord length with inner angle to find of Ball will touch atom
|
---|
31 | {
|
---|
32 |
|
---|
33 | if (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1))>Storage[1]) //This will give absolute preference to those in "right-hand" quadrants
|
---|
34 | {
|
---|
35 | Storage[0]=(double)Candidate.nr;
|
---|
36 | Storage[1]=1;
|
---|
37 | Storage[2]=AngleCheck.Angle(d2);
|
---|
38 | }
|
---|
39 | else
|
---|
40 | {
|
---|
41 | if ((dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]>0 && Storage[2]< AngleCheck.Angle(d2)) or \
|
---|
42 | (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]<0 && Storage[2]> AngleCheck.Angle(d2)))
|
---|
43 | //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
|
---|
44 | {
|
---|
45 | Storage[0]=(double)Candidate.nr;
|
---|
46 | Storage[1]=dif_a.ScalarProduct(d1)/fabs(dif.ScalarProduct(d1));
|
---|
47 | Storage[2]=AngleCheck.Angle(d2);
|
---|
48 | }
|
---|
49 | }
|
---|
50 | }
|
---|
51 |
|
---|
52 | if (n<5)
|
---|
53 | {
|
---|
54 | for(i=0; i<mol.NumberOfBondsPerAtom[Candidate.nr];i++)
|
---|
55 | {
|
---|
56 | while (Candidate.nr != mol->ListOfBonds[Candidate.nr][i])
|
---|
57 | {
|
---|
58 | Walker = Walker.next;
|
---|
59 | }
|
---|
60 |
|
---|
61 | Find_next_suitable_point(a, b, Walker, n+1, d1, d2, RADIUS, mol);
|
---|
62 | }
|
---|
63 | }
|
---|
64 | }
|
---|
65 |
|
---|
66 |
|
---|
67 | void Find_next_suitable_triangle(molecule mol, BoundaryLineSet Line, BoundaryTriangleSet T)
|
---|
68 | {
|
---|
69 | Vector CenterOfLine = Line->endpoints.node[0].x;
|
---|
70 | Vector direction1;
|
---|
71 | Vector direction2;
|
---|
72 | Vector helper;
|
---|
73 |
|
---|
74 | double *Storage[3];
|
---|
75 | Storage[0]=-1; // Id must be positive, we see should nothing be done
|
---|
76 | Storage[1]=-1; // This direction is either +1 or -1 one, so any result will take precedence over initial values
|
---|
77 | Storage[2]=-10; // This is also lower then any value produced by an eligible atom, which are all positive
|
---|
78 |
|
---|
79 |
|
---|
80 | helper.CopyVector(Line->endpoints[0].x);
|
---|
81 | for (int i =0; i<3; i++)
|
---|
82 | {
|
---|
83 | if (T->endpoints[i].node.nr != Line->endpoints[0].node.nr && T->endpoints[i].node.nr!=Line->endpoints[1].node.nr)
|
---|
84 | {
|
---|
85 | helper.SubtractVector(T->endpoints[i].x);
|
---|
86 | break;
|
---|
87 | }
|
---|
88 | }
|
---|
89 |
|
---|
90 |
|
---|
91 | direction1.CopyVector(Line->endpoints.node[0].x);
|
---|
92 | direction1.Subtract(Line->endpoints.node[1].x);
|
---|
93 | direction1.Crossproduct(T.NormalVector);
|
---|
94 |
|
---|
95 | if (direction1.ScalarProduct(helper)>0)
|
---|
96 | {
|
---|
97 | direction1.Scale(-1);
|
---|
98 | }
|
---|
99 |
|
---|
100 | Find_next_suitable_point(Line->endpoints.node[0], Line->endpoints.node[1], Line->endpoints->node[0], 0, direction1, T.NormalVector, Storage, RADIUS);
|
---|
101 |
|
---|
102 | // Konstruiere nun neues Dreieck am Ende der Liste der Dreiecke
|
---|
103 | // Next Triangle is Line, atom with number in Storage[0]
|
---|
104 |
|
---|
105 | Walker=mol->start;
|
---|
106 | while (Walker.nr != (int)Storage[0])
|
---|
107 | {
|
---|
108 | Walker = Walker->next;
|
---|
109 | }
|
---|
110 |
|
---|
111 | AddPoint(Walker);
|
---|
112 |
|
---|
113 | BPS[0] = BoundaryPointSet(Walker);
|
---|
114 | BPS[1] = Line->enpoints.node[0];
|
---|
115 | BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
|
---|
116 | BPS[0] = Walker;
|
---|
117 | BPS[1] = Line->endpoints.node[1];
|
---|
118 | BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
|
---|
119 | BLS[2] = line;
|
---|
120 |
|
---|
121 | BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
|
---|
122 | TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
|
---|
123 | TrianglesOnBoundaryCount++;
|
---|
124 |
|
---|
125 | for(int i=0;i<NDIM;i++) // sind Linien bereits vorhanden ???
|
---|
126 | {
|
---|
127 | if (LinesOnBoundary.find(BTS->lines[i]) == LinesOnBoundary->end)
|
---|
128 | {
|
---|
129 | LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
|
---|
130 | LinesOnBoundaryCount++;
|
---|
131 | }
|
---|
132 | }
|
---|
133 | GetNormalVector(BTS.NormalVector);
|
---|
134 |
|
---|
135 | if( (BTS.NormalVector.ScalarProduct(T.NormalVecotr)<0 && Storage[1]>0) || \
|
---|
136 | (BTS.NormalVector.ScalarProduct(T.NormalVecotr)>0 && Storage[1]<0))
|
---|
137 | {
|
---|
138 | BTS.NormalVector.Scale(-1);
|
---|
139 | }
|
---|
140 |
|
---|
141 | }
|
---|
142 |
|
---|
143 |
|
---|
144 | void Find_starting_triangle(molecule mol)
|
---|
145 | {
|
---|
146 | atom Walker;
|
---|
147 | atom Walker2;
|
---|
148 | atom Walker3;
|
---|
149 | int max_index[3];
|
---|
150 | double max_coordinate[3];
|
---|
151 | Vector Oben;
|
---|
152 | Vector helper;
|
---|
153 |
|
---|
154 | Oben.Zero;
|
---|
155 |
|
---|
156 |
|
---|
157 | for(int i =0; i<3; i++)
|
---|
158 | {
|
---|
159 | max_index[i] =-1;
|
---|
160 | max_coordinate[i] =-1;
|
---|
161 | }
|
---|
162 |
|
---|
163 | Walker = mol->start;
|
---|
164 | while (Walker->next != NULL)
|
---|
165 | {
|
---|
166 | for (i=0; i<3; i++)
|
---|
167 | {
|
---|
168 | if (Walker.x[i]>max_coordinate[i])
|
---|
169 | {
|
---|
170 | max_coordinate[i]=Walker.x[i];
|
---|
171 | max_index[i]=Walker.nr;
|
---|
172 | }
|
---|
173 | }
|
---|
174 | }
|
---|
175 |
|
---|
176 | //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
|
---|
177 | const int k=0;
|
---|
178 |
|
---|
179 | Oben.x[k]=1;
|
---|
180 | Walker = mol->start;
|
---|
181 | while (Walker.nr != max_index[k])
|
---|
182 | {
|
---|
183 | Walker =Walker->next;
|
---|
184 | }
|
---|
185 |
|
---|
186 | double *Storage[3];
|
---|
187 | Storage[0]=-1; // Id must be positive, we see should nothing be done
|
---|
188 | Storage[1]=-2; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
|
---|
189 | Storage[2]=-10; // This will be an angle looking for the third point.
|
---|
190 |
|
---|
191 |
|
---|
192 | for (i=0; i< mol->NumberOfBondsPerAtoms[Walker.nr]; i++)
|
---|
193 | {
|
---|
194 | Walker2 = mol->start;
|
---|
195 | while (Walker2.nr != mol->ListOfBondsPerAtoms[Walker.nr][i]) // Stimmt die Ueberpruefung $$$
|
---|
196 | {
|
---|
197 | Walker2 =Walker2->next;
|
---|
198 | }
|
---|
199 |
|
---|
200 | Find_second_point_for_Tesselation(Walker, Walker2, Oben, Storage);
|
---|
201 | }
|
---|
202 |
|
---|
203 | Walker2=mol->start;
|
---|
204 |
|
---|
205 | while (Walker2.nr != int(Storage[0]))
|
---|
206 | {
|
---|
207 | Walker = Walker.next;
|
---|
208 | }
|
---|
209 |
|
---|
210 | helper.copyVector(Walker.x);
|
---|
211 | helper.Subtract(Walker2.x);
|
---|
212 | Oben.ProjectOntoPlane(helper.x);
|
---|
213 | helper.VectorProduct(Oben);
|
---|
214 |
|
---|
215 | Find_next_suitable_point(Walker, Walker2, Candidate, 0, helper, Oben, Storage, Radius);
|
---|
216 | Walker3 = mol->start;
|
---|
217 | while (Walker3.nr != int(Storage[0]))
|
---|
218 | {
|
---|
219 | Walker3 = Walker3->next;
|
---|
220 | }
|
---|
221 |
|
---|
222 | //Starting Triangle is Walker, Walker2, index Storage[0]
|
---|
223 |
|
---|
224 | AddPoint(Walker);
|
---|
225 | AddPoint(Walker2);
|
---|
226 | AddPoint(Walker3);
|
---|
227 |
|
---|
228 | BPS[0] = BoundaryPointSet(Walker);
|
---|
229 | BPS[1] = BoundaryPointSet(Walker2);
|
---|
230 | BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
|
---|
231 | BPS[0] = Walker;
|
---|
232 | BPS[1] = Walker3;
|
---|
233 | BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
|
---|
234 | BPS[0] = Walker;
|
---|
235 | BPS[1] = Walker2;
|
---|
236 | BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
|
---|
237 |
|
---|
238 | BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
|
---|
239 | TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
|
---|
240 | TrianglesOnBoundaryCount++;
|
---|
241 |
|
---|
242 | for(int i=0;i<NDIM;i++)
|
---|
243 | {
|
---|
244 | LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
|
---|
245 | LinesOnBoundaryCount++;
|
---|
246 | }
|
---|
247 |
|
---|
248 | }
|
---|
249 |
|
---|
250 |
|
---|
251 | void Find_non_convex_border(Tesselation Tess, molecule mol) // this needs input of type molecule
|
---|
252 | {
|
---|
253 |
|
---|
254 | Tess.Find_starting_triangle(mol);
|
---|
255 |
|
---|
256 | for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++)
|
---|
257 | if (baseline->second->TrianglesCount == 1)
|
---|
258 | {
|
---|
259 | Find_next_suitable_triangle(mol, baseline->second, baseline->second->triangles.begin()->second); //the line is there, so there is a triangle, but only one.
|
---|
260 |
|
---|
261 | }
|
---|
262 | else
|
---|
263 | {
|
---|
264 | printf("There is a line with %d triangles adjacent", baseline->second->TrianglesCount);
|
---|
265 | }
|
---|
266 | }
|
---|