Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmv-deformation.cc
Go to the documentation of this file.
1 /*
2  * lib-gmapkernel : Un noyau de 3-G-cartes et des opérations.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-gmapkernel
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 //******************************************************************************
25 #include "g-map-vertex.hh"
26 #include "geometry.hh"
27 using namespace GMap3d;
28 //******************************************************************************
30  TOrbit AOrbit, int ADirectInfoVertex)
31 {
32  assert(ADart!=NULL);
33 
34  int mark= getNewMark();
35 
36  markOrbit(ADart, AOrbit, mark);
37  applyMatrix(AMatrix, mark, ADirectInfoVertex);
38  unmarkOrbit(ADart, AOrbit, mark);
39 
40  freeMark(mark);
41 }
42 //******************************************************************************
44  int AMarkNumber, int ADirectInfoVertex)
45 {
46  int treated = getNewMark();
47 
48  for (CDynamicCoverageAll it(this); it.cont(); ++it)
49  if (!isMarked(*it, treated))
50  {
51  if (isMarked(*it, AMarkNumber))
52  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
53  {
54  setMark(*cov, treated);
55 
56  if (isOrbitUsed(*cov, ORBIT_VERTEX))
57  {
58  CVertex * Vdest = getVertex(*cov);
59  assert(Vdest!=NULL);
60 
61  CVertex * Vsrce =
62  ADirectInfoVertex<0 ? Vdest :
63  getDirectInfoAsVertex(*cov, ADirectInfoVertex);
64  assert(Vsrce!=NULL);
65 
66  AMatrix.applyOn(*Vsrce, *Vdest);
67  }
68  }
69  else
70  setMark(*it, treated);
71  }
72 
73  negateMaskMark(treated);
74  freeMark(treated);
75 }
76 //******************************************************************************
77 #define SET_VALUE(DART, INDEX, VALUE) \
78 ((* getDirectInfoAsCoord(DART, INDEX)) = (VALUE))
79 //------------------------------------------------------------------------------
80 void CGMapVertex::computeDistanceToVertex(int AMarkNumber, int ADirectInfoIndex,
81  const CVertex & AVertex)
82 {
83  int treated = getNewMark();
84 
85  for (CDynamicCoverageAll it(this); it.cont(); ++it)
86  if (!isMarked(*it, treated))
87  {
88  if (isMarked(*it, AMarkNumber))
89  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
90  {
91  setMark(*cov, treated);
92 
93  if (isOrbitUsed(*cov, ORBIT_VERTEX))
94  {
95  CVertex * vertex = getVertex(*cov);
96  assert(vertex!=NULL);
97 
98  SET_VALUE(*cov, ADirectInfoIndex,
99  CGeometry::distanceToVertex(*vertex, AVertex));
100  }
101  }
102  else
103  setMark(*it, treated);
104  }
105 
106  negateMaskMark(treated);
107  freeMark(treated);
108 }
109 //******************************************************************************
110 void CGMapVertex::computeDistanceToLine(int AMarkNumber, int ADirectInfoIndex,
111  const CVertex & ALineVertex,
112  const CVertex & ALineDirection)
113 {
114  assert(!ALineDirection.isNull());
115 
116  int treated = getNewMark();
117 
118  for (CDynamicCoverageAll it(this); it.cont(); ++it)
119  if (!isMarked(*it, treated))
120  {
121  if (isMarked(*it, AMarkNumber))
122  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
123  {
124  setMark(*cov, treated);
125 
126  if (isOrbitUsed(*cov, ORBIT_VERTEX))
127  {
128  CVertex * vertex = getVertex(*cov);
129  assert(vertex!=NULL);
130 
131  SET_VALUE(*cov, ADirectInfoIndex,
133  ALineVertex,
134  ALineDirection));
135  }
136  }
137  else
138  setMark(*it, treated);
139  }
140 
141  negateMaskMark(treated);
142  freeMark(treated);
143 }
144 //******************************************************************************
145 void CGMapVertex::computeDistanceToPlane(int AMarkNumber, int ADirectInfoIndex,
146  const CVertex & APlaneVertex,
147  const CVertex & APlaneNormal)
148 {
149  assert(!APlaneNormal.isNull());
150 
151  int treated = getNewMark();
152 
153  for (CDynamicCoverageAll it(this); it.cont(); ++it)
154  if (!isMarked(*it, treated))
155  {
156  if (isMarked(*it, AMarkNumber))
157  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
158  {
159  setMark(*cov, treated);
160 
161  if (isOrbitUsed(*cov, ORBIT_VERTEX))
162  {
163  CVertex * vertex = getVertex(*cov);
164  assert(vertex!=NULL);
165 
166  SET_VALUE(*cov, ADirectInfoIndex,
168  APlaneVertex,
169  APlaneNormal));
170  }
171  }
172  else
173  setMark(*it, treated);
174  }
175 
176  negateMaskMark(treated);
177  freeMark(treated);
178 }
179 //------------------------------------------------------------------------------
180 #undef SET_VALUE
181 //******************************************************************************
182 void CGMapVertex::normalizeParameter(int AMarkNumber, int ADirectInfoIndex,
183  TCoordinate AMin, TCoordinate AMax)
184 {
185  int treated = getNewMark();
186 
187  bool first = true;
188  /* Les variables suivantes sont initialisées uniquement pour éviter un warning
189  * à la compilation.
190  */
191  TCoordinate oldMin = 0, oldMax = 0;
192 
193  CDynamicCoverageAll it(this);
194 
195  for (; it.cont(); ++it)
196  if (!isMarked(*it, treated))
197  {
198  if (isMarked(*it, AMarkNumber))
199  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
200  {
201  setMark(*cov, treated);
202 
203  if (isOrbitUsed(*cov, ORBIT_VERTEX))
204  {
205  TCoordinate & value =
206  * getDirectInfoAsCoord(*cov,ADirectInfoIndex);
207 
208  if (first)
209  {
210  first = false;
211  oldMin = oldMax = value;
212  }
213  else
214  {
215  if (value < oldMin) oldMin = value;
216  if (value > oldMax) oldMax = value;
217  }
218  }
219  }
220  else
221  setMark(*it, treated);
222  }
223 
224  negateMaskMark(treated);
225 
226  for (it.reinit(); it.cont(); ++it)
227  if (!isMarked(*it, treated))
228  {
229  if (isMarked(*it, AMarkNumber))
230  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
231  {
232  setMark(*cov, treated);
233 
234  if (isOrbitUsed(*cov, ORBIT_VERTEX))
235  {
236  TCoordinate & value =
237  * getDirectInfoAsCoord(*cov,ADirectInfoIndex);
238 
239  if (oldMax==oldMin)
240  value = (AMin+AMax)/2;
241  else
242  value = AMin + (AMax-AMin)*(value-oldMin)/(oldMax-oldMin);
243  }
244  }
245  else
246  setMark(*it, treated);
247  }
248 
249  negateMaskMark(treated);
250  freeMark(treated);
251 }
252 //******************************************************************************
254  int ADirectInfoIndex,
255  TFunctionType AFunctionType)
256 {
257  if (AFunctionType==FUNCTION_LIN)
258  return;
259 
260  int treated = getNewMark();
261 
262  for (CDynamicCoverageAll it(this); it.cont(); ++it)
263  if (!isMarked(*it, treated))
264  {
265  if (isMarked(*it, AMarkNumber))
266  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
267  {
268  setMark(*cov, treated);
269 
270  if (isOrbitUsed(*cov, ORBIT_VERTEX))
271  {
272  TCoordinate & value =
273  * getDirectInfoAsCoord(*cov, ADirectInfoIndex);
274 
275  switch (AFunctionType)
276  {
277  case FUNCTION_QUAD: value = value*value ; break;
278  case FUNCTION_EXP : value = exp(value) ; break;
279  case FUNCTION_LOG : value = value<=0 ? 0 : log(value); break;
280  case FUNCTION_SIN : value = sin(value) ; break;
281  case FUNCTION_COS : value = cos(value) ; break;
282  default:
283  assert(false);
284  }
285  }
286  }
287  else
288  setMark(*it, treated);
289  }
290 
291  negateMaskMark(treated);
292  freeMark(treated);
293 }
294 //******************************************************************************
295 void CGMapVertex::translate(int AMarkNumber, const CVertex & AVector,
296  int ADirectInfoVertex, int ADirectInfoParam)
297 {
298 
299  if (ADirectInfoParam<0)
300  {
302  translationMatrix.translate(AVector);
303  applyMatrix(translationMatrix, AMarkNumber, ADirectInfoVertex);
304  return;
305  }
306 
307  int treated = getNewMark();
308 
309  for (CDynamicCoverageAll it(this); it.cont(); ++it)
310  if (!isMarked(*it, treated))
311  {
312  if (isMarked(*it, AMarkNumber))
313  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
314  {
315  setMark(*cov, treated);
316 
317  if (isOrbitUsed(*cov, ORBIT_VERTEX))
318  {
319  CVertex * Vdest = getVertex(*cov);
320  assert(Vdest!=NULL);
321 
322  CVertex * Vsrce =
323  ADirectInfoVertex<0 ? Vdest :
324  getDirectInfoAsVertex(*cov,ADirectInfoVertex);
325  assert(Vsrce!=NULL);
326 
327  TCoordinate param =
328  * getDirectInfoAsCoord(*cov,ADirectInfoParam);
329 
331  translationMatrix.translate(param*AVector);
332 
333  translationMatrix.applyOn(*Vsrce, *Vdest);
334  }
335  }
336  else
337  setMark(*it, treated);
338  }
339 
340  negateMaskMark(treated);
341  freeMark(treated);
342 }
343 //******************************************************************************
344 void CGMapVertex::rotate(int AMarkNumber,
345  const CVertex & AAxeVertex,
346  const CVertex & AAxeDirection,
347  TCoordinate AAngle,
348  int ADirectInfoVertex, int ADirectInfoParam)
349 {
350  if (ADirectInfoParam<0)
351  {
354  rotationMatrix.rotate(AAxeVertex, AAxeDirection, AAngle);
355  applyMatrix(rotationMatrix, AMarkNumber, ADirectInfoVertex);
356  return;
357  }
358 
359  int treated = getNewMark();
360 
361  for (CDynamicCoverageAll it(this); it.cont(); ++it)
362  if (!isMarked(*it, treated))
363  {
364  if (isMarked(*it, AMarkNumber))
365  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
366  {
367  setMark(*cov, treated);
368 
369  if (isOrbitUsed(*cov, ORBIT_VERTEX))
370  {
371  CVertex * Vdest = getVertex(*cov);
372  assert(Vdest!=NULL);
373 
374  CVertex * Vsrce =
375  ADirectInfoVertex<0 ? Vdest :
376  getDirectInfoAsVertex(*cov,ADirectInfoVertex);
377  assert(Vsrce!=NULL);
378 
379  TCoordinate param =
380  * getDirectInfoAsCoord(*cov, ADirectInfoParam);
381 
383  rotationMatrix.rotate(AAxeVertex, AAxeDirection,
384  param*AAngle);
385 
386  rotationMatrix.applyOn(*Vsrce, *Vdest);
387  }
388  }
389  else
390  setMark(*it, treated);
391  }
392 
393  negateMaskMark(treated);
394  freeMark(treated);
395 }
396 //******************************************************************************
397 void CGMapVertex::scale(int AMarkNumber,
398  const CVertex & ACenter, const CVertex & ACoef,
399  int ADirectInfoVertex, int ADirectInfoParam)
400 {
401  if (ADirectInfoParam<0)
402  {
404  scaleMatrix.scale(ACenter, ACoef);
405  applyMatrix(scaleMatrix, AMarkNumber, ADirectInfoVertex);
406  return;
407  }
408 
409  int treated = getNewMark();
410 
411  for (CDynamicCoverageAll it(this); it.cont(); ++it)
412  if (!isMarked(*it, treated))
413  {
414  if (isMarked(*it, AMarkNumber))
415  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
416  {
417  setMark(*cov, treated);
418 
419  if (isOrbitUsed(*cov, ORBIT_VERTEX))
420  {
421  CVertex * Vdest = getVertex(*cov);
422  assert(Vdest!=NULL);
423 
424  CVertex * Vsrce =
425  ADirectInfoVertex<0 ? Vdest :
426  getDirectInfoAsVertex(*cov, ADirectInfoVertex);
427  assert(Vsrce!=NULL);
428 
429  TCoordinate param =
430  * getDirectInfoAsCoord(*cov, ADirectInfoParam);
431 
433  scaleMatrix.scale(ACenter, param*ACoef);
434 
435  scaleMatrix.applyOn(*Vsrce, *Vdest);
436  }
437  }
438  else
439  setMark(*it, treated);
440  }
441 
442  negateMaskMark(treated);
443  freeMark(treated);
444 }
445 //******************************************************************************
446 void CGMapVertex::scale(int AMarkNumber,
447  const CVertex & ACenter, TCoordinate ACoef,
448  int ADirectInfoVertex, int ADirectInfoParam)
449 {
450  scale(AMarkNumber,
451  ACenter, CVertex(ACoef, ACoef, ACoef),
452  ADirectInfoVertex, ADirectInfoParam);
453 }
454 //******************************************************************************
455 void CGMapVertex::axialScale(int AMarkNumber,
456  const CVertex & AAxeVertex,
457  const CVertex & AAxeDirection,
458  TCoordinate ACoef,
459  int ADirectInfoVertex, int ADirectInfoParam)
460 {
461  assert(!AAxeDirection.isNull());
462 
463  if (ADirectInfoParam<0)
464  {
466  scaleMatrix.axialScale(AAxeVertex, AAxeDirection, ACoef);
467  applyMatrix(scaleMatrix, AMarkNumber, ADirectInfoVertex);
468  return;
469  }
470 
471  int treated = getNewMark();
472 
473  for (CDynamicCoverageAll it(this); it.cont(); ++it)
474  if (!isMarked(*it, treated))
475  {
476  if (isMarked(*it, AMarkNumber))
477  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
478  {
479  setMark(*cov, treated);
480 
481  if (isOrbitUsed(*cov, ORBIT_VERTEX))
482  {
483  CVertex * Vdest = getVertex(*cov);
484  assert(Vdest!=NULL);
485 
486  CVertex * Vsrce =
487  ADirectInfoVertex<0 ? Vdest :
488  getDirectInfoAsVertex(*cov, ADirectInfoVertex);
489  assert(Vsrce!=NULL);
490 
491  TCoordinate param =
492  * getDirectInfoAsCoord(*cov, ADirectInfoParam);
493 
495  scaleMatrix.axialScale(AAxeVertex, AAxeDirection,
496  param*ACoef);
497 
498  scaleMatrix.applyOn(*Vsrce, *Vdest);
499  }
500  }
501  else
502  setMark(*it, treated);
503  }
504 
505  negateMaskMark(treated);
506  freeMark(treated);
507 }
508 //******************************************************************************
509 void CGMapVertex::planarScale(int AMarkNumber,
510  const CVertex & APlaneVertex,
511  const CVertex & APlaneNormal,
512  TCoordinate ACoef,
513  int ADirectInfoVertex, int ADirectInfoParam)
514 {
515  assert(!APlaneNormal.isNull());
516 
517  if (ADirectInfoParam<0)
518  {
520  scaleMatrix.planarScale(APlaneVertex, APlaneNormal, ACoef);
521  applyMatrix(scaleMatrix, AMarkNumber, ADirectInfoVertex);
522  return;
523  }
524 
525  int treated = getNewMark();
526 
527  for (CDynamicCoverageAll it(this); it.cont(); ++it)
528  if (!isMarked(*it, treated))
529  {
530  if (isMarked(*it, AMarkNumber))
531  for (CDynamicCoverageVertex cov(this, *it); cov.cont(); ++cov)
532  {
533  setMark(*cov, treated);
534 
535  if (isOrbitUsed(*cov, ORBIT_VERTEX))
536  {
537  CVertex * Vdest = getVertex(*cov);
538  assert(Vdest!=NULL);
539 
540  CVertex * Vsrce =
541  ADirectInfoVertex<0 ? Vdest :
542  getDirectInfoAsVertex(*cov, ADirectInfoVertex);
543  assert(Vsrce!=NULL);
544 
545  TCoordinate param =
546  * getDirectInfoAsCoord(*cov, ADirectInfoParam);
547 
549  scaleMatrix.planarScale(APlaneVertex, APlaneNormal,
550  param*ACoef);
551 
552  scaleMatrix.applyOn(*Vsrce, *Vdest);
553  }
554  }
555  else
556  setMark(*it, treated);
557  }
558 
559  negateMaskMark(treated);
560  freeMark(treated);
561 }
562 //******************************************************************************
563 void CGMapVertex::orthoProjectOnPlane(int AMarkNumber,
564  TCoordinate AA,
565  TCoordinate AB,
566  TCoordinate AC,
567  TCoordinate AD)
568 {
569  int treated = getNewMark();
570 
571  for (CDynamicCoverageAll it(this); it.cont(); ++it)
572  if (! isMarked(*it, treated))
573  {
574  if (isMarked(*it, AMarkNumber))
575  {
576  CVertex & v = * findVertex(*it);
577 
578  v = CGeometry::orthoProjectVertexOnPlane(v, AA, AB, AC, AD);
579  }
580  else
581  setMark(*it, treated);
582  }
583 
584  negateMaskMark(treated);
585  freeMark(treated);
586 }
587 //******************************************************************************