iOS新增绘制圆的方法实例代码

2025-05-29 0 54

ios 的坐标系和我们几何课本中的二维坐标系并不一样!

# bezierpath绘制

使用 uibezierpath 进行绘制弧的方法,通常会直接使用 addarc :

?

1
addarc(withcenter:, radius:, startangle:, endangle:, clockwise:)

或者使用 addcurve 进行拟弧:

?

1
addcurve(to:, controlpoint1:, controlpoint2:)

其实我们可以通过,两个坐标点(startpoint & endpoint),和两点间的线段对应的弧的弧度(angle/radian)就能确定这个的信息(半径radius, center), 所以我们是不是可以封装出只提供 start, end 和 angle 就能绘制 arc 的函数?

?

1
addarc(startpoint: , endpoint: , angle: , clockwise:)

# 计算两点间的距离

这里逻辑很简单不做赘述。

?

1

2

3

4

5
func calculatelinelength(_ point1: cgpoint, _ point2: cgpoint) -> cgfloat {

let w = point1.x - point2.x

let h = point1.y - point2.y

return sqrt(w * w + h * h)

}

# 计算两点间的夹角

计算 point 和 origin 连线在 ios 坐标系的角度

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21
func calculateangle(point: cgpoint, origin: cgpoint) -> double {

if point.y == origin.y {

return point.x > origin.x ? 0.0 : -double.pi

}

if point.x == origin.x {

return point.y > origin.y ? double.pi * 0.5 : double.pi * -0.5

}

// note: 修正标准坐标系角度到 ios 坐标系

let rotationadjustment = double.pi * 0.5

let offsetx = point.x - origin.x

let offsety = point.y - origin.y

// note: 使用 -offsety 是因为 ios 坐标系与标准坐标系的区别

if offsety > 0 {

return double(atan(offsetx / -offsety)) + rotationadjustment

} else {

return double(atan(offsetx / -offsety)) - rotationadjustment

}

}

# 计算心的坐标

如果你已经将几何知识丢的差不多了的话,我在这里画了个大概的草图,如下( angle 比较小时):

iOS新增绘制圆的方法实例代码

angle 比较大时:

iOS新增绘制圆的方法实例代码

所以我么可以写出如下计算中心点的代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73
// woring: 只计算从start到end **顺时针** 计算对应的 **小于π** 圆弧对应的圆心

// note: 计算逆时针(end到start)可以看做将传入的start和end对调后计算顺时针时的圆心位置

// note: 计算大于π的叫相当于将end和start对换后计算2π-angle的顺时针圆心位置

// note: 综上传入start,end,angle 右外部自行处理逻辑

func calculatecenterfor(startpoint start: cgpoint, endpoint end: cgpoint, radian: double) -> cgpoint {

guard radian <= double.pi else {

fatalerror("does not support radian calculations greater than π!")

}

guard start != end else {

fatalerror("start position and end position cannot be equal!")

}

if radian == double.pi {

let centerx = (end.x - start.x) * 0.5 + start.x

let centery = (end.y - start.y) * 0.5 + start.y

return cgpoint(x: centerx, y: centery)

}

let lineab = calculatelinelength(start, end)

// 平行 y 轴

if start.x == end.x {

let centery = (end.y - start.y) * 0.5 + start.y

let tanresult = cgfloat(tan(radian * 0.5))

let offsetx = lineab * 0.5 / tanresult

let centerx = start.x + offsetx * (start.y > end.y ? 1.0 : -1.0)

return cgpoint(x: centerx, y: centery)

}

// 平行 x 轴

if start.y == end.y {

let centerx = (end.x - start.x) * 0.5 + start.x

let tanresult = cgfloat(tan(radian * 0.5))

let offsety = lineab * 0.5 / tanresult

let centery = start.y + offsety * (start.x < end.x ? 1.0 : -1.0)

return cgpoint(x: centerx, y: centery)

}

// 普通情况

// 计算半径

let radius = lineab * 0.5 / cgfloat(sin(radian * 0.5))

// 计算与 y 轴的夹角

let angletoyaxis = atan(abs(start.x - end.x) / abs(start.y - end.y))

let cacluteangle = cgfloat(double.pi - radian) * 0.5 - angletoyaxis

// 偏移量

let offsetx = radius * sin(cacluteangle)

let offsety = radius * cos(cacluteangle)

var centetx = end.x

var centery = end.y

// 以 start 为原点判断象限区间(ios坐标系)

if end.x > start.x && end.y < start.y {

// 第一象限

centetx = end.x + offsetx

centery = end.y + offsety

} else if end.x > start.x && end.y > start.y {

// 第二象限

centetx = start.x - offsetx

centery = start.y + offsety

} else if end.x < start.x && end.y > start.y {

// 第三象限

centetx = end.x - offsetx

centery = end.y - offsety

} else if end.x < start.x && end.y < start.y {

// 第四象限

centetx = start.x + offsetx

centery = start.y - offsety

}

return cgpoint(x: centetx, y: centery)

}

这里附上一个逆时针绘制第一张图中心位置的草图,图中已将 start 和 end 对换

iOS新增绘制圆的方法实例代码

如果你对其中计算时到底该使用 + 还是 – 有困惑的话也可以自己多画些草图大概验证下,总之有疑惑多动手

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 iOS新增绘制圆的方法实例代码 https://www.kuaiidc.com/89169.html

相关文章

发表评论
暂无评论