1 /*
2 * Copyright (c) 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 "gfx_utils/diagram/vertexprimitive/geometry_arc.h"
17 namespace OHOS {
18 #if defined(GRAPHIC_ENABLE_ARC_FLAG) && GRAPHIC_ENABLE_ARC_FLAG
19 const int32_t CURVERENUMSTEP = 4;
GeometryArc(float centerX,float centerY,float rx,float ry,float start,float end,bool isClockwise)20 GeometryArc::GeometryArc(float centerX, float centerY,
21 float rx, float ry,
22 float start, float end,
23 bool isClockwise)
24 : centerX_(centerX), centerY_(centerY), radiusX_(rx), radiusY_(ry), expansionRatio_(1.0)
25 {
26 Normalize(start, end, isClockwise);
27 }
28
SetApproximationScale(float sale)29 void GeometryArc::SetApproximationScale(float sale)
30 {
31 expansionRatio_ = sale;
32 if (initialized_) {
33 Normalize(beginAngle_, endAngle_, isClockwise_);
34 }
35 }
36
GenerateVertex(float * x,float * y)37 uint32_t GeometryArc::GenerateVertex(float* x, float* y)
38 {
39 // The current command is an end point with no vertices
40 if (IsStop(pathCommand_)) {
41 return PATH_CMD_STOP;
42 }
43 if ((currentAngle_ < endAngle_ - deltaAngle_ / CURVERENUMSTEP) != isClockwise_) {
44 *x = centerX_ + Cos(endAngle_ * RADIAN_TO_ANGLE) * radiusX_;
45 *y = centerY_ + Sin(endAngle_ * RADIAN_TO_ANGLE) * radiusY_;
46 pathCommand_ = PATH_CMD_STOP;
47 return PATH_CMD_LINE_TO;
48 }
49
50 *x = centerX_ + Cos(currentAngle_ * RADIAN_TO_ANGLE) * radiusX_;
51 *y = centerY_ + Sin(currentAngle_ * RADIAN_TO_ANGLE) * radiusY_;
52
53 currentAngle_ += deltaAngle_;
54
55 uint32_t pf = pathCommand_;
56 pathCommand_ = PATH_CMD_LINE_TO;
57 return pf;
58 }
59
Rewind(uint32_t)60 void GeometryArc::Rewind(uint32_t)
61 {
62 pathCommand_ = PATH_CMD_MOVE_TO;
63 currentAngle_ = beginAngle_;
64 }
65
Normalize(float startAngle,float endAngle,bool isClockwise)66 void GeometryArc::Normalize(float startAngle, float endAngle, bool isClockwise)
67 {
68 float ra = (MATH_ABS(radiusX_) + MATH_ABS(radiusY_)) / FLOATNUM;
69 // Calculate the radian change rate
70 deltaAngle_ = Acos(ra / (ra + RADDALETAELPS / expansionRatio_)) * FLOATNUM;
71 if (isClockwise) {
72 while (endAngle < startAngle) {
73 endAngle += PI * FLOATNUM;
74 }
75 } else {
76 while (startAngle < endAngle) {
77 startAngle += PI * FLOATNUM;
78 }
79 deltaAngle_ = -deltaAngle_;
80 }
81 isClockwise_ = isClockwise;
82 beginAngle_ = startAngle;
83 endAngle_ = endAngle;
84 initialized_ = true;
85 }
86
Init(float centerX,float centerY,float rx,float ry,float startAngle,float endAngle,bool isClockwise)87 void GeometryArc::Init(float centerX, float centerY, float rx, float ry,
88 float startAngle, float endAngle, bool isClockwise)
89 {
90 centerX_ = centerX;
91 centerY_ = centerY;
92 radiusX_ = rx;
93 radiusY_ = ry;
94 Normalize(startAngle, endAngle, isClockwise);
95 }
96 #endif
97 } // namespace OHOS
98