KiCad PCB EDA Suite
wrlfacet.cpp File Reference
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <cmath>
#include "wrlfacet.h"

Go to the source code of this file.

Macros

#define GLM_FORCE_RADIANS
 
#define LOWER_LIMIT   (1e-12)
 

Functions

static bool VDegenerate (glm::vec3 *pts)
 
static WRLVEC3F VCalcTriNorm (const WRLVEC3F &p1, const WRLVEC3F &p2, const WRLVEC3F &p3)
 
static float VCalcCosAngle (const WRLVEC3F &p1, const WRLVEC3F &p2, const WRLVEC3F &p3)
 

Macro Definition Documentation

◆ GLM_FORCE_RADIANS

#define GLM_FORCE_RADIANS

Definition at line 26 of file wrlfacet.cpp.

◆ LOWER_LIMIT

#define LOWER_LIMIT   (1e-12)

Definition at line 34 of file wrlfacet.cpp.

Function Documentation

◆ VCalcCosAngle()

static float VCalcCosAngle ( const WRLVEC3F p1,
const WRLVEC3F p2,
const WRLVEC3F p3 
)
static

Definition at line 99 of file wrlfacet.cpp.

100 {
101  // note: p1 = reference vertex
102  float l12, l13;
103  float dx, dy, dz;
104 
105  dx = p2.x - p1.x;
106  dy = p2.y - p1.y;
107  dz = p2.z - p1.z;
108  float p12 = dx*dx + dy*dy + dz*dz;
109  l12 = sqrtf( p12 );
110 
111  dx = p3.x - p2.x;
112  dy = p3.y - p2.y;
113  dz = p3.z - p2.z;
114  float p23 = dx*dx + dy*dy + dz*dz;
115 
116  dx = p3.x - p1.x;
117  dy = p3.y - p1.y;
118  dz = p3.z - p1.z;
119  float p13 = dx*dx + dy*dy + dz*dz;
120  l13 = sqrtf( p13 );
121 
122  float dn = 2.0f * l12 * l13;
123 
124  // place a limit to prevent calculations from blowing up
125  if( dn < LOWER_LIMIT )
126  {
127  if( ( p12 + p13 - p23 ) < FLT_EPSILON )
128  return -1.0f;
129 
130  if( ( p12 + p13 - p23 ) > FLT_EPSILON )
131  return 1.0f;
132 
133  return 0.0f;
134  }
135 
136  float cosAngle = ( p12 + p13 - p23 ) / dn;
137 
138  // check the domain; errors in the cosAngle calculation can result in domain errors
139  if( cosAngle > 1.0f )
140  cosAngle = 1.0f;
141  else if( cosAngle < -1.0f )
142  cosAngle = -1.0f;
143 
144  // note: we are guaranteed that acosf() is never negative
145  return cosAngle;
146 }
#define LOWER_LIMIT
Definition: wrlfacet.cpp:34

References LOWER_LIMIT.

Referenced by FACET::CalcFaceNormal(), and FACET::CalcVertexNormal().

◆ VCalcTriNorm()

static WRLVEC3F VCalcTriNorm ( const WRLVEC3F p1,
const WRLVEC3F p2,
const WRLVEC3F p3 
)
static

Definition at line 69 of file wrlfacet.cpp.

70 {
71  // note: p1 = reference vertex
72  glm::vec3 tri = glm::vec3( 0.0, 0.0, 0.0 );
73  glm::vec3 pts[3];
74 
75  pts[0] = p1;
76  pts[1] = p2;
77  pts[2] = p3;
78 
79  // degenerate points are given a default 0, 0, 0 normal
80  if( VDegenerate( pts ) )
81  return tri;
82 
83  // normal
84  tri = glm::cross( pts[2] - pts[0], pts[1] - pts[0] );
85 
86  float dn = sqrtf( tri.x * tri.x + tri.y * tri.y + tri.z * tri.z );
87 
88  if( dn > LOWER_LIMIT )
89  {
90  tri.x /= dn;
91  tri.y /= dn;
92  tri.z /= dn;
93  }
94 
95  return tri;
96 }
static bool VDegenerate(glm::vec3 *pts)
Definition: wrlfacet.cpp:37
#define LOWER_LIMIT
Definition: wrlfacet.cpp:34

References LOWER_LIMIT, and VDegenerate().

Referenced by FACET::CalcFaceNormal().

◆ VDegenerate()

static bool VDegenerate ( glm::vec3 *  pts)
static

Definition at line 37 of file wrlfacet.cpp.

38 {
39  // note: only checks the degenerate case of zero length sides; it
40  // does not detect the case of 3 distinct collinear points
41 
42  double dx, dy, dz;
43 
44  dx = double{ pts[1].x } - pts[0].x;
45  dy = double{ pts[1].y } - pts[0].y;
46  dz = double{ pts[1].z } - pts[0].z;
47 
48  if( ( dx*dx + dy*dy + dz*dz ) < LOWER_LIMIT )
49  return true;
50 
51  dx = double{ pts[2].x } - pts[0].x;
52  dy = double{ pts[2].y } - pts[0].y;
53  dz = double{ pts[2].z } - pts[0].z;
54 
55  if( ( dx*dx + dy*dy + dz*dz ) < LOWER_LIMIT )
56  return true;
57 
58  dx = double{ pts[2].x } - pts[1].x;
59  dy = double{ pts[2].y } - pts[1].y;
60  dz = double{ pts[2].z } - pts[1].z;
61 
62  if( ( dx*dx + dy*dy + dz*dz ) < LOWER_LIMIT )
63  return true;
64 
65  return false;
66 }
#define LOWER_LIMIT
Definition: wrlfacet.cpp:34

References LOWER_LIMIT.

Referenced by VCalcTriNorm().