• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "camera_log.h"
17 #include "cubic_bezier.h"
18 
19 namespace OHOS {
20 namespace CameraStandard {
21 namespace {
22 constexpr float CUBIC_BEZIER_MULTIPLE = 3.0;
23 constexpr float MAX_RESOLUTION = 4000.0;
24 constexpr float SERCH_STEP = 1.0 / MAX_RESOLUTION;
25 
26 constexpr float CONTROL_POINT_X1 = 0.4;
27 constexpr float CONTROL_POINT_X2 = 0.2;
28 constexpr float CONTROL_POINT_Y1 = 0.0;
29 constexpr float CONTROL_POINT_Y2 = 1.0;
30 
31 constexpr float DURATION_SLOP = 55.0;
32 constexpr float DURATION_BASE = 450.0;
33 constexpr float DURATION_POWER = 1.2;
34 constexpr int MAX_ZOOM_ARRAY_SIZE = 100;
35 }
36 
37 float CubicBezier::mControPointX1 = CONTROL_POINT_X1;
38 float CubicBezier::mControPointX2 = CONTROL_POINT_X2;
39 float CubicBezier::mControPointY1 = CONTROL_POINT_Y1;
40 float CubicBezier::mControPointY2 = CONTROL_POINT_Y2;
41 float CubicBezier::mDurationBase = DURATION_BASE;
42 
GetZoomArray(const float & currentZoom,const float & targetZoom,const float & frameInterval)43 std::vector<float> CubicBezier::GetZoomArray(const float& currentZoom, const float& targetZoom,
44     const float& frameInterval)
45 {
46     float duration = GetDuration(currentZoom, targetZoom);
47     MEDIA_INFO_LOG("CubicBezier::GetZoomArray duration is:%{public}f", duration);
48     std::vector<float> result;
49     CHECK_RETURN_RET(duration == 0 || frameInterval == 0, result);
50     int arraySize = static_cast<int>(duration / frameInterval);
51     CHECK_RETURN_RET_ELOG(arraySize > MAX_ZOOM_ARRAY_SIZE, result,
52         "Error size, duration is:%{public}f, interval is:%{public}f", duration, frameInterval);
53     for (int i = 1; i <= arraySize; i++) {
54         float time = frameInterval * i / duration;
55         float zoom = (currentZoom + (targetZoom - currentZoom) * GetInterpolation(time));
56         result.push_back(zoom);
57         MEDIA_DEBUG_LOG("CubicBezier::GetZoomArray zoom is:%{public}f", zoom);
58     }
59     result.push_back(targetZoom);
60     return result;
61 }
62 
GetDuration(const float & currentZoom,const float & targetZoom)63 float CubicBezier::GetDuration(const float& currentZoom, const float& targetZoom)
64 {
65     if (currentZoom == 0) {
66         return 0;
67     } else {
68         return (DURATION_SLOP * DURATION_POWER * abs(log(targetZoom / currentZoom)) + mDurationBase);
69     }
70 }
71 
SetBezierValue(const std::vector<float> & zoomBezierValue)72 bool CubicBezier::SetBezierValue(const std::vector<float>& zoomBezierValue)
73 {
74     const size_t DURATION_BASE_INDEX = 0;
75     const size_t CONTROL_POINT_X1_INDEX = 1;
76     const size_t CONTROL_POINT_Y1_INDEX = 2;
77     const size_t CONTROL_POINT_X2_INDEX = 3;
78     const size_t CONTROL_POINT_Y2_INDEX = 4;
79 
80     mDurationBase = zoomBezierValue[DURATION_BASE_INDEX];
81     mControPointX1 = zoomBezierValue[CONTROL_POINT_X1_INDEX];
82     mControPointY1 = zoomBezierValue[CONTROL_POINT_Y1_INDEX];
83     mControPointX2 = zoomBezierValue[CONTROL_POINT_X2_INDEX];
84     mControPointY2 = zoomBezierValue[CONTROL_POINT_Y2_INDEX];
85     return true;
86 }
87 
GetCubicBezierY(const float & time)88 float CubicBezier::GetCubicBezierY(const float& time)
89 {
90     return CUBIC_BEZIER_MULTIPLE * (1- time) * (1 - time) * time * mControPointY1 +
91         CUBIC_BEZIER_MULTIPLE * (1- time) * time * time * mControPointY2 + time * time * time;
92 }
93 
GetCubicBezierX(const float & time)94 float CubicBezier::GetCubicBezierX(const float& time)
95 {
96     return CUBIC_BEZIER_MULTIPLE * (1- time) * (1 - time) * time * mControPointX1 +
97         CUBIC_BEZIER_MULTIPLE * (1- time) * time * time * mControPointX2 + time * time * time;
98 }
99 
BinarySearch(const float & value)100 float CubicBezier::BinarySearch(const float& value)
101 {
102     int low = 0;
103     int high = MAX_RESOLUTION;
104     int num = 0;
105     while (low <= high) {
106         num = num + 1;
107         int middle = (low + high) / 2;
108         float approximation = GetCubicBezierX(SERCH_STEP * middle);
109         if (approximation < value) {
110             low = middle + 1;
111         } else if (approximation > value) {
112             high = middle -1;
113         } else {
114             return middle;
115         }
116     }
117     return low;
118 }
119 
GetInterpolation(const float & input)120 float CubicBezier::GetInterpolation(const float& input)
121 {
122     return GetCubicBezierY(SERCH_STEP * BinarySearch(input));
123 }
124 } // namespace CameraStandard
125 } // namespace OHOS