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 #include "arc_round.h"
16
17 #ifndef PI_NUM
18 #define PI_NUM 3.14f
19 #endif
20
21 namespace OHOS::Ace {
22
ArcRound(const ArcRound & other)23 ArcRound::ArcRound(const ArcRound& other)
24 {
25 *this = other;
26 }
27
ArcRound(Point centerPoint,float radius,float startAngle,float sweepAngle,float width)28 ArcRound::ArcRound(Point centerPoint, float radius, float startAngle, float sweepAngle, float width)
29 {
30 centerPoint_ = centerPoint;
31 radius_ = radius;
32 startAngle_ = startAngle;
33 sweepAngle_ = sweepAngle;
34 width_ = width;
35 outerRadius_ = radius + width * HALF;
36 }
37
operator =(const ArcRound & arc)38 ArcRound& ArcRound::operator=(const ArcRound& arc)
39 {
40 centerPoint_ = arc.GetCenterPoint();
41 radius_ = arc.GetRadius();
42 startAngle_ = arc.GetStartAngle();
43 sweepAngle_ = arc.GetSweepAngle();
44 width_ = arc.GetWidth();
45 outerRadius_ = radius_ + width_ * HALF;
46 return *this;
47 }
48
Rotate(const Point & point,float angle)49 void ArcRound::Rotate(const Point& point, float angle)
50 {
51 centerPoint_.Rotate(point, angle);
52 startAngle_ += angle;
53 endAngle_ += angle;
54 }
55
Move(float xOffset,float yOffset)56 void ArcRound::Move(float xOffset, float yOffset)
57 {
58 centerPoint_.SetX(centerPoint_.GetX() + xOffset);
59 centerPoint_.SetY(centerPoint_.GetY() + yOffset);
60 }
61
GetPointByAngle(float angle,Point & out) const62 void ArcRound::GetPointByAngle(float angle, Point& out) const
63 {
64 out.SetX(centerPoint_.GetX() + radius_);
65 out.SetY(centerPoint_.GetY());
66 out.Rotate(centerPoint_, angle);
67 }
68
GetPositionAngle(const Offset & position) const69 float ArcRound::GetPositionAngle(const Offset& position) const
70 {
71 float angle = atan2(position.GetY() - centerPoint_.GetY(), position.GetX() - centerPoint_.GetX());
72 return angle;
73 }
74
GetStartPoint() const75 Point ArcRound::GetStartPoint() const
76 {
77 Point startPoint;
78 GetStartPoint(startPoint);
79 return startPoint;
80 }
81
GetEndPoint() const82 Point ArcRound::GetEndPoint() const
83 {
84 Point endPoint;
85 GetEndPoint(endPoint);
86 return endPoint;
87 }
88
SetOuterRadius(float outerRadius)89 void ArcRound::SetOuterRadius(float outerRadius)
90 {
91 if (outerRadius < 0.0) {
92 LOGE("Invalid outerRadius:%{public}lf", outerRadius);
93 return;
94 }
95 outerRadius_ = outerRadius;
96 }
97
SetWidth(float width)98 void ArcRound::SetWidth(float width)
99 {
100 if (width < 0.0) {
101 LOGE("Invalid width:%{public}lf", width);
102 return;
103 }
104 width_ = width;
105 }
106
Get2PIRadians(double radian) const107 double ArcRound::Get2PIRadians(double radian) const
108 {
109 if (radian < 0) {
110 return SQUARE * PI_NUM + radian; // 2 * PI: 360度
111 }
112 return radian;
113 }
114
IsInRegion(const Point & point,float minHotRegion) const115 bool ArcRound::IsInRegion(const Point& point, float minHotRegion) const
116 {
117 float distance = pow(pow(point.GetX() - centerPoint_.GetX(), SQUARE) +
118 pow(point.GetY() - centerPoint_.GetY(), SQUARE), HALF);
119 float angle = GetPositionAngle(Offset(point.GetX(), point.GetY()));
120 float width = std::max(minHotRegion, width_);
121 if (distance > outerRadius_ || distance < outerRadius_ - width) {
122 return false;
123 }
124 auto startAngle = startAngle_;
125 auto endAngle = startAngle_ + sweepAngle_;
126 auto startRadian = startAngle * PI_NUM / HALF_CIRCULARITY;
127 auto endRadian = endAngle * PI_NUM / HALF_CIRCULARITY;
128 if (positionMode_ == PositionMode::LEFT) {
129 endAngle = startAngle_ + sweepAngle_ <= -HALF_CIRCULARITY ? startAngle_ + sweepAngle_ + WHOLE_CIRCULARITY :
130 startAngle_ + sweepAngle_;
131 startRadian = Get2PIRadians(startRadian);
132 endRadian = Get2PIRadians(endAngle * PI_NUM / HALF_CIRCULARITY);
133 angle = Get2PIRadians(angle);
134 if (angle < endRadian || angle > startRadian) {
135 return false;
136 }
137 } else {
138 if (angle < startRadian || angle > endRadian) {
139 return false;
140 }
141 }
142 return true;
143 }
144 } // namespace OHOS::Ace