particle_cell_2D_secured.hpp 8.14 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
24

25 26 27 28 29 30 31 32 33 34 35 36
namespace CGoGN
{

namespace Algo
{

namespace Surface
{

namespace MovingObjects
{

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
template <typename PFP>
std::vector<Dart> ParticleCell2DSecured<PFP>::move(const VEC3& goal)
{
	this->crossCell = NO_CROSS ;
	if (!Geom::arePointsEquals(goal, this->getPosition()))
	{
		CellMarkerMemo<FACE> memo_cross(this->m);
//		memo_cross.mark(this->d);

		switch (this->getState())
		{
			case VERTEX :
				vertexState(goal,memo_cross) ;
				break ;
			case EDGE :
				edgeState(goal,memo_cross) ;
				break ;
			case FACE :
				faceState(goal,memo_cross) ;
				break ;
		}

		return memo_cross.get_markedCells();
	}
	else
62
		this->Algo::MovingObjects::ParticleBase<PFP>::move(goal) ;
63 64 65 66 67 68 69

	std::vector<Dart> res;
	res.push_back(this->d);
	return res;
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
70
void ParticleCell2DSecured<PFP>::vertexState(const VEC3& current, CellMarkerMemo<MAP, FACE>& memo_cross)
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
{
#ifdef DEBUG
	CGoGNout << "vertexState" << this->d << CGoGNendl ;
#endif

//	std::vector<Dart> mc = memo_cross.get_markedCells();
//	if(std::find(mc.begin(),mc.end(),this->d)!=mc.end())
//	{
//		std::cout << "Error : particle outside map (vertex) " << std::endl;
//		return;
//	}
//	else
	{
		assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
		this->crossCell = CROSS_OTHER ;

87
		if (Geometry::isPointOnVertex < PFP > (this->m, this->d, this->positionAttribut, current))
88 89
		{
			this->setState(VERTEX) ;
90
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
			return ;
		}
		else
		{
			//orientation step
			if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0] && this->positionAttribut[this->d][1] == this->positionAttribut[this->m.phi1(this->d)][1])
				this->d = this->m.phi2_1(this->d) ;
			if (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT)
			{
				Dart dd_vert = this->d ;
				do
				{
					this->d = this->m.phi2_1(this->d) ;
					if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0]
						&& this->positionAttribut[this->d][1]== this->positionAttribut[this->m.phi1(this->d)][1])
						this->d = this->m.phi2_1(this->d) ;
				} while (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT && dd_vert != this->d) ;

				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)
					{
114
						if (!Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
115 116 117 118 119 120 121
							this->d = this->m.phi2_1(this->d) ;
					}
					else
					{
						//checking : case with 3 orthogonal darts and point on an edge
						do
						{
122 123
							if(Geometry::isPointOnHalfEdge<PFP>(this->m,this->d,this->positionAttribut,current)
									&& Geometry::isPointOnHalfEdge<PFP>(this->m,this->m.phi2(this->d),this->positionAttribut,current)
124 125 126 127 128 129 130 131 132 133
									&& this->getOrientationEdge(current, this->d) == Geom::ALIGNED)
							{

								this->edgeState(current,memo_cross) ;

								return;
							}
							this->d = this->m.phi2_1(this->d) ;
						} while (this->getOrientationEdge(current, this->m.phi2_1(this->d)) != Geom::RIGHT && dd_vert != this->d) ;

134
						this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
						this->setState(VERTEX) ;
						return ;
					}
				}
			}
			else
			{
				Dart dd_vert = this->m.phi2_1(this->d) ;
				while (this->getOrientationEdge(current, this->d) == Geom::RIGHT && dd_vert != this->d)
				{
					this->d = this->m.phi12(this->d) ;
					if (this->positionAttribut[this->d][0] == this->positionAttribut[this->m.phi1(this->d)][0]
						&& this->positionAttribut[this->d][1] == this->positionAttribut[this->m.phi1(this->d)][1])
						this->d = this->m.phi12(this->d) ;
				}
			}

			//displacement step

			if (this->getOrientationEdge(current, this->d) == Geom::ALIGNED
155
					&& Geometry::isPointOnHalfEdge<PFP>(this->m, this->d, this->positionAttribut, current))
156 157 158 159 160 161 162 163 164 165 166
				edgeState(current,memo_cross) ;
			else
			{
				this->d = this->m.phi1(this->d) ;
				faceState(current,memo_cross) ;
			}
		}
	}
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
167
void ParticleCell2DSecured<PFP>::edgeState(const VEC3& current, CellMarkerMemo<MAP, FACE>& memo_cross, Geom::Orientation2D sideOfEdge)
168 169 170 171 172 173 174 175 176 177 178 179 180 181
{
#ifdef DEBUG
	CGoGNout << "edgeState" << this->d << CGoGNendl ;
#endif

//	std::vector<Dart> mc = memo_cross.get_markedCells();
//	if(std::find(mc.begin(),mc.end(),this->d)!=mc.end())
//	{
//		std::cout << "Error : particle outside map (edge)" << std::endl;
//		return;
//	}
//	else
	{
			assert(std::isfinite(current[0]) && std::isfinite(current[1]) && std::isfinite(current[2])) ;
182
		// 	assert(Geometry::isPointOnEdge<PFP>(m,d,m_positions,m_position));
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
			if (this->crossCell == NO_CROSS)
			{
				this->crossCell = CROSS_EDGE ;
				this->lastCrossed = this->d ;
			}
			else
				this->crossCell = CROSS_OTHER ;

			if (sideOfEdge == Geom::ALIGNED) sideOfEdge = this->getOrientationEdge(current, this->d) ;

			switch (sideOfEdge)
			{
				case Geom::LEFT :
					this->d = this->m.phi1(this->d) ;
					faceState(current,memo_cross) ;
					return ;
				case Geom::RIGHT :
					this->d = this->m.phi1(this->m.phi2(this->d)) ;
					faceState(current,memo_cross) ;
					return ;
				default :
					this->setState(EDGE) ;
					break ;
			}

208
			if (!Geometry::isPointOnHalfEdge < PFP
209 210
				> (this->m, this->d, this->positionAttribut, current))
			{
211
				this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
212 213 214
				vertexState(current,memo_cross) ;
				return ;
			}
215
			else if (!Geometry::isPointOnHalfEdge < PFP
216 217 218
				> (this->m, this->m.phi2(this->d), this->positionAttribut, current))
			{
				this->d = this->m.phi2(this->d) ;
219
				this->Algo::MovingObjects::ParticleBase<PFP>::move(this->positionAttribut[this->d]) ;
220 221 222 223
				vertexState(current,memo_cross) ;
				return ;
			}

224
			this->Algo::MovingObjects::ParticleBase<PFP>::move(current) ;
225 226 227 228 229
	}

}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
230
void ParticleCell2DSecured<PFP>::faceState(const VEC3& current, CellMarkerMemo<MAP, FACE>& memo_cross)
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
{
#ifdef DEBUG
	CGoGNout << "faceState" << this->d << CGoGNendl ;
#endif

	std::vector<Dart> mc = memo_cross.get_markedCells();
	if(std::find(mc.begin(),mc.end(),this->d)!=mc.end())
	{
		std::cout << "Error : particle outside map (face)" << std::endl;
		return;
	}
	else
	{
		ParticleCell2DMemo<PFP>::faceState(current,memo_cross);
	}

247
}
248

Pierre Kraemer's avatar
Pierre Kraemer committed
249 250 251 252 253 254 255
} // namespace MovingObjects

} // namespace Surface

} // namespace Algo

} // namespace CGoGN