particle_cell_2D_memo.hpp 8.03 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
4
5
// #define DEBUG

template <typename PFP>
void ParticleCell2DMemo<PFP>::move(const VEC3& newCurrent)
{
pitiot's avatar
pitiot committed
6
7
8
9
10
11
12
13
	this->crossCell = NO_CROSS ;
			if(!Geom::arePointsEquals(newCurrent, this->m_position))
			{
				switch(this->state) {
				case VERTEX : vertexState(newCurrent); break;
				case EDGE : 	edgeState(newCurrent);   break;
				case FACE : 	faceState(newCurrent);   break;
				}
Pierre Kraemer's avatar
Pierre Kraemer committed
14

pitiot's avatar
pitiot committed
15
16
17
18
19
//				display();
			}
			else
				this->m_position = newCurrent;
//	this->display();
Pierre Kraemer's avatar
Pierre Kraemer committed
20
21
22
23
24
25
}

template <typename PFP>
void ParticleCell2DMemo<PFP>::vertexState(const VEC3& current)
{
	#ifdef DEBUG
pitiot's avatar
pitiot committed
26
	CGoGNout << "vertexState" << d << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
27
	#endif
pitiot's avatar
pitiot committed
28
29
30
31
32
33
	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2]));

	this->crossCell = CROSS_OTHER;

	if(Algo::Geometry::isPointOnVertex<PFP>(this->m,this->d,this->m_positions,current))
	{
34
		this->state = VERTEX;
pitiot's avatar
pitiot committed
35
		this->m_position = current;
Pierre Kraemer's avatar
Pierre Kraemer committed
36
37
		return;
	}
pitiot's avatar
pitiot committed
38
39
	else
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
40
		//orientation step
pitiot's avatar
pitiot committed
41
42
43
44
		if(this->m_positions[this->d][0] == this->m_positions[this->m.phi1(this->d)][0] && this->m_positions[this->d][1] == this->m_positions[this->m.phi1(this->d)][1])
			this->d = this->m.phi2_1(this->d);
		if(getOrientationEdge(current,this->m.phi2_1(this->d)) != Geom::RIGHT)
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
45
			Dart dd_vert = this->d;
pitiot's avatar
pitiot committed
46
47
48
49
50
51
			do
			{
				this->d = this->m.phi2_1(this->d);
				if(this->m_positions[this->d][0] == this->m_positions[this->m.phi1(this->d)][0] && this->m_positions[this->d][1] == this->m_positions[this->m.phi1(this->d)][1])
					this->d = this->m.phi2_1(this->d);
			} while(getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT && dd_vert != this->d);
Pierre Kraemer's avatar
Pierre Kraemer committed
52

pitiot's avatar
pitiot committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
			if(dd_vert == this->d)
			{
				//orbit with 2 edges : point on one edge
				if(this->m.phi2_1(this->m.phi2_1(this->d)) == this->d)
				{
					if(!Algo::Geometry::isPointOnHalfEdge<PFP>(this->m,this->d,this->m_positions,current))
						this->d = this->m.phi2_1(this->d);
				}
				else
				{
					this->m_position = current;
					this->state = VERTEX;
					return;
				}
Pierre Kraemer's avatar
Pierre Kraemer committed
67
68
			}
		}
pitiot's avatar
pitiot committed
69
70
71
72
73
74
75
76
		else
		{
			Dart dd_vert = this->m.phi2_1(this->d);
			while(getOrientationEdge(current, this->d) == Geom::RIGHT && dd_vert != this->d)
			{
				this->d = this->m.phi12(this->d);
				if(this->m_positions[this->d][0] == this->m_positions[this->m.phi1(this->d)][0] && this->m_positions[this->d][1] == this->m_positions[this->m.phi1(this->d)][1])
					this->d = this->m.phi12(this->d);
Pierre Kraemer's avatar
Pierre Kraemer committed
77
78
79
80
			}
		}

		//displacement step
pitiot's avatar
pitiot committed
81
82
83
84
85
86
87
		memo_cross.push_back(this->d);
		if(getOrientationEdge(current, this->d) == Geom::ALIGNED && Algo::Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->m_positions, current))
			edgeState(current);
		else
		{
			this->d = this->m.phi1(this->d);
			faceState(current);
Pierre Kraemer's avatar
Pierre Kraemer committed
88
		}
pitiot's avatar
pitiot committed
89
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
90
91
92
93
94
95
}

template <typename PFP>
void ParticleCell2DMemo<PFP>::edgeState(const VEC3& current, Geom::Orientation2D sideOfEdge)
{
	#ifdef DEBUG
pitiot's avatar
pitiot committed
96
	CGoGNout << "edgeState" <<  d << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
97
	#endif
pitiot's avatar
pitiot committed
98
99
100
101
102
103
104
105
106
107
108
	memo_cross.push_back(this->d);
	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2]));
// 	assert(Algo::Geometry::isPointOnEdge<PFP>(m,d,m_positions,m_position));

	if(this->crossCell == NO_CROSS)
	{
		this->crossCell = CROSS_EDGE;
		this->lastCrossed = this->d;
	}
	else
		this->crossCell = CROSS_OTHER;
Pierre Kraemer's avatar
Pierre Kraemer committed
109

pitiot's avatar
pitiot committed
110
111
	if(sideOfEdge == Geom::ALIGNED)
		sideOfEdge = getOrientationEdge(current, this->d);
Pierre Kraemer's avatar
Pierre Kraemer committed
112

pitiot's avatar
pitiot committed
113
114
	switch(sideOfEdge)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
115
		case Geom::LEFT :
pitiot's avatar
pitiot committed
116
117
118
			this->d = this->m.phi1(this->d);
			faceState(current);
			return;
Pierre Kraemer's avatar
Pierre Kraemer committed
119
		case Geom::RIGHT:
pitiot's avatar
pitiot committed
120
121
122
123
124
			this->d = this->m.phi1(this->m.phi2(this->d));
			faceState(current);
			return;
		default :
			this->state = EDGE;
Pierre Kraemer's avatar
Pierre Kraemer committed
125
126
	}

pitiot's avatar
pitiot committed
127
128
	if(!Algo::Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->m_positions, current))
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
129
130
131
132
		this->m_position = this->m_positions[this->d];
		vertexState(current);
		return;
	}
pitiot's avatar
pitiot committed
133
134
135
	else if(!Algo::Geometry::isPointOnHalfEdge<PFP>(this->m, this->m.phi2(this->d), this->m_positions, current))
	{
		this->d = this->m.phi2(this->d);
Pierre Kraemer's avatar
Pierre Kraemer committed
136
137
138
139
140
		this->m_position = this->m_positions[this->d];
		vertexState(current);
		return;
	}

pitiot's avatar
pitiot committed
141
	this->m_position = current;
Pierre Kraemer's avatar
Pierre Kraemer committed
142
143
}

pitiot's avatar
pitiot committed
144
145


Pierre Kraemer's avatar
Pierre Kraemer committed
146
147
148
149
template <typename PFP>
void ParticleCell2DMemo<PFP>::faceState(const VEC3& current)
{
	#ifdef DEBUG
pitiot's avatar
pitiot committed
150
	CGoGNout << "faceState" <<  d << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
151
	#endif
pitiot's avatar
pitiot committed
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
	memo_cross.push_back(this->d);
 	assert(std::isfinite(this->m_position[0]) && std::isfinite(this->m_position[1]) && std::isfinite(this->m_position[2]));
 	assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2]));
// 	assert(Algo::Geometry::isPointInConvexFace2D<PFP>(m,d,m_positions,m_position,true));

	Dart dd = this->d;
	float wsoe = getOrientationFace(current, this->m_position, this->m.phi1(this->d));

	// orientation step
	if(wsoe != Geom::RIGHT)
	{
		this->d = this->m.phi1(this->d);
		wsoe = getOrientationFace(current, this->m_position, this->m.phi1(this->d));
		while(wsoe != Geom::RIGHT && dd != this->d)
		{
			this->d = this->m.phi1(this->d);
			wsoe = getOrientationFace(current, this->m_position, this->m.phi1(this->d));
		}

 		// source and position to reach are the same : verify if no edge is crossed due to numerical approximation
		if(dd == this->d)
		{
			do
			{
				switch (getOrientationEdge(current, this->d))
				{
				case Geom::LEFT: 	this->d = this->m.phi1(this->d);
Pierre Kraemer's avatar
Pierre Kraemer committed
179
									break;
pitiot's avatar
pitiot committed
180
				case Geom::ALIGNED:	this->m_position = current;
Pierre Kraemer's avatar
Pierre Kraemer committed
181
182
									edgeState(current);
									return;
pitiot's avatar
pitiot committed
183
184
185
186
187
188
189
				case Geom::RIGHT:
//									CGoGNout << "smthg went bad " << m_position << " " << current << CGoGNendl;
//									CGoGNout << "d1 " << m_positions[d] << " d2 " << m_positions[m.phi1(d)] << CGoGNendl;
					this->m_position = intersectLineEdge(current, this->m_position, this->d);
//									CGoGNout << " " << m_position << CGoGNendl;

									edgeState(current,Geom::RIGHT);
Pierre Kraemer's avatar
Pierre Kraemer committed
190
191
									return;
				}
pitiot's avatar
pitiot committed
192
			} while(this->d != dd);
Pierre Kraemer's avatar
Pierre Kraemer committed
193
			this->m_position = current;
194
			this->state = FACE;
pitiot's avatar
pitiot committed
195
196
197
198
199
200
201
202

// 			m_position = Algo::Geometry::faceCentroid<PFP>(m,d,m_positions);
// 			d = m.phi1(d);
// 			m_position = pointInFace(d);
// 			faceState(current);

// 			m_position = m_positions[d];
// 			vertexState(current);
Pierre Kraemer's avatar
Pierre Kraemer committed
203
204
			return;
		}
pitiot's avatar
pitiot committed
205
206
		// take the orientation with d1 : in case we are going through a vertex
		wsoe = getOrientationFace(current, this->m_position,this->d);
Pierre Kraemer's avatar
Pierre Kraemer committed
207
	}
pitiot's avatar
pitiot committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
	else
	{
		wsoe = getOrientationFace(current,this->m_position,this->d);
		while(wsoe == Geom::RIGHT && this->m.phi_1(this->d) != dd)
		{
			this->d = this->m.phi_1(this->d);
			wsoe = getOrientationFace(current, this->m_position, this->d);
		}

		// in case of numerical incoherence
		if(this->m.phi_1(this->d) == dd && wsoe == Geom::RIGHT)
		{
			this->d = this->m.phi_1(this->d);
			do
			{
				switch (getOrientationEdge(current, this->d))
				{
				case Geom::LEFT :
					this->d = this->m.phi1(this->d);
					break;
				case Geom::ALIGNED :
// 					CGoGNout << "pic" << CGoGNendl;
					this->m_position = current;
					edgeState(current);
					return;
				case Geom::RIGHT :
//					CGoGNout << "smthg went bad(2) " << m_position << CGoGNendl;
					this->m_position = intersectLineEdge(current, this->m_position, this->d);
// 					CGoGNout << " " << m_position << CGoGNendl;
					edgeState(current, Geom::RIGHT);
					return;
Pierre Kraemer's avatar
Pierre Kraemer committed
239
				}
pitiot's avatar
pitiot committed
240
			} while(this->d != dd);
Pierre Kraemer's avatar
Pierre Kraemer committed
241
242

			this->m_position = current;
243
			this->state = FACE;
Pierre Kraemer's avatar
Pierre Kraemer committed
244
245
246
247
248
			return;
		}
	}

	//displacement step
pitiot's avatar
pitiot committed
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
	memo_cross.push_back(this->d);
	switch (getOrientationEdge(current, this->d))
	{
	case Geom::LEFT :
		this->m_position = current;
		this->state = FACE;;
		break;
// 	case Geom::ALIGNED :
//		if(wsoe==Geom::ALIGNED) {
// 			m_position = m_positions[d];
// 			vertexState(current);
// 		}
// 		else {
// 			CGoGNout << "poc" << CGoGNendl;
// 			m_position = current;
// 			state = EDGE;
// 		}
// 		break;
	default :
		if(wsoe == Geom::ALIGNED)
		{

			this->d = this->m.phi1(this->d); //to check
			this->m_position = this->m_positions[this->d];
			vertexState(current);
		}
		else
		{
// 			CGoGNout << "wsoe : " << wsoe << CGoGNendl;
// 			CGoGNout << "current " << current << " " << m_position << CGoGNendl;
// 			CGoGNout << "d " << d << "d1 " << m_positions[d] << " d2 " << m_positions[m.phi2(d)] << CGoGNendl;
			this->m_position = intersectLineEdge(current, this->m_position, this->d);
// 			CGoGNout << " inter : " << m_position << CGoGNendl;
			edgeState(current, Geom::RIGHT);
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
284
	}
pitiot's avatar
pitiot committed
285
}