2020-04-27

A self creat...


这是我瞎发明的SCNCylinder链接ARkit或者Scenekit中两个节点的小算法,因为SCNCylinder不能设置起始位置和结束位置,只能通过三角函数自己旋转,下面代码需要的直接CV就好了

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
public func linkTwoNodes(_ node1: SCNNode, _ node2: SCNNode, _ lineNode: SCNNode, _ line: SCNCylinder) {
let p1 = node1.position
let p2 = node2.position
let dx = p1.x - p2.x
let dy = p1.y - p2.y
let dz = p1.z - p2.z

line.height = get3dDis(node1.position, node2.position)

lineNode.position = SCNVector3((p1.x+p2.x)/2, (p1.y+p2.y)/2, (p1.z+p2.z)/2)

var rotateX: Float = 0
var rotateZ: Float = 0

let crossLen:Float = Float(abs(sqrt(pow(dx, 2) + pow(dy, 2))))

if dy > 0 && dx > 0 {
rotateZ = -atanRotation(len1: dx, len2: dy)
}
if dy > 0 && dx < 0 {
rotateZ = atanRotation(len1: -dx, len2: dy)
}
if dy < 0 && dx < 0 {
rotateZ = -atanRotation(len1: -dx, len2: -dy)
}
if dy < 0 && dx > 0 {
rotateZ = atanRotation(len1: dx, len2: -dy)
}
if dy == 0 {
rotateZ = Float.pi / 2
}

if dy > 0 && dz < 0 {
rotateX = -atanRotation(len1: -dz, len2: crossLen)
}
if dy > 0 && dz > 0 {
rotateX = atanRotation(len1: dz, len2: crossLen)
}
if dy < 0 && dz > 0 {
rotateX = -atanRotation(len1: dz, len2: crossLen)
}
if dy < 0 && dz < 0 {
rotateX = atanRotation(len1: -dz, len2: crossLen)
}
if dy == 0 {
//mod
if dz != 0 {
rotateX = Float.pi / 2
}
}
lineNode.eulerAngles.x = Float(rotateX)
lineNode.eulerAngles.z = Float(rotateZ)
}


public func linkTwoNodes(_ node1: SCNNode, _ node2: SCNNode, _ lineNode: SCNNode) {
let p1 = node1.position
let p2 = node2.position
let dx = p1.x - p2.x
let dy = p1.y - p2.y
let dz = p1.z - p2.z

lineNode.position = SCNVector3((p1.x+p2.x)/2, (p1.y+p2.y)/2, (p1.z+p2.z)/2)

var rotateX: Float = 0
var rotateZ: Float = 0

let crossLen:Float = Float(abs(sqrt(pow(dx, 2) + pow(dy, 2))))

if dy > 0 && dx > 0 {
rotateZ = -atanRotation(len1: dx, len2: dy)
}
if dy > 0 && dx < 0 {
rotateZ = atanRotation(len1: -dx, len2: dy)
}
if dy < 0 && dx < 0 {
rotateZ = -atanRotation(len1: -dx, len2: -dy)
}
if dy < 0 && dx > 0 {
rotateZ = atanRotation(len1: dx, len2: -dy)
}
if dy == 0 {
rotateZ = Float.pi / 2
}

if dy > 0 && dz < 0 {
rotateX = -atanRotation(len1: -dz, len2: crossLen)
}
if dy > 0 && dz > 0 {
rotateX = atanRotation(len1: dz, len2: crossLen)
}
if dy < 0 && dz > 0 {
rotateX = -atanRotation(len1: dz, len2: crossLen)
}
if dy < 0 && dz < 0 {
rotateX = atanRotation(len1: -dz, len2: crossLen)
}
if dy == 0 {
//mod
if dz != 0 {
rotateX = Float.pi / 2
}
}
lineNode.eulerAngles.x = Float(rotateX)
lineNode.eulerAngles.z = Float(rotateZ)
}
public func get3dDis(_ p1: SCNVector3, _ p2: SCNVector3) -> CGFloat {
let dx = p1.x - p2.x
let dy = p1.y - p2.y
let dz = p1.z - p2.z
return CGFloat(abs(sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2))))
}


public func atanRotation(len1: Float, len2: Float) -> Float {
if len2 == 0 {
return Float.pi / 2
}else {
if len1 == 0{
return 0
}else {
return atan(len1 / len2)
}
}
}