TexGen
SectionPolygon.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2006 Martin Sherburn
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18=============================================================================*/
19
20#include "PrecompiledHeaders.h"
21#include "SectionPolygon.h"
22using namespace TexGen;
23
24CSectionPolygon::CSectionPolygon(const vector<XY> &PolygonPoints, bool bSingleQuadrant, bool bRetainPoints)
25: m_PolygonPoints(PolygonPoints),
26m_bRetainPoints(bRetainPoints)
27{
28
29 if (bSingleQuadrant)
30 {
31 vector<XY>::const_iterator itPoint;
32 XY P;
33 // Reflect to top left quadrant
34 for (itPoint = PolygonPoints.end()-2; itPoint != PolygonPoints.begin(); --itPoint)
35 {
36 P = *itPoint;
37 P.x *= -1;
38 m_PolygonPoints.push_back(P);
39 }
40 // Reflect to bottom left quadrant
41 for (itPoint = PolygonPoints.begin(); itPoint != PolygonPoints.end(); ++itPoint)
42 {
43 P = *itPoint;
44 P.y *= -1;
45 P.x *= -1;
46 m_PolygonPoints.push_back(P);
47 }
48 // Reflect to bottom right quadrant
49 for (itPoint = PolygonPoints.end()-2; itPoint != PolygonPoints.begin(); --itPoint)
50 {
51 P = *itPoint;
52 P.y *= -1;
53 m_PolygonPoints.push_back(P);
54 }
55 }
56
58 if (bRetainPoints)
60}
61
63{
64}
65
66bool CSectionPolygon::operator == (const CSection &CompareMe) const
67{
68 if (CompareMe.GetType() != GetType())
69 return false;
70 return m_PolygonPoints == ((CSectionPolygon*)&CompareMe)->m_PolygonPoints;
71}
72
74: CSection(Element)
75{
76 m_bRetainPoints = valueify<bool>(Element.Attribute("RetainPoints"));
77 FOR_EACH_TIXMLELEMENT(pPoint, Element, "PolygonPoint")
78 {
79 m_PolygonPoints.push_back(valueify<XY>(pPoint->Attribute("value")));
80 }
84}
85
86void CSectionPolygon::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
87{
88 CSection::PopulateTiXmlElement(Element, OutputType);
89 Element.SetAttribute("RetainPoints", stringify(m_bRetainPoints));
90 vector<XY>::const_iterator itPoint;
91 for (itPoint = m_PolygonPoints.begin(); itPoint != m_PolygonPoints.end(); ++itPoint)
92 {
93 TiXmlElement Point("PolygonPoint");
94 Point.SetAttribute("value", stringify(*itPoint));
95 Element.InsertEndChild(Point);
96 }
97}
98
99/*XY CSectionPolygon::GetPoint(double t) const
100{
101 t *= m_PolygonPoints.size();
102 int iIndex = int(t);
103 t -= iIndex;
104 XY P1, P2;
105 P1 = m_PolygonPoints[iIndex];
106 P2 = m_PolygonPoints[(iIndex+1)%m_PolygonPoints.size()];
107 return P1 + (P2-P1) * t;
108}*/
109
111{
112 vector<double>::const_iterator itT;
113 vector<XY>::const_iterator itPoint;
114
115 // Find which points given t value lies between
116 int i;
117 for( itT = m_t.begin(), i = 0; itT != m_t.end(); ++itT, ++i )
118 {
119 if ( fabs(*itT - t) < 1e-10 )
120 return( m_PolygonPoints[i] );
121 if ( *itT > t )
122 break;
123 }
124 XY P;
125 double t2 = itT == m_t.end() ? 1.0 : m_t[i]; // If last point t = 1.0
126 // Interpolate between points to find point for given t value
127 P = m_PolygonPoints[i-1] + ( (t - m_t[i-1]) / (t2 - m_t[i-1]) * (m_PolygonPoints[i%m_PolygonPoints.size()]-m_PolygonPoints[i-1]));
128 return P;
129}
130
132{
133 return "Polygon(N:" + stringify(m_PolygonPoints.size()) + ")";
134}
135
137{
138 vector<XY>::iterator itPoint;
139 for (itPoint = m_PolygonPoints.begin(); itPoint != m_PolygonPoints.end(); ++itPoint)
140 {
141 itPoint->x *= Scale.x;
142 itPoint->y *= Scale.y;
143 }
144}
145
146void CSectionPolygon::Scale(double dScale)
147{
148 vector<XY>::iterator itPoint;
149 for (itPoint = m_PolygonPoints.begin(); itPoint != m_PolygonPoints.end(); ++itPoint)
150 {
151 *itPoint *= dScale;
152 }
153}
154
156{
157// Find length of perimeter of section
158 vector<XY>::const_iterator itPoint;
159 double dTotalLength = 0.0;
160 itPoint = m_PolygonPoints.begin();
161 XY StartPoint = *itPoint;
162 XY LastPoint = *itPoint;
163
164 m_t.push_back( 0.0 );
165 while( ++itPoint != m_PolygonPoints.end() )
166 {
167 dTotalLength += GetLength( *itPoint, LastPoint );
168 m_t.push_back( dTotalLength );
169 LastPoint = *itPoint;
170 }
171 dTotalLength += GetLength( LastPoint, StartPoint );
172
173 // Assign t for each section point as proportion of distance around perimeter from start point
174 vector<double>::iterator itT;
175 for ( itT = m_t.begin(); itT != m_t.end(); ++itT )
176 {
177 *itT /= dTotalLength;
178 }
179}
180
182{
183 m_bEquiSpaced = false;
184 m_EdgePoints.clear();
185
187}
188
189
190
191
192
193
#define FOR_EACH_TIXMLELEMENT(CHILDELEMENT, PARENTELEMENT, ELEMENTNAME)
Macro to enable looping over tinyxml easier.
Definition: Misc.h:45
Abstract base class respresenting a yarn cross-section.
Definition: Section.h:31
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
Used for saving data to XML.
Definition: Section.cpp:51
vector< XY > m_EdgePoints
List of 2d points creating the outline of the cross-section.
Definition: Section.h:119
bool m_bEquiSpaced
Keep this variable to determine whether the section was created with equidistant points or not.
Definition: Section.h:122
virtual string GetType() const =0
Derived class should return the class name.
Creates a polygonal section, where a list of points are given to form the closed polygon.
string GetDefaultName() const
Get the default name to assign to a section.
vector< XY > m_PolygonPoints
XY GetPoint(double t) const
Get a point lying on the perimeter correspending to parametric value t.
void CreateSection() const
Create section with edge points same as polygon points.
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
Used for saving data to XML.
void Scale(XY Scale)
Change the scale of the section by multiplying each coordinate component by the component given by th...
string GetType() const
Derived class should return the class name.
void CalcTValues()
Assign t value as proportion of distance around perimeter for each point.
vector< double > m_t
The proportion of the distance around the total perimeter range from 0 to 1 for each point.
CSectionPolygon(const vector< XY > &PolygonPoints, bool bSingleQuadrant=false, bool bRetainPoints=false)
bool operator==(const CSection &CompareMe) const
Overloaded equality operator to determine if two sections are the same.
bool m_bRetainPoints
Whether or not to use the polygon points to define the section edge points.
Namespace containing a series of customised math operations not found in the standard c++ library.
OUTPUT_TYPE
Definition: Misc.h:105
double GetLength(const XYZ &Point1, const XYZ &Point2)
Get the length between two points.
Definition: mymath.h:540
std::string stringify(const T &x, int iPrecision=12, bool bScientific=true)
Function to convert a value (e.g. int, double, etc...) to a string.
Definition: Misc.h:50
Struct for representing points in 2D space.
Definition: mymath.h:103
double x
Definition: mymath.h:104
double y
Definition: mymath.h:104