- Aldebaran documentation |
- C++ Libraries |
- index

libalmath 2.8.7.4

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bezierautotangent.h
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2017 Softbank Robotics. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the COPYING file.
5 */
6
7 #ifndef LIBALMATH_ALMATH_SCENEGRAPH_QIANIM_BEZIERAUTOTANGENT_H
8 #define LIBALMATH_ALMATH_SCENEGRAPH_QIANIM_BEZIERAUTOTANGENT_H
9
10 #include <almath/api.h>
11 #include <utility>
12 #include <cassert>
13 #include <cmath>
14 #include <type_traits>
15
16 namespace AL {
17 namespace qianim {
18
19 // Compute the two tangents of a legacy (xar/qianim v1) bezier auto key.
20 //
21 // pDeltaTime1 is the time between this key and previous key,
22 // pDeltaTime2 is the time between next key and this key.
23 // pDeltaAngle1 is the angle change between this key and previous key,
24 // pDeltaAngle2 is the angle change between next key and this key.
25 //
26 // pDeltaTime1 and pDeltaTime2 shall be non-negative
27 // If the key is not a local extremum (ie. if pDeltaAngle1 * pDeltaAngle2 > 0)
28 // then pDeltaTime1 + pDeltaTime2 shall be positive
29 //
30 // Return the (left tangent, right tangent) pair, where each tangent is
31 // an (abscissa, ordinate) pair.
32 template <typename Scalar,
33 typename std::enable_if<std::is_floating_point<Scalar>::value, int>::type = 0 >
34 std::pair<std::pair<Scalar, Scalar>, std::pair<Scalar, Scalar>>
35 computeBezierAutoTangents(Scalar pDeltaTime1, Scalar pDeltaTime2,
36 Scalar pDeltaAngle1, Scalar pDeltaAngle2) {
37 assert(pDeltaTime1 > -1e-5f);
38 assert(pDeltaTime2 > -1e-5f);
39
40 const auto alpha = Scalar(1) / 3;
41 auto beta = Scalar(0);
42
43 if (pDeltaAngle1 * pDeltaAngle2 > 0) {
44 // Key is not a local extremum
45 assert(pDeltaTime1 + pDeltaTime2 > 0);
46 beta = (pDeltaAngle1 + pDeltaAngle2) / (pDeltaTime1 + pDeltaTime2);
47
48 // avoid overshooting
49 auto tgtHeight = std::abs(alpha * pDeltaTime2 * beta);
50 auto absDeltaAngle = std::abs(pDeltaAngle2);
51 if (tgtHeight > absDeltaAngle) {
52 beta *= absDeltaAngle / tgtHeight;
53 }
54 tgtHeight = std::abs(alpha * pDeltaTime1 * beta);
55 absDeltaAngle = std::abs(pDeltaAngle1);
56 if (tgtHeight > absDeltaAngle) {
57 beta *= absDeltaAngle / tgtHeight;
58 }
59 }
60 return std::make_pair(std::make_pair(-alpha * pDeltaTime1,
61 -alpha * beta * pDeltaTime1),
62 std::make_pair(alpha * pDeltaTime2,
63 alpha * beta * pDeltaTime2));
64 }
65 }
66 }
67
68 #endif
AL::qianim::computeBezierAutoTangents
std::pair< std::pair< Scalar, Scalar >, std::pair< Scalar, Scalar > > computeBezierAutoTangents(Scalar pDeltaTime1, Scalar pDeltaTime2, Scalar pDeltaAngle1, Scalar pDeltaAngle2)
Definition: bezierautotangent.h:35