• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "animation/rs_cubic_bezier_interpolator.h"
17 
18 namespace OHOS {
19 namespace Rosen {
20 namespace {
GetCubicBezierValue(const float time,const float ctl1,const float ctl2)21 inline float GetCubicBezierValue(const float time, const float ctl1, const float ctl2)
22 {
23     if (time < 0.0f) {
24         return 0.0f;
25     }
26     if (time > 1.0f) {
27         return 1.0f;
28     }
29     constexpr static int three = 3.0;
30     const float oneMinusTime = 1.0f - time;
31     return three * oneMinusTime * oneMinusTime * time * ctl1 + three * oneMinusTime * time * time * ctl2 +
32            time * time * time;
33 }
34 } // namespace
35 
RSCubicBezierInterpolator(float ctlX1,float ctlY1,float ctlX2,float ctlY2)36 RSCubicBezierInterpolator::RSCubicBezierInterpolator(float ctlX1, float ctlY1, float ctlX2, float ctlY2)
37     : controlX1_(ctlX1), controlY1_(ctlY1), controlX2_(ctlX2), controlY2_(ctlY2)
38 {}
39 
RSCubicBezierInterpolator(uint64_t id,float ctlX1,float ctlY1,float ctlX2,float ctlY2)40 RSCubicBezierInterpolator::RSCubicBezierInterpolator(uint64_t id, float ctlX1, float ctlY1, float ctlX2, float ctlY2)
41     : RSInterpolator(id), controlX1_(ctlX1), controlY1_(ctlY1), controlX2_(ctlX2), controlY2_(ctlY2)
42 {}
43 
InterpolateImpl(float input) const44 float RSCubicBezierInterpolator::InterpolateImpl(float input) const
45 {
46     constexpr float ONE = 1.0f;
47     if (ROSEN_EQ(input, ONE, 1e-6f)) {
48         return ONE;
49     }
50     return GetCubicBezierValue(SEARCH_STEP * BinarySearch(input), controlY1_, controlY2_);
51 }
52 
BinarySearch(float key) const53 int RSCubicBezierInterpolator::BinarySearch(float key) const
54 {
55     int low = 0;
56     int high = MAX_RESOLUTION;
57     int middle = 0;
58     float approximation = 0.0;
59     constexpr float epsilon = 1e-6f;
60     while (low <= high) {
61         middle = (static_cast<unsigned int>(low + high)) >> 1;
62         approximation = GetCubicBezierValue(SEARCH_STEP * middle, controlX1_, controlX2_);
63         if (ROSEN_EQ(approximation, key, epsilon)) {
64             // Early exit if the key is found within an acceptable error range
65             return middle;
66         } else if (approximation < key) {
67             low = middle + 1;
68         } else {
69             high = middle - 1;
70         }
71     }
72     return low;
73 }
74 } // namespace Rosen
75 } // namespace OHOS
76