Flow123d  release_2.2.0-23-g01927c6
polygon.cpp
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file polygon.cpp
15  * @brief
16  */
17 
18 #include <iostream>
19 #include <vector>
20 
24 
25 using namespace mathfce;
26 
28 
30  return TPolygon::numberInstance++;
31 }
32 
34  id = generateId();
35 
36  area_is_actual = false;
37  center_is_actual = false;
38  center.SetCoord(0, 0, 0);
39  area = 0;
40 }
41 
43  TPolygon *pol = this;
45 
46  FOR_POL_VERTECES(pol, iv) {
47  delete (*iv);
48  }
49  verteces.clear();
50 }
51 
52 std::ostream & operator <<(std::ostream& stream, const TPolygon& p) {
54  int i = 0;
55 
56  // in the following, the explicit typecast is neccessary, since otherwise
57  // the operators '=' and '!=' are not defined (I wander why constantness
58  // of the Polygon instance can lead to this
59 
60  FOR_POL_VERTECES((TPolygon*) & p, iv) {
61  stream << "V" << i << " = " << (*iv)->GetPoint() << "\n";
62  i++;
63  }
64  return stream;
65 }
66 
67 void TPolygon::Add(const TPoint& P) {
69 
70  FOR_POL_VERTECES(this, iv) {
71  if ((*iv)->GetPoint() == P)
72  return;
73  }
74  TVertex* V = new TVertex(P);
75  int insertPos = InsertPosition(*V);
76  area_is_actual = false;
77  center_is_actual = false;
78  verteces.insert(verteces.begin() + insertPos, V);
79  return;
80 }
81 
83  if (!center_is_actual)
84  ComputeCenter();
85  if (area_is_actual)
86  return area;
87  ComputeArea();
88  return area;
89 }
90 
92  int i;
93  double D[ 3 ] = {0, 0, 0};
95  if (verteces.size() < 3) {
96  center.SetCoord(D[ 0 ], D[ 1 ], D[ 2 ]);
97  return;
98  }
99 
100  FOR_POL_VERTECES(this, iv) {
101  for (i = 0; i < 3; i++)
102  D[ i ] += (*iv)->GetPoint().Get(i + 1);
103  }
104  for (i = 0; i < 3; i++)
105  D[ i ] /= verteces.size();
106  center.SetCoord(D[ 0 ], D[ 1 ], D[ 2 ]);
107  center_is_actual = true;
108  return;
109 }
110 
112  if (center_is_actual)
113  return center;
114  ComputeCenter();
115  return center;
116 }
117 
119  TVertex *V1, *V2;
120  TVector U1, U2, N;
121  int pos = 0;
122 
123  // if size < 2 new vertex is insert at the end
124  if (verteces.size() < 2)
125  return verteces.size();
126 
127  // if size == 2 new vertex is insert at the end and normal vector is computed
128  if (verteces.size() == 2) {
129  V1 = (*(verteces.begin()));
130  V2 = (*(verteces.begin() + 1));
131 
132  U1 = V2->GetPoint() - V1->GetPoint();
133  U2 = Vx.GetPoint() - V1->GetPoint();
134  normal_vector = Cross(U1, U2);
135  return verteces.size();
136  }
137 
138  for (unsigned int i=0; i<verteces.size(); ++i) {
139  V1 = (*(verteces.begin() + i));
140  if (i == verteces.size() - 1)
141  V2 = (*(verteces.begin()));
142  else
143  V2 = (*(verteces.begin() + i + 1));
144  U1 = V2->GetPoint() - V1->GetPoint();
145  U2 = Vx.GetPoint() - V1->GetPoint();
146  N = Cross(U1, U2);
147  if (Dot(N, normal_vector) < 0) {
148  if (pos > 0) MessageOut() << "TPolygon::InsertPosition - ERROR: only one vector product must be negative\n";
149  pos = i+1;
150  }
151  }
152 
153  if (pos == 0) MessageOut() << "TPolygon::InsertPosition - ERROR: no vector product is negative\n";
154  return pos;
155 }
156 
159 
160  TTriangle T;
161  TPoint P1, P2, P3;
162 
163  area = 0;
164  area_is_actual = true;
165  if (verteces.size() < 3)
166  return;
167 
168  FOR_POL_VERTECES(this, iv) {
169  P1 = center;
170  P2 = (*iv)->GetPoint();
171  if (iv == verteces.end() - 1)
172  P3 = (*verteces.begin())->GetPoint();
173  else
174  P3 = (*(iv + 1))->GetPoint();
175  T.SetPoints(P1, P2, P3);
176  area += T.GetArea();
177  }
178  return;
179 }
180 
void ComputeCenter()
Definition: polygon.cpp:91
#define MessageOut()
Macro defining &#39;message&#39; record of log.
Definition: logger.hh:233
TPoint GetPoint() const
Definition: vertex.cpp:37
double GetArea()
Definition: triangle.cpp:148
TPoint GetCenter()
Definition: polygon.cpp:111
void ComputeArea()
Definition: polygon.cpp:157
Definition: point.h:27
static int numberInstance
Definition: polygon.h:30
void SetPoints(const TPoint &, const TPoint &, const TPoint &)
Definition: triangle.cpp:129
TVector Cross(const TVector &, const TVector &)
Definition: vector.cpp:180
~TPolygon()
Definition: polygon.cpp:42
int generateId()
Definition: polygon.cpp:29
int InsertPosition(const TVertex &Vx)
Definition: polygon.cpp:118
#define FOR_POL_VERTECES(i, j)
Definition: polygon.h:25
double GetArea()
Definition: polygon.cpp:82
void Add(const TPoint &)
Definition: polygon.cpp:67
TPolygon()
Definition: polygon.cpp:33
std::ostream & operator<<(std::ostream &stream, const TPolygon &p)
Definition: polygon.cpp:52
Definition: vertex.h:23
double Dot(const TVector &, const TVector &)
Definition: vector.cpp:197