KiCad PCB EDA Suite
cpolygon4pts2d.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
5  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
30 #include "cpolygon4pts2d.h"
31 #include <wx/debug.h>
32 
33 
34 CPOLYGON4PTS2D::CPOLYGON4PTS2D( const SFVEC2F& v1, const SFVEC2F& v2, const SFVEC2F& v3,
35  const SFVEC2F& v4, const BOARD_ITEM& aBoardItem )
36  : COBJECT2D( OBJECT2D_TYPE::POLYGON4PT, aBoardItem )
37 {/*
38  if( (v1.x > v2.x) || (v1.y < v2.y) )
39  {
40  m_segments[0] = v4;
41  m_segments[1] = v3;
42  m_segments[2] = v2;
43  m_segments[3] = v1;
44  }
45  else
46  {*/
47  m_segments[0] = v1;
48  m_segments[1] = v4;
49  m_segments[2] = v3;
50  m_segments[3] = v2;
51  // }
52 
53  unsigned int i;
54  unsigned int j = 4 - 1;
55 
56  for( i = 0; i < 4; j = i++ )
57  {
58  SFVEC2F slope = m_segments[j] - m_segments[i];
59  m_precalc_slope[i] = slope;
60  m_seg_normal[i] = glm::normalize( SFVEC2F( -slope.y, +slope.x ) );
61  }
62 
63  m_bbox.Reset();
64  m_bbox.Union( v1 );
65  m_bbox.Union( v2 );
66  m_bbox.Union( v3 );
67  m_bbox.Union( v4 );
74 
75  wxASSERT( m_bbox.IsInitialized() );
76 }
77 
78 
79 bool CPOLYGON4PTS2D::Intersects( const CBBOX2D &aBBox ) const
80 {
81  return m_bbox.Intersects( aBBox );
82 
83  // This source code is not working OK.
84  /*
85  if( !m_bbox.Intersects( aBBox ) )
86  return false;
87 
88  // Check if the bounding box complety have inside the small bounding box
89  if( (aBBox.Max().x > m_bbox.Max().x) &&
90  (aBBox.Max().y > m_bbox.Max().x) &&
91  (aBBox.Min().x < m_bbox.Min().x) &&
92  (aBBox.Min().y < m_bbox.Min().y)
93  )
94  return true;
95 
96  SFVEC2F v[4];
97 
98  v[0] = aBBox.Min();
99  v[1] = SFVEC2F( aBBox.Min().x, aBBox.Max().y );
100  v[2] = aBBox.Max();
101  v[3] = SFVEC2F( aBBox.Max().x, aBBox.Min().y );
102 
103  for( unsigned int i = 0; i < 4; i++ )
104  {
105  if( IntersectSegment( m_segments[i], m_precalc_slope[i], v[0], v[1] - v[0] ) )
106  return true;
107  if( IntersectSegment( m_segments[i], m_precalc_slope[i], v[1], v[2] - v[1] ) )
108  return true;
109  if( IntersectSegment( m_segments[i], m_precalc_slope[i], v[2], v[3] - v[2] ) )
110  return true;
111  if( IntersectSegment( m_segments[i], m_precalc_slope[i], v[3], v[0] - v[3] ) )
112  return true;
113  }
114 
115  if( IsPointInside( v[0] ) )
116  return true;
117  if( IsPointInside( v[1] ) )
118  return true;
119  if( IsPointInside( v[2] ) )
120  return true;
121  if( IsPointInside( v[3] ) )
122  return true;
123 
124  return false;*/
125 }
126 
127 
128 bool CPOLYGON4PTS2D::Overlaps( const CBBOX2D &aBBox ) const
129 {
130  // NOT IMPLEMENTED
131  return true;
132 }
133 
134 
135 bool CPOLYGON4PTS2D::Intersect( const RAYSEG2D &aSegRay,
136  float *aOutT,
137  SFVEC2F *aNormalOut ) const
138 {
139  wxASSERT( aOutT );
140  wxASSERT( aNormalOut );
141 
142  bool hited = false;
143  unsigned int hitIndex;
144  float bestHitT;
145 
146  for( unsigned int i = 0; i < 4; i++ )
147  {
148  float t;
149 
150  if( aSegRay.IntersectSegment( m_segments[i], m_precalc_slope[i], &t ) )
151  if( (hited == false) || ( t < bestHitT) )
152  {
153  hited = true;
154  hitIndex = i;
155  bestHitT = t;
156  }
157  }
158 
159  if( hited )
160  {
161  wxASSERT( (bestHitT >= 0.0f) && (bestHitT <= 1.0f) );
162 
163  *aOutT = bestHitT;
164  *aNormalOut = m_seg_normal[hitIndex];
165 
166  return true;
167  }
168 
169  return false;
170 }
171 
172 
174 {
175  // !TODO:
176 
178 }
179 
180 
181 bool CPOLYGON4PTS2D::IsPointInside( const SFVEC2F &aPoint ) const
182 {
183  unsigned int i;
184  unsigned int j = 4 - 1;
185  bool oddNodes = false;
186 
187  for( i = 0; i < 4; j = i++ )
188  {
189  const float polyJY = m_segments[j].y;
190  const float polyIY = m_segments[i].y;
191 
192  if( ((polyIY <= aPoint.y) && (polyJY >= aPoint.y)) ||
193  ((polyJY <= aPoint.y) && (polyIY >= aPoint.y))
194  )
195  {
196  const float polyJX = m_segments[j].x;
197  const float polyIX = m_segments[i].x;
198 
199  if( (polyIX <= aPoint.x) || (polyJX <= aPoint.x) )
200  {
201  oddNodes ^= ( ( polyIX +
202  ( ( aPoint.y - polyIY ) / ( polyJY - polyIY ) ) *
203  ( polyJX - polyIX ) ) < aPoint.x );
204  }
205  }
206  }
207 
208  return oddNodes;
209 }
INTERSECTION_RESULT
Definition: cobject2d.h:38
bool Overlaps(const CBBOX2D &aBBox) const override
Function Overlaps.
void Union(const SFVEC2F &aPoint)
Function Union recalculate the bounding box adding a point.
Definition: cbbox2d.cpp:94
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
CBBOX manages a bounding box defined by two SFVEC2F min max points.
Definition: cbbox2d.h:40
SFVEC2F m_segments[4]
void Reset()
Function Reset reset the bounding box to zero and de-initialized it.
Definition: cbbox2d.cpp:87
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
bool IntersectSegment(const SFVEC2F &aStart, const SFVEC2F &aEnd_minus_start, float *aOutT) const
Definition: ray.cpp:294
SFVEC2F m_seg_normal[4]
bool Intersects(const CBBOX2D &aBBox) const
Function Intersects test if a bounding box intersects this box.
Definition: cbbox2d.cpp:212
bool IsInitialized() const
Function IsInitialized check if this bounding box is already initialized.
Definition: cbbox2d.cpp:78
bool Intersect(const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut) const override
Function Intersect.
void ScaleNextUp()
Function ScaleNextUp scales a bounding box to the next float representation making it larger.
Definition: cbbox2d.cpp:163
CBBOX2D m_bbox
Definition: cobject2d.h:65
SFVEC2F m_precalc_slope[4]
bool Intersects(const CBBOX2D &aBBox) const override
Function Intersects.
A simplified 4 point polygon.
SFVEC2F m_centroid
Definition: cobject2d.h:66
OBJECT2D_TYPE
Definition: cobject2d.h:46
SFVEC2F GetCenter() const
Function GetCenter return the center point of the bounding box.
Definition: cbbox2d.cpp:120
CPOLYGON4PTS2D(const SFVEC2F &v1, const SFVEC2F &v2, const SFVEC2F &v3, const SFVEC2F &v4, const BOARD_ITEM &aBoardItem)
INTERSECTION_RESULT IsBBoxInside(const CBBOX2D &aBBox) const override
Function IsBBoxInside.
Definition: ray.h:110
bool IsPointInside(const SFVEC2F &aPoint) const override