source: molecuilder/src/border.cpp@ a709c4

Last change on this file since a709c4 was a709c4, checked in by Christian Neuen <neuen@…>, 17 years ago

Construction of border triangles of non convex point set

  • Property mode set to 100644
File size: 5.0 KB
Line 
1#include "molecules.hpp"
2#include "boundary.hpp"
3
4inline int round(double x)
5{
6 //brauche ich das hier? Kann ich mit int operieren?
7 return int(x > 0.0 ? x + 0.5 : x - 0.5);
8}
9
10
11
12
13void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS)
14{
15 /* d2 ist der Normalenvektor auf dem Dreieck,
16 * d1 ist der Vektor, der normal auf der Kante und d2 steht.
17 */
18 Vector *dif_a;
19 Vector *dif_b;
20 Vector *Chord;
21 Vector *AngleCheck;
22 atom *Walker;
23
24 dif_a.CopyVector(a.x);
25 dif_a.SubtractVector(Candidate->x);
26 dif_b.CopyVector(b.x);
27 dif.b.SubtractVector(Candidate->x);
28 Chord.CopyVector(a.x);
29 Chord.SubtractVector(b.x);
30 AngleCheck.CopyVector(dif_a);
31 AngleCheck.ProjectOntoPlane(Chord);
32
33 //Storage eintrag fuer aktuelles Atom
34 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
35 {
36
37 if (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1))>Storage[1]) //This will give absolute preference to those in "right-hand" quadrants
38 {
39 Storage[0]=(double)Candidate.nr;
40 Storage[1]=1;
41 Storage[2]=AngleCheck.Angle(d2);
42 }
43 else
44 {
45 if ((dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]>0 && Storage[2]< AngleCheck.Angle(d2)) or \
46 (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]<0 && Storage[2]> AngleCheck.Angle(d2)))
47 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
48 {
49 Storage[0]=(double)Candidate.nr;
50 Storage[1]=dif_a.ScalarProduct(d1)/fabs(dif.ScalarProduct(d1));
51 Storage[2]=AngleCheck.Angle(d2);
52 }
53 }
54 }
55
56 if (n<5)
57 {
58 for(i=0; i<molecule.NumberOfBondsPerAtom[Candidate.nr];i++)
59 {
60 while (Candidate.nr != molecule->ListOfBonds[Candidate.nr][i])
61 {
62 Walker = Walker.next;
63 }
64
65 Find_next_suitable_point(a, b, Walker, n+1, d1, d2, RADIUS);
66 }
67 }
68}
69
70
71void Find_next_suitable_triangle(Triangle T, BoundaryLine Line)
72{
73 Vector CenterOfLine = Line->endpoints.node[0].x;
74 Vector direction1;
75 Vector direction2;
76 Vector helper;
77
78 double *Storage[3];
79 Storage[0]=-1; // Id must be positive, we see should nothing be done
80 Storage[1]=-2; // This direction is either +1 or -1 one, so any result will take precedence over initial values
81 Storage[2]=-10; // This is also lower then any value produced by an eligible atom, though due to Storage[1] this is of no concern
82
83
84 helper.CopyVector(Line->endpoints[0].x);
85 for (int i =0; i<3; i++)
86 {
87 if (T->endpoints[i].node.nr != Line->endpoints[0].node.nr && T->endpoints[i].node.nr!=Line->endpoints[1].node.nr)
88 {
89 helper.SubtractVector(T->endpoints[i].x);
90 break;
91 }
92 }
93
94
95 direction1.CopyVector(Line->endpoints.node[0].x);
96 direction1.Subtract(Line->endpoints.node[1].x);
97 direction1.Crossproduct(T.NormalVector);
98
99 if (direction1.ScalarProduct(helper)>0)
100 {
101 direction1.Scale(-1);
102 }
103
104 Find_next_suitable_point(Line->endpoints.node[0], Line->endpoints.node[1], Line->endpoints->node[0], 0, direction1, T.NormalVector, Storage, RADIUS);
105
106 // Konstruiere nun neues Dreieck am Ende der Liste der Dreiecke
107 // Next Triangle is Line, atom with number in Storage[0]
108
109}
110
111
112void Find_starting_triangle()
113{
114 atom Walker;
115 atom Walker2;
116 int max_index[3];
117 double max_coordinate[3];
118 Vector Oben;
119 Vector helper;
120
121 Oben.Zero;
122
123
124 for(int i =0; i<3; i++)
125 {
126 max_index[i] =-1;
127 max_coordinate[i] =-1;
128 }
129
130 Walker = molecule->start;
131 while (Walker->next != NULL)
132 {
133 for (i=0; i<3; i++)
134 {
135 if (Walker.x[i]>max_coordinate[i])
136 {
137 max_coordinate[i]=Walker.x[i];
138 max_index[i]=Walker.nr;
139 }
140 }
141 }
142
143 //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
144 const int k=0;
145
146 Oben.x[k]=1;
147 Walker = molecule->start;
148 while (Walker.nr != max_index[k])
149 {
150 Walker =Walker->next;
151 }
152
153 double *Storage[3];
154 Storage[0]=-1; // Id must be positive, we see should nothing be done
155 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.
156 Storage[2]=-10; // This will be an angle looking for the third point.
157
158
159 for (i=0; i< molecule->NumberOfBondsPerAtoms[Walker.nr]; i++)
160 {
161 Walker2 = molecule->start;
162 while (Walker2.nr != molecule->ListOfBondsPerAtoms[Walker.nr][i]) // Stimmt die Ueberpruefung $$$
163 {
164 Walker2 =Walker2->next;
165 }
166
167 Find_second_point_for_Tesselation(Walker, Walker2, Oben, Storage);
168 }
169
170 Walker2=molecule->start;
171
172 while (Walker2.nr != int(Storage[0]))
173 {
174 Walker = Walker.next;
175 }
176
177 helper.copyVector(Walker.x);
178 helper.Subtract(Walker2.x);
179 Oben.ProjectOntoPlane(helper.x);
180 helper.VectorProduct(Oben);
181
182 Find_next_suitable_point(Walker, Walker2, Candidate, 0, helper, Oben, Storage, Radius);
183
184 //Starting Triangle is Walker, Walker2, index Storage[0]
185
186}
187
188
189void Find_non_convex_border()
190{
191
192}
Note: See TracBrowser for help on using the repository browser.