V3FIT
vertex.cpp
1 //
2 // vertex.cpp
3 // lgrid
4 //
5 // Created by Cianciosa, Mark R. on 10/12/15.
6 // Copyright (c) 2015 Cianciosa, Mark R. All rights reserved.
7 //
8 
9 #include "vertex.hpp"
10 #include <cmath>
11 #include <algorithm>
12 #include <iostream>
13 
14 //------------------------------------------------------------------------------
20 //------------------------------------------------------------------------------
21 vertex::vertex(const vector3d point_) : point(point_) {
22  this->next = this;
23  this->last = this;
24 }
25 
26 //------------------------------------------------------------------------------
31 //------------------------------------------------------------------------------
33  this->last->next = nullptr;
34  if (this->next != nullptr) {
35  delete this->next;
36  }
37 }
38 
39 //------------------------------------------------------------------------------
43 //------------------------------------------------------------------------------
45  this->last->next = v;
46  v->last = this->last;
47  this->last = v;
48  v->next = this;
49 }
50 
51 //------------------------------------------------------------------------------
59 //------------------------------------------------------------------------------
60 const vector3d vertex::get_normal(const vertex &v1, const vertex &v2) {
61  const vector3d line_vector = v2.point - v1.point;
62  return vector3d(line_vector.y, -line_vector.x, 0.0).normalize();
63 }
64 
65 //------------------------------------------------------------------------------
75 //------------------------------------------------------------------------------
76 const vector3d vertex::get_normal(const vertex &v1, const vertex &v2, const vertex &v3) {
77  const vector3d norm_vector1 = get_normal(v1, v2);
78  const vector3d norm_vector2 = get_normal(v2, v3);
79  return (norm_vector2 + norm_vector1)/2.0;
80 }
81 
82 // The next set of functions defines are used to find the distance from a point to a line.
83 //------------------------------------------------------------------------------
91 //------------------------------------------------------------------------------
92 const double vertex::a(const vertex &v1, const vertex &v2) {
93  return v2.point.y - v1.point.y;
94 }
95 
96 //------------------------------------------------------------------------------
104 //------------------------------------------------------------------------------
105 const double vertex::b(const vertex &v1, const vertex &v2) {
106  return -(v2.point.x - v1.point.x);
107 }
108 
109 //------------------------------------------------------------------------------
117 //------------------------------------------------------------------------------
118 const double vertex::c(const vertex &v1, const vertex &v2) {
119  return v2.point.x*v1.point.y - v1.point.x*v2.point.y;
120 }
121 
122 // Find the minimum x and y position along the line to the point.
123 //------------------------------------------------------------------------------
132 //------------------------------------------------------------------------------
133 const double vertex::x_min(const vertex &v1, const vertex &v2, const vector3d &p) {
134  const double a_value = a(v1, v2);
135  const double b_value = b(v1, v2);
136  return (b_value*(b_value*p.x - a_value*p.y) - a_value*c(v1, v2))/(a_value*a_value + b_value*b_value);
137 }
138 
139 //------------------------------------------------------------------------------
148 //------------------------------------------------------------------------------
149 const double vertex::y_min(const vertex &v1, const vertex &v2, const vector3d &p) {
150  const double a_value = a(v1, v2);
151  const double b_value = b(v1, v2);
152  return (a_value*(-b_value*p.x + a_value*p.y) - b_value*c(v1, v2))/(a_value*a_value + b_value*b_value);
153 }
154 
155 //------------------------------------------------------------------------------
164 //------------------------------------------------------------------------------
165 const double vertex::length(const vertex &v1, const vertex &v2, const vector3d &p) {
166  const double a_value = a(v1, v2);
167  const double b_value = b(v1, v2);
168  return fabs(a_value*p.x + b_value*p.y + c(v1, v2))/sqrt(a_value*a_value + b_value*b_value);
169 }
170 
171 //------------------------------------------------------------------------------
179 //------------------------------------------------------------------------------
180 const double vertex::length(const vertex &v, const vector3d &p) {
181  return (v.point - p).length();
182 }
183 
184 //------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------
196 const bool vertex::in_range(const vertex &v1, const vertex &v2, const double x, const double y) {
197  return (std::min(v1.point.x, v2.point.x) <= x && std::max(v1.point.x, v2.point.x) >= x) && (std::min(v1.point.y, v2.point.y) <= y && std::max(v1.point.y, v2.point.y) >= y);
198 }
199 
200 //------------------------------------------------------------------------------
210 //------------------------------------------------------------------------------
211 const double vertex::direction(const vertex &v, const vector3d &n, const vector3d &p) {
212  return std::signbit(vector3d::dot_product(v.point - p, n)) ? 1.0 : -1.0;
213 }
214 
215 //------------------------------------------------------------------------------
224 //------------------------------------------------------------------------------
225 void vertex::distance(vertex *start, const vector3d &p, std::vector<double> &d) {
226  for (vertex *v = start; v->next != start; v = v->next) {
227  const double x = x_min(*v, *(v->next), p);
228  const double y = y_min(*v, *(v->next), p);
229  if (in_range(*v, *(v->next), x, y)) {
230  d.push_back(direction(*v, get_normal(*v, *(v->next)), p)*length(*v, *(v->next), p));
231  } else {
232  // Normal is outside the line segment from v to v->next. Check the two corners.
233  d.push_back(direction(*v, get_normal(*(v->last), *v, *(v->next)), p)*length(*v, p));
234  d.push_back(direction(*(v->next), get_normal(*v, *(v->next), *(v->next->next)), p)*length(*(v->next), p));
235  }
236  }
237 
238  // Get distance to last segment.
239  const double x = x_min(*(start->last), *start, p);
240  const double y = y_min(*(start->last), *start, p);
241  if (in_range(*(start->last), *start, x, y)) {
242  d.push_back(direction(*(start->last), get_normal(*(start->last), *start), p)*length(*(start->last), *start, p));
243  } else {
244  // Normal is outside the line segment from v to v->next. Check the two corners.
245  d.push_back(direction(*(start->last), get_normal(*(start->last->last), *(start->last), *start), p)*length(*(start->last), p));
246  d.push_back(direction(*start, get_normal(*(start->last), *start, *(start->next)), p)*length(*start, p));
247  }
248 }
249 
250 //------------------------------------------------------------------------------
256 //------------------------------------------------------------------------------
257 void vertex::print(vertex *start) {
258  std::cout << start->point.x << " " << start->point.y << std::endl;
259  for (vertex *v = start->next; v != start; v = v->next) {
260  std::cout << v->point.x << " " << v->point.y << std::endl;
261  }
262 }
vertex::y_min
static const double y_min(const vertex &v1, const vertex &v2, const vector3d &p)
Minimum distance in the y direction.
Definition: vertex.cpp:149
vertex::next
vertex * next
Vertex next vertex.
Definition: vertex.hpp:26
vertex::print
static void print(vertex *start)
Print out all vertices.
Definition: vertex.cpp:257
vertex::a
static const double a(const vertex &v1, const vertex &v2)
a coefficient.
Definition: vertex.cpp:92
vertex::b
static const double b(const vertex &v1, const vertex &v2)
b coefficient.
Definition: vertex.cpp:105
vertex
A vertex.
Definition: vertex.hpp:21
vertex::point
const vector3d point
Vertex point.
Definition: vertex.hpp:23
vertex::direction
static const double direction(const vertex &v, const vector3d &n, const vector3d &p)
Finds which side of the limiter face the point is on.
Definition: vertex.cpp:211
vector3d
A vector.
Definition: vector3d.hpp:19
vector3d::x
const double x
x component.
Definition: vector3d.hpp:22
vertex::vertex
vertex(const vector3d point_)
vertex constructor.
Definition: vertex.cpp:21
vector3d::dot_product
static const double dot_product(const vector3d &v1, const vector3d &v2)
Takes the doc product of two vectors.
Definition: vector3d.cpp:71
vertex::~vertex
~vertex()
vertex destructor.
Definition: vertex.cpp:32
vertex::length
static const double length(const vertex &v1, const vertex &v2, const vector3d &p)
Distance to a limiter face.
Definition: vertex.cpp:165
vector3d::normalize
const vector3d normalize() const
Normalize vector3d instance.
Definition: vector3d.cpp:43
vertex::get_normal
static const vector3d get_normal(const vertex &v1, const vertex &v2)
Normal to a line.
Definition: vertex.cpp:60
vertex::in_range
static const bool in_range(const vertex &v1, const vertex &v2, const double x, const double y)
Finds if the line to the point is in range.
Definition: vertex.cpp:196
vertex::c
static const double c(const vertex &v1, const vertex &v2)
c coefficient.
Definition: vertex.cpp:118
vertex::distance
static void distance(vertex *start, const vector3d &p, std::vector< double > &d)
Find the distances to the limiter.
Definition: vertex.cpp:225
vertex::last
vertex * last
Vertex last vertex.
Definition: vertex.hpp:28
vertex::x_min
static const double x_min(const vertex &v1, const vertex &v2, const vector3d &p)
Minimum distance in the x direction.
Definition: vertex.cpp:133
vector3d::y
const double y
y component.
Definition: vector3d.hpp:24
vertex::insert
void insert(vertex *v)
Insert a new vertex.
Definition: vertex.cpp:44