cgv
Loading...
Searching...
No Matches
sphere.h
1#pragma once
2#include <cgv/math/vec.h>
3#include <cgv/math/functions.h>
4#include <cgv/math/det.h>
5#include <cgv/math/lin_solve.h>
6#include <limits>
7
8
9namespace cgv{
10 namespace math{
11
19template <typename T>
20T sphere_val(const vec<T>& sphere, const vec<T>& x)
21{
22
23 assert(sphere.size()-1 == x.size());
24
25 T val=0;
26 for(unsigned i = 0; i< x.size(); i++)
27 val += sqr(x(i)-sphere(i));
28
29 return sqrt(val)-sphere(sphere.size()-1);
30}
31
34template <typename T>
35vec<T> sphere_val(const vec<T>& sphere, const mat<T>& xs)
36{
37
38 assert(sphere.size()-1 == xs.ncols());
39
40 vec<T> vals=0;
41 for(unsigned i = 0; i< xs.ncols(); i++)
42 vals(i) += sphere_val(sphere,xs.col(i));
43
44 return vals;
45}
46
49template <typename T>
50T sphere_val2(const vec<T>& sphere, const vec<T>& x)
51{
52
53 assert(sphere.size()-1 == x.size());
54
55 T val=0;
56 for(unsigned i = 0; i< x.size(); i++)
57 val += sqr(x(i)-sphere(i));
58
59 return val-sqr(sphere(sphere.size()-1));
60}
61
64template <typename T>
65vec<T> sphere_val2(const vec<T>& sphere, const mat<T>& xs)
66{
67
68 assert(sphere.size()-1 == xs.ncols());
69
70 vec<T> vals=0;
71 for(unsigned i = 0; i< xs.ncols(); i++)
72 vals(i) += sphere_val2(sphere,xs.col(i));
73
74 return vals;
75}
76
78template <typename T>
79vec<T> sphere_fit(const vec<T>& p1)
80{
81 vec<T> sphere(4);
82 sphere.set(p1(0),p1(1),p1(2),std::numeric_limits<T>::epsilon());
83
84 return sphere;
85}
86
88template <typename T>
89vec<T> sphere_fit(const vec<T>& p1,const vec<T>& p2)
90{
91 vec<T> sphere(4);
92 vec<T> center = (T)0.5*(p1+p2);
93
94 sphere.set(center(0),center(1),center(2),length(p2-center)+ std::numeric_limits<T>::epsilon());
95
96 return sphere;
97}
98
100template<typename T>
101vec<T> sphere_fit(const vec<T>& O,const vec<T>& A,const vec<T>& B)
102{
103 vec<T> a = A - O;
104 vec<T> b = B - O;
105 T denominator = (T)2.0 * dot(cross(a , b) , cross(a , b));
106 vec<T> o = (dot(b,b) * cross(cross(a , b) , a) +
107 dot(a,a) * cross(b , cross(a , b))) / denominator;
108
109 T radius = length(o) + std::numeric_limits<T>::epsilon();
110 vec<T> center = O + o;
111
112 return vec<T>(center(0),center(1),center(2),radius);
113
114}
115
116
117
118
120template <typename T>
121vec<T> sphere_fit(const vec<T>& x1,const vec<T>& x2,const vec<T>& x3,const vec<T>& x4)
122{
123 mat<T> M(4,4);
124 M(0,0) = 1; M(0,1) = x1(0); M(0,2) = x1(1); M(0,3) = x1(2);
125 M(1,0) = 1; M(1,1) = x2(0); M(1,2) = x2(1); M(1,3) = x2(2);
126 M(2,0) = 1; M(2,1) = x3(0); M(2,2) = x3(1); M(2,3) = x3(2);
127 M(3,0) = 1; M(3,1) = x4(0); M(3,2) = x4(1); M(3,3) = x4(2);
128 vec<T> b(4);
129 b(0) = -dot(x1,x1);
130 b(1) = -dot(x2,x2);
131 b(2) = -dot(x3,x3);
132 b(3) = -dot(x4,x4);
133 vec<T> x;
134 cgv::math::solve(M,b,x);
135 vec<T> center = vec<T>(-x(1)/(T)2.0,-x(2)/(T)2.0,-x(3)/(T)2.0);
136 T radius = sqrt(dot(center,center)-x(0));
137 return vec<T>(center(0),center(1),center(2),radius);
138
139
140}
141
142
143//recursive helper function
144template <typename T>
145vec<T> recurse_mini_ball(T** P, unsigned int p, unsigned int b=0)
146{
147 vec<T> mb;
148
149 switch(b)
150 {
151 case 0:
152 mb=vec<T>((T)0,(T)0,(T)0,(T)-1);
153 break;
154 case 1:
155 mb = sphere_fit(vec<T>(3,(const T*)P[-1]));
156 break;
157 case 2:
158 mb = sphere_fit(vec<T>(3,(const T*)P[-1]),vec<T>(3,(const T*)P[-2]));
159 break;
160 case 3:
161 mb = sphere_fit(vec<T>(3,(const T*)P[-1]),vec<T>(3,(const T*)P[-2]),vec<T>(3,(const T*)P[-3]));
162 break;
163 case 4:
164 mb = sphere_fit(vec<T>(3,(const T*)P[-1]),vec<T>(3,(const T*)P[-2]),vec<T>(3,(const T*)P[-3])
165 ,vec<T>(3,(const T*)P[-4]));
166 return mb;
167 }
168
169 for(unsigned int i = 0; i < p; i++)
170 {
171 if(sphere_val2(mb,vec<T>(3,(const T*)P[i])) > 0) // Signed square distance to sphere
172 {
173 for(unsigned int j = i; j > 0; j--)
174 {
175 T *a = P[j];
176 P[j] = P[j - 1];
177 P[j - 1] = a;
178 }
179
180 mb = recurse_mini_ball(P + 1, i, b + 1);
181 }
182 }
183
184 return mb;
185 }
186
187
188
189
191template <typename T>
192vec<T> mini_ball(cgv::math::mat<T>& points)
193{
194 unsigned p = points.ncols();
195 T **L = new T*[p];
196
197 for(unsigned int i = 0; i < p; i++)
198 L[i] = &(points(0,i));
199
200
201
202 vec<T> mb = recurse_mini_ball(L, p);
203
204 delete[] L;
205
206 return mb;
207
208}
209
210
211 }
212}
213
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
Definition mat.h:208
unsigned ncols() const
number of columns
Definition mat.h:546
the cgv namespace
Definition print.h:11