32 #ifndef SPL_Arcball_hpp
33 #define SPL_Arcball_hpp
39 #include <SPL/config.hpp>
40 #include <CGAL/Plane_3.h>
41 #include <CGAL/Ray_3.h>
65 rayOrigin,
const typename CGAL::Vector_3<T>& rayDir,
66 const typename CGAL::Point_3<T>& point)
68 typename T::FT t = (rayDir * (point - rayOrigin)) / (rayDir * rayDir);
72 return typename T::Point_3(rayOrigin + t * rayDir);
91 const typename CGAL::Point_3<T>& sphereCenter,
typename T::FT sphereRadius,
92 const typename CGAL::Point_3<T>& rayOrigin,
93 const typename CGAL::Vector_3<T>& rayDir)
95 typename T::FT a = rayDir * rayDir;
96 typename T::Vector_3 delta = rayOrigin - sphereCenter;
97 typename T::FT b = 2.0 * delta * rayDir;
98 typename T::FT c = delta * delta - sphereRadius * sphereRadius;
99 typename T::FT discrim = b * b - 4.0 * a * c;
101 return std::pair<bool, typename T::Point_3>(
false,
104 typename T::FT d = sqrt(discrim);
105 typename T::FT t0 = (-b - d) / (2.0 * a);
106 typename T::FT t1 = (-b + d) / (2.0 * a);
107 typename T::FT t = t0;
108 if (t1 >= 0 && t1 < t0) {
112 return std::pair<bool, typename T::Point_3>(
false,
115 return std::pair<bool, typename T::Point_3>(
true, rayOrigin + t * rayDir);
133 const typename CGAL::Point_3<T>& planePoint,
134 const typename CGAL::Vector_3<T>& planeNormal,
135 const typename CGAL::Point_3<T>& rayOrigin,
136 const typename CGAL::Vector_3<T>& rayDir)
138 typename T::Point_3 intersectPoint;
139 typename T::Ray_3 intersectRay;
140 CGAL::Object result = CGAL::intersection(
typename T::Plane_3(planePoint,
141 planeNormal),
typename T::Ray_3(rayOrigin, rayDir));
142 if (CGAL::assign(intersectPoint, result)) {
143 return std::pair<bool, typename T::Point_3>(
true, intersectPoint);
144 }
else if (CGAL::assign(intersectRay, result)) {
145 return std::pair<bool, typename T::Point_3>(
true,
146 intersectRay.source());
148 return std::pair<bool, typename T::Point_3>(
false, rayOrigin);
168 typedef typename Kernel::Point_3
Point;
171 typedef typename Kernel::Vector_3
Vector;
184 void initialize(
double arcBallRadius,
const Point& eyePos,
185 const Vector& eyeDir,
const Vector& eyeUp,
const Point& sceneCenter);
195 void start(
const Point& pos);
200 void move(
const Point& pos);
229 double arcBallRadius_;
256 eyeUp_(0, 0, 0), startPosValid_(false), startPos_(0, 0, 0),
257 curPos_(0, 0, 0), sceneCenter_(0, 0, 0), debugLevel_(0)
263 const typename T::Point_3& eyePos,
264 const typename T::Vector_3& eyeDir,
265 const typename T::Vector_3& eyeUp,
266 const typename T::Point_3& sceneCenter)
269 arcBallRadius_ = arcBallRadius;
271 sceneCenter_ = sceneCenter;
287 startPosValid_ =
true;
288 if (debugLevel_ > 0) {
290 <<
"start: startPos=" << startPos_ <<
" curPos=" << curPos_ <<
"\n";
298 if (debugLevel_ > 0) {
300 <<
"move: startPos=" << startPos_ <<
" curPos=" << curPos_ <<
"\n";
307 startPosValid_ =
false;
308 startPos_ =
typename T::Point_3(0, 0, 0);
310 if (debugLevel_ > 0) {
312 <<
"clear: startPos=" << startPos_ <<
" curPos=" << curPos_ <<
"\n";
320 assert(startPosValid_);
322 if (debugLevel_ > 0) {
323 std::cerr <<
"startPos=" << startPos_ <<
" curPos=" << curPos_ <<
"\n";
327 std::pair<bool, typename T::Point_3> oldResult;
328 std::pair<bool, typename T::Point_3> curResult;
330 oldResult = findRaySphereIntersection<T>(sceneCenter_,
331 arcBallRadius_, eyePos_, startPos_ - eyePos_);
332 curResult = findRaySphereIntersection<T>(sceneCenter_,
333 arcBallRadius_, eyePos_, curPos_ - eyePos_);
334 if (!oldResult.first && !curResult.first) {
335 oldResult = findRayPlaneIntersection<T>(sceneCenter_,
336 eyePos_ - sceneCenter_, eyePos_, startPos_ - eyePos_);
337 curResult = findRayPlaneIntersection<T>(sceneCenter_,
338 eyePos_ - sceneCenter_, eyePos_, curPos_ - eyePos_);
339 oldResult.first =
true;
340 curResult.first =
true;
343 typename T::Vector_3 planeNormal(eyePos_ - sceneCenter_);
344 oldResult = findRayPlaneIntersection<T>(sceneCenter_, planeNormal,
345 eyePos_, startPos_ - eyePos_);
346 curResult = findRayPlaneIntersection<T>(sceneCenter_, planeNormal,
347 eyePos_, curPos_ - eyePos_);
351 Rotation result(
typename T::Vector_3(0, 0, 1), 0);
352 if (oldResult.first && curResult.first) {
353 typename T::Vector_3 curVec =
normalize(curResult.second -
355 typename T::Vector_3 oldVec =
normalize(oldResult.second -
357 if (
norm(curVec - oldVec) > 1e-20) {
364 if (debugLevel_ > 0) {
365 std::cerr <<
"result=" << result.
axis <<
" " << result.
angle <<
"\n";
T::Vector_3 normalize(const typename CGAL::Vector_3< T > &v)
Compute a unit vector.
Definition: cgalUtil.hpp:79
A quaternion represented in terms of its scalar and vector parts.
Definition: cgalUtil.hpp:133
static Rotation combineRotations(const Rotation &, const Rotation &)
Combine two rotations.
Definition: Arcball.hpp:371
void clear()
Clear the starting and current positions for the arcball.
Definition: Arcball.hpp:305
void setDebugLevel(int debugLevel) const
For debugging...
Kernel::Vector_3 Vector
The vector type.
Definition: Arcball.hpp:171
Definition: Arcball.hpp:48
void initialize(double arcBallRadius, const Point &eyePos, const Vector &eyeDir, const Vector &eyeUp, const Point &sceneCenter)
Initialize the state of an arcball.
Definition: Arcball.hpp:262
Rotation_3< T > quaternionToRotation(const Quaternion< T > &q)
Convert a unit-norm quaternion into its corresponding rotation.
Definition: cgalUtil.hpp:198
Kernel::Point_3 Point
The point type.
Definition: Arcball.hpp:168
T::FT norm(const typename CGAL::Vector_3< T > &v)
Compute the norm of a vector.
Definition: cgalUtil.hpp:66
Arcball.
Definition: Arcball.hpp:160
Real angle
The angle of rotation.
Definition: cgalUtil.hpp:124
A 3-D rotation.
Definition: cgalUtil.hpp:106
Quaternion< T > rotationToQuaternion(const Rotation_3< T > &rot)
Convert a rotation into its corresponding quaternion.
Definition: cgalUtil.hpp:187
void start(const Point &pos)
Set the starting position for arcball movement.
Definition: Arcball.hpp:283
std::pair< bool, typename T::Point_3 > findRayPlaneIntersection(const typename CGAL::Point_3< T > &planePoint, const typename CGAL::Vector_3< T > &planeNormal, const typename CGAL::Point_3< T > &rayOrigin, const typename CGAL::Vector_3< T > &rayDir)
Compute the intersection of a ray and a plane.
Definition: Arcball.hpp:132
T Kernel
The CGAL kernel.
Definition: Arcball.hpp:165
void move(const Point &pos)
Set the current position for arcball movement.
Definition: Arcball.hpp:295
Rotation_3< Kernel > Rotation
The representation of a rotation.
Definition: Arcball.hpp:174
std::pair< bool, typename T::Point_3 > findRaySphereIntersection(const typename CGAL::Point_3< T > &sphereCenter, typename T::FT sphereRadius, const typename CGAL::Point_3< T > &rayOrigin, const typename CGAL::Vector_3< T > &rayDir)
Compute the intersection of a ray and a sphere.
Definition: Arcball.hpp:90
Arcball()
Create an arcball.
Definition: Arcball.hpp:255
Rotation getRotation() const
Get the rotation required to turn the arcball from the starting position to the current position...
Definition: Arcball.hpp:317
void setMode(int mode)
Set the arcball rotation mode.
Definition: Arcball.hpp:277
Vector_3 axis
The axis of rotation.
Definition: cgalUtil.hpp:121
T::Point_3 closestPointOnRay(const typename CGAL::Point_3< T > &rayOrigin, const typename CGAL::Vector_3< T > &rayDir, const typename CGAL::Point_3< T > &point)
Compute the closest point on a ray to the specified point.
Definition: Arcball.hpp:64
This file contains various CGAL utility code.