DSC
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros
geometry.h
1 //
2 // Deformabel Simplicial Complex (DSC) method
3 // Copyright (C) 2013 Technical University of Denmark
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // See licence.txt for a copy of the GNU General Public License.
16 
17 #pragma once
18 
19 #include <array>
20 #include "util.h"
21 
22 namespace is_mesh {
23 
24  class Geometry {
25  protected:
26  bool inverse = false;
27 
28  public:
29  Geometry()
30  {
31 
32  }
33 
34  void invert()
35  {
36  inverse = !inverse;
37  }
38 
39  virtual bool is_inside(vec3 p) const
40  {
41  return true;
42  }
43 
44  virtual bool is_all_inside(std::vector<vec3> pos) const
45  {
46  for(vec3& p : pos)
47  {
48  if(!is_inside(p))
49  {
50  return false;
51  }
52  }
53  return true;
54  }
55 
56  virtual void clamp_vector(const vec3& p, vec3& v) const
57  {
58 
59  }
60 
61  virtual vec3 project(const vec3& p) const
62  {
63  return p;
64  }
65  };
66 
67  enum class SetType { Union, Intersection};
68 
69  class MultipleGeometry : public Geometry
70  {
71  std::vector<std::shared_ptr<Geometry>> geometries;
72  SetType setType;
73  public:
74 
75 
76  MultipleGeometry(SetType setType = SetType::Intersection)
77  :setType(setType)
78  {
79  }
80 
82  {
83  }
84 
85  const std::vector<std::shared_ptr<Geometry>> &get_geometries(){
86  return geometries;
87  }
88 
89  void add_geometry(std::shared_ptr<Geometry> geometry)
90  {
91  geometries.push_back(geometry);
92  }
93 
94  void clear(){
95  geometries.clear();
96  }
97 
98  void remove_geometry(std::shared_ptr<Geometry> geometry)
99  {
100  auto pos = std::find(geometries.begin(), geometries.end(), geometry);
101  if (pos != geometries.end()){
102  geometries.erase(pos);
103  }
104  }
105 
106  virtual bool is_inside(vec3 p) const
107  {
108  if (setType == SetType::Intersection){
109  for (auto geometry : geometries)
110  {
111  if(!geometry->is_inside(p))
112  {
113  return false;
114  }
115  }
116  return true;
117  } else if (setType == SetType::Union) {
118  for (auto geometry : geometries)
119  {
120  if(geometry->is_inside(p))
121  {
122  return true;
123  }
124  }
125  return false;
126  }
127  assert(false);
128  return false;
129  }
130 
131  virtual void clamp_vector(const vec3& p, vec3& v) const
132  {
133  for (auto geometry : geometries)
134  {
135  geometry->clamp_vector(p, v);
136  }
137  }
138 
139  virtual vec3 project(const vec3& p) const
140  {
141  vec3 proj_p;
142  double dist = INFINITY;
143  for (auto geometry : geometries)
144  {
145  vec3 pp = geometry->project(p);
146  if(sqr_length(pp - p) < dist)
147  {
148  dist = sqr_length(pp - p);
149  proj_p = pp;
150  }
151  }
152  return proj_p;
153  }
154 
155  };
156 
157  class Point : public Geometry {
158  protected:
159  vec3 point;
160 
161  public:
162  Point(vec3 c) : Geometry(), point(c)
163  {
164 
165  }
166 
167  virtual bool is_inside(vec3 p) const override
168  {
169  return sqr_length(p - point) < EPSILON;
170  }
171 
172  vec3 get_point() const {
173  return point;
174  }
175  };
176 
177  class Sphere : public Geometry {
178  protected:
179  vec3 point;
180  double radius2;
181 
182  public:
183  Sphere(vec3 c, double radius) : Geometry(), point(c),radius2(radius*radius)
184  {
185 
186  }
187 
188  virtual bool is_inside(vec3 p) const override
189  {
190  bool res = sqr_length(p - point) < radius2;
191  if (inverse){
192  res = !res;
193  }
194  return res;
195  }
196 
197  vec3 get_point() const {
198  return point;
199  }
200 
201  double get_radius() const {
202  return sqrt(radius2);
203  }
204  };
205 
206  class Cube : public Point {
207  protected:
208  vec3 size;
209  std::array<vec3, 3> directions;
210 
211  public:
212  Cube(vec3 c, vec3 s, vec3 x = vec3(1., 0., 0.), vec3 y = vec3(0., 1., 0.)) : Point(c), size(0.5*s)
213  {
214  directions[0] = normalize(x);
215  directions[1] = normalize(y);
216  directions[2] = normalize(cross(directions[0], directions[1]));
217  }
218 
219  vec3 get_size() const {
220  return size;
221  }
222 
223  std::array<vec3, 3> get_directions() const {
224  return directions;
225  }
226 
227  virtual bool is_inside(vec3 p) const override
228  {
229  if(!inverse)
230  {
231  for(int i = 0; i < 3; i++)
232  {
233  double d = dot(p - point, directions[i]);
234  if(std::abs(d) > size[i])
235  {
236  return false;
237  }
238  }
239  return true;
240  }
241  for(int i = 0; i < 3; i++)
242  {
243  double d = dot(p - point, directions[i]);
244  if(std::abs(d) > size[i] - EPSILON)
245  {
246  return true;
247  }
248  }
249  return false;
250  }
251 
252  virtual void clamp_vector(const vec3& p, vec3& v) const override
253  {
254  if(is_inside(p+v) != is_inside(p))
255  {
256  for (int i = 0; i < 3; i++) {
257 
258  double t = Util::intersection_ray_plane(p, v, point + size[i]*directions[i], directions[i]);
259  if(t >= 0. && t < 1.)
260  {
261  v = t*v;
262  }
263  t = Util::intersection_ray_plane(p, v, point - size[i]*directions[i], -directions[i]);
264  if(t >= 0. && t < 1.)
265  {
266  v = t*v;
267  }
268  }
269  }
270  }
271 
272  virtual vec3 project(const vec3& p) const
273  {
274  vec3 proj_p;
275  double dist = INFINITY;
276  for (int i = 0; i < 3; i++) {
277  vec3 pp = Util::project_point_plane(p, point + size[i]*directions[i], directions[i]);
278  if(sqr_length(pp - p) < dist)
279  {
280  dist = sqr_length(pp - p);
281  proj_p = pp;
282  }
283  pp = Util::project_point_plane(p, point - size[i]*directions[i], -directions[i]);
284  if(sqr_length(pp - p) < dist)
285  {
286  dist = sqr_length(pp - p);
287  proj_p = pp;
288  }
289  }
290 
291  return proj_p;
292  }
293  };
294 
295  class Cylinder : public Point {
296  protected:
297  double sqr_radius, height;
298  vec3 up_direction;
299  public:
300  Cylinder(vec3 c, double r, double h, vec3 up = vec3(0., 1., 0.)) : Point(c), sqr_radius(r*r), height(0.5*h), up_direction(normalize(up))
301  {
302 
303  }
304 
305  Cylinder(vec3 c, double r, vec3 up) : Point(c), sqr_radius(r*r), height(0.5*length(up)), up_direction(normalize(up))
306  {
307 
308  }
309 
310  double get_radius() const {
311  return sqrt(sqr_radius);
312  }
313 
314  double get_height() const {
315  return height;
316  }
317 
318  vec3 get_up_direction() const {
319  return up_direction;
320  }
321 
322  virtual bool is_inside(vec3 p) const override
323  {
324  double d = dot(p - point, up_direction);
325  if(std::abs(d) > height)
326  {
327  return false;
328  }
329 
330  vec3 p_proj = p - up_direction * d;
331  return sqr_length(p_proj - point) < sqr_radius;
332  }
333 
334  virtual void clamp_vector(const vec3& p, vec3& v) const override
335  {
336  assert(false); // NOT IMPLEMENTED YET!
337  if(is_inside(p+v) != is_inside(p))
338  {
339 
340  }
341  }
342 
343  virtual vec3 project(const vec3& p) const
344  {
345  assert(false); // NOT IMPLEMENTED YET!
346  return p;
347  }
348  };
349 
350  class Plane : public Point {
351  protected:
352  vec3 normal;
353 
354  public:
355  Plane(vec3 p, vec3 n) : Point(p), normal(normalize(n))
356  {
357 
358  }
359 
360  virtual bool is_inside(vec3 p) const override
361  {
362  return std::abs(dot(p - point, normal)) < EPSILON;
363  }
364 
365  vec3 get_normal() const {
366  return normal;
367  }
368  };
369 
370  class Circle : public Cylinder {
371 
372  public:
373  Circle(vec3 center, double radius, vec3 normal) : Cylinder(center, radius, 2.*EPSILON, normal)
374  {
375 
376  }
377  };
378 
379  class Square : public Cube {
380 
381  public:
382  Square(vec3 center, double width, double height, vec3 width_dir, vec3 height_dir) : Cube(center, vec3(width, height, 2.*EPSILON), width_dir, height_dir)
383  {
384 
385  }
386 
387  Square(vec3 center, vec3 width, vec3 height) : Cube(center, vec3(length(width), length(height), 2.*EPSILON), normalize(width), normalize(height))
388  {
389 
390  }
391  };
392 
393 }
Definition: geometry.h:69
Definition: geometry.h:24
Definition: geometry.h:379
A 3D double vector.
Definition: Vec3d.h:26
Definition: geometry.h:295
Definition: geometry.h:177
Definition: geometry.h:350
Definition: geometry.h:157
Definition: geometry.h:206
Definition: geometry.h:370