119 return Point_3d<T>(-cos(phi)*sin(theta),-sin(theta)*sin(phi),cos(theta));
178template <
typename T =
double>
182 v[0] = v[1] = v[2] = v[3] = 0;
184 Quaternion(T s,T x,T y,T z){
190 Quaternion(
const Quaternion &q){
196 Quaternion(Point_3d<T> p){
202 Quaternion(SphericalPoint<T> sp){
207 Quaternion &operator=(
const Quaternion &q){
216 Quaternion operator*(
const Quaternion &q)
const{
218 v[0]*q.v[0] - v[1]*q.v[1] - v[2]*q.v[2] - v[3]*q.v[3],
219 v[0]*q.v[1] + v[1]*q.v[0] + v[2]*q.v[3] - v[3]*q.v[2],
220 v[0]*q.v[2] - v[1]*q.v[3] + v[2]*q.v[0] + v[3]*q.v[1],
221 v[0]*q.v[3] + v[1]*q.v[2] - v[2]*q.v[1] + v[3]*q.v[0]);
225 Quaternion conj()
const{
226 return Quaternion(v[0],-v[1],-v[2],-v[3]);
233 Quaternion inverse()
const{
234 return this->conj()/(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]);
239 return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]);
243 Quaternion RotateX(T theta){
244 Quaternion R = q_x_rotation(theta);
245 return R*(*this)*R.conj();
248 Quaternion RotateY(T theta){
249 Quaternion R = q_y_rotation(theta);
250 return R*(*this)*R.conj();
253 Quaternion RotateZ(T theta){
254 Quaternion R = q_z_rotation(theta);
255 return R*(*this)*R.conj();
261 Quaternion RotateYZ(T theta,T phi){
262 Quaternion R = q_z_rotation(theta)*q_z_rotation(phi);
263 return R*(*this)*R.conj();
268 Quaternion Rotate(
const Quaternion &R)
const{
269 return R*(*this)*R.conj();
274 void RotInplace(
const Quaternion &R){
275 *
this = R*(*this)*R.conj();
280 static Point_3d<T> Rotate(
const Point_3d<T> &p
281 ,
const Quaternion &R){
284 return q.to_point_3d();
289 static SphericalPoint<T> Rotate(
const SphericalPoint<T> &p
290 ,
const Quaternion &R){
293 return q.to_SpericalPoint();
296 Quaternion operator+(
const Quaternion &q)
const{
297 return Quaternion(v[0] + q.v[0] , v[1] + q.v[1] , v[2] + q.v[2] , v[3] + q.v[3] );
300 Quaternion operator-(
const Quaternion &q)
const{
301 return Quaternion(v[0] - q.v[0] , v[1] - q.v[1] , v[2] - q.v[2] , v[3] - q.v[3] );
305 Quaternion operator/(
double s)
const{
306 return Quaternion(v[0]/s,v[1]/s,v[2]/s,v[3]/s);
309 Quaternion operator*(
double s)
const{
310 return Quaternion(v[0]*s,v[1]*s,v[2]*s,v[3]*s);
314 Point_3d<T> cross(
const Quaternion &q)
const{
315 return (*
this*q).to_point_3d();
319 T scalor(
const Quaternion &q)
const{
320 return v[1]*q.v[1] + v[2]*q.v[2] + v[3]*q.v[3];
324 Point_3d<T> to_point_3d()
const{
325 return Point_3d<T>(v[1],v[2],v[3]);
329 SphericalPoint<T> to_SpericalPoint()
const{
330 SphericalPoint<T> sp;
331 sp.cartisianTOspherical(v+1);
339 T & operator[](
int i){
return v[i];}
342 static Quaternion q_x_rotation(T theta){
343 return Quaternion(cos(theta/2),sin(theta/2),0,0);
346 static Quaternion q_y_rotation(T theta){
347 return Quaternion(cos(theta/2),0,-sin(theta/2),0);
350 static Quaternion q_z_rotation(T theta){
351 return Quaternion(cos(theta/2),0,0,sin(theta/2));
357bool intersect(
const PosType a1[],
const PosType a2[]
358 ,
const PosType b1[],
const PosType b2[]);
360int intersect(
const std::vector<Point_2d> &curve);
361int intersections(
const std::vector<Point_2d> &curve,std::vector<Point_2d> &intersections,std::vector<std::pair<int,int> > &segments);
370int orientation(
const PosType p[],
const PosType q[],
const PosType r[]);
374bool onSegment(
const PosType p[],
const PosType q[],
const PosType r[]);
377double AngleBetween2d(
double v1[],
double v2[]);
388 x[0] = r*cos(theta)*cos(phi);
389 x[1] = r*cos(theta)*sin(phi);
397 ,r*cos(theta)*sin(phi),r*sin(theta) );
403 r = sqrt( x[0]*x[0] + x[1]*x[1] +x[2]*x[2]);
404 theta = asin(x[2]/r);
405 phi = atan2(x[1],x[0]);
409void SphericalPoint<T>::TOspherical(
Point_3d<T> &x){
410 r = sqrt( x[0]*x[0] + x[1]*x[1] +x[2]*x[2]);
411 theta = asin(x[2]/r);
412 phi = atan2(x[1],x[0]);
423 const SphericalPoint<T> ¢ral
426 double ct = cos(theta),st = sin(theta);
427 double cosphi = cos(phi - central.phi);
428 double so = sin(central.theta);
429 double co = cos(central.theta);
431 PosType k = 2/( 1 + so*st + co*ct*cosphi );
433 x[0] = k*(ct*sin(phi - central.phi));
434 x[1] = k*(co*st - so*ct*cosphi);
438 const SphericalPoint<T> ¢ral
441 double ct = cos(theta),st = sin(theta);
442 double cosphi = cos(phi - central.phi);
443 double so = sin(central.theta);
444 double co = cos(central.theta);
446 PosType k = 2/( 1 + so*st + co*ct*cosphi );
448 x[0] = k*(ct*sin(phi - central.phi));
449 x[1] = k*(co*st - so*ct*cosphi);
454 const SphericalPoint<T> ¢ral
456 double ct = cos(theta),st = sin(theta);
457 double cosphi = cos(phi - central.phi);
458 double so = sin(central.theta);
459 double co = cos(central.theta);
461 PosType k = 2/( 1 + so*st + co*ct*cosphi );
463 return Point_2d(k*(ct*sin(phi - central.phi)),k*(co*st - so*ct*cosphi));
475 const SphericalPoint<T> ¢ral
478 double ct = cos(theta),st = sin(theta);
479 double cosphi = cos(phi - central.phi);
480 double so = sin(central.theta);
481 double co = cos(central.theta);
483 x[0] = ct*sin(phi - central.phi);
484 x[1] = co*st - so*ct*cosphi;
486 if(st*so + ct*co*cosphi < 0 ){
487 double s = sqrt( x[0]*x[0] + x[1]*x[0] );
495 const SphericalPoint<T> ¢ral
497 double c = cos(theta);
498 return Point_2d( c*sin(phi - central.phi),
499 cos(central.theta)*sin(theta) - sin(central.theta)*c*cos(phi - central.phi) );
506 const SphericalPoint<T> ¢ral
509 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
510 PosType c = asin(rho);
512 theta = asin( cos(c)*sin(central.theta) + x[1]*cos(central.theta) );
513 phi = central.phi + atan2(x[0] , cos(central.theta)*cos(c)
514 - x[1]*sin(central.theta) );
519 const SphericalPoint<T> ¢ral
522 PosType rho = sqrt(x[0]*x[0] + x[1]*x[1]);
523 PosType c = asin(rho);
525 double at=cos(c)*sin(central.theta) + x[1]*cos(central.theta);
526 at = (at > 1) ? 1 : at;
527 at = (at < -1) ? -1 : at;
529 phi = central.phi + atan2(x[0] , cos(central.theta)*cos(c)
530 - x[1]*sin(central.theta) );
535 const SphericalPoint<T> ¢ral
537 return atan2( sin(central.theta) * sin(phi - central.phi)
538 , cos(phi - central.phi) );
543 const SphericalPoint<T> ¢ral
545 return atan2( cos(central.theta) * cos(theta) + sin(central.theta) * sin(central.theta)
546 *cos(phi - central.phi)
547 , -sin(phi - central.phi) * sin(phi - central.phi) );