gpt4 book ai didi

ios - 如何用 6 个三角形 SCNNode 制作六边形?

转载 作者:行者123 更新时间:2023-12-01 15:40:05 26 4
gpt4 key购买 nike

我正在尝试在不更改任何枢轴点的情况下制作带有三角形的六边形网格,但我似乎无法正确定位三角形以制作单个六边形。我正在使用 UIBezierPaths 创建 SCNNodes 以形成三角形,然后旋转贝塞尔路径。这似乎工作正常,直到我尝试使用参数方程将三角形定位在一个圆圈周围以形成六边形,然后它们最终没有处于正确的位置。你能帮我找出我在哪里做错了吗?

class TrianglePlane: SCNNode {

var size: CGFloat = 0.1
var coords: SCNVector3 = SCNVector3Zero
var innerCoords: Int = 0

init(coords: SCNVector3, innerCoords: Int, identifier: Int) {
super.init()

self.coords = coords
self.innerCoords = innerCoords
setup()
}

init(identifier: Int) {
super.init()
// super.init(identifier: identifier)
setup()
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func setup() {
let myPath = path()
let geo = SCNShape(path: myPath, extrusionDepth: 0)
geo.firstMaterial?.diffuse.contents = UIColor.red
geo.firstMaterial?.blendMode = .multiply
self.geometry = geo
}

func path() -> UIBezierPath {

let max: CGFloat = self.size
let min: CGFloat = 0

let bPath = UIBezierPath()
bPath.move(to: .zero)
bPath.addLine(to: CGPoint(x: max / 2,
y: UIBezierPath.middlePeak(height: max)))
bPath.addLine(to: CGPoint(x: max, y: min))
bPath.close()
return bPath
}
}

extension TrianglePlane {

static func generateHexagon() -> [TrianglePlane] {

var myArr: [TrianglePlane] = []

let colors = [UIColor.red, UIColor.green,
UIColor.yellow, UIColor.systemTeal,
UIColor.cyan, UIColor.magenta]


for i in 0 ..< 6 {

let tri = TrianglePlane(identifier: 0)
tri.geometry?.firstMaterial?.diffuse.contents = colors[i]
tri.position = SCNVector3( -0.05, 0, -0.5)

// Rotate bezier path
let angleInDegrees = (Float(i) + 1) * 180.0
print(angleInDegrees)
let angle = CGFloat(deg2rad(angleInDegrees))
let geo = tri.geometry as! SCNShape
let path = geo.path!
path.rotateAroundCenter(angle: angle)
geo.path = path

// Position triangle in hexagon
let radius = Float(tri.size)/2
let deg: Float = Float(i) * 60
let radians = deg2rad(-deg)

let x1 = tri.position.x + radius * cos(radians)
let y1 = tri.position.y + radius * sin(radians)
tri.position.x = x1
tri.position.y = y1

myArr.append(tri)
}

return myArr
}

static func deg2rad(_ number: Float) -> Float {
return number * Float.pi / 180
}
}

extension UIBezierPath {

func rotateAroundCenter(angle: CGFloat) {

let center = self.bounds.center
var transform = CGAffineTransform.identity
transform = transform.translatedBy(x: center.x, y: center.y)
transform = transform.rotated(by: angle)
transform = transform.translatedBy(x: -center.x, y: -center.y)
self.apply(transform)
}

static func middlePeak(height: CGFloat) -> CGFloat {
return sqrt(3.0) / 2 * height
}
}

extension CGRect {
var center : CGPoint {
return CGPoint(x:self.midX, y:self.midY)
}
}

What it currently looks like:

enter image description here

What it SHOULD look like:

enter image description here

最佳答案

我创建了两个版本 - SceneKit 和 RealityKit。


SceneKit(macOS 版本)

组成六边形的最简单方法是使用六个非均匀缩放的 SCNPyramids(平面)及其偏移的枢轴点。每个“三角形”必须以 60 度增量旋转 (.pi/3)。

import SceneKit

class ViewController: NSViewController {

override func viewDidLoad() {
super.viewDidLoad()

let sceneView = self.view as! SCNView
let scene = SCNScene()
sceneView.scene = scene
sceneView.allowsCameraControl = true
sceneView.backgroundColor = NSColor.white

let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)

for i in 1...6 {

let triangleNode = SCNNode(geometry: SCNPyramid(width: 1.15,
height: 1,
length: 1))

// the depth of the pyramid is almost zero
triangleNode.scale = SCNVector3(5, 5, 0.001)

// move a pivot point from pyramid its base to upper vertex
triangleNode.simdPivot.columns.3.y = 1

triangleNode.geometry?.firstMaterial?.diffuse.contents = NSColor(
calibratedHue: CGFloat(i)/6,
saturation: 1.0,
brightness: 1.0,
alpha: 1.0)

triangleNode.rotation = SCNVector4(0, 0, 1,
-CGFloat.pi/3 * CGFloat(i))

scene.rootNode.addChildNode(triangleNode)
}
}
}

enter image description here


RealityKit(iOS 版)

在这个项目中,我在 MeshDescriptor 的帮助下生成了一个三角形,并将其复制了 5 次。

import UIKit
import RealityKit

class ViewController: UIViewController {

@IBOutlet var arView: ARView!
let anchor = AnchorEntity()
let camera = PointOfView()
let indices: [UInt32] = [0, 1, 2]

override func viewDidLoad() {
super.viewDidLoad()

self.arView.environment.background = .color(.black)
self.arView.cameraMode = .nonAR
self.camera.position.z = 9

let positions: [simd_float3] = [[ 0.00, 0.00, 0.00],
[ 0.52, 0.90, 0.00],
[-0.52, 0.90, 0.00]]

var descriptor = MeshDescriptor(name: "Hexagon's side")
descriptor.materials = .perFace(self.indices)
descriptor.primitives = .triangles(self.indices)
descriptor.positions = MeshBuffers.Positions(positions[0...2])

var material = UnlitMaterial()
let mesh: MeshResource = try! .generate(from: [descriptor])

let colors: [UIColor] = [.systemRed, .systemGreen, .yellow,
.systemTeal, .cyan, .magenta]

for i in 0...5 {

material.color = .init(tint: colors[i], texture: nil)
let triangleModel = ModelEntity(mesh: mesh,
materials: [material])

let trianglePivot = Entity() // made to control pivot point
trianglePivot.addChild(triangleModel)

trianglePivot.orientation = simd_quatf(angle: -.pi/3 * Float(i),
axis: [0,0,1])
self.anchor.addChild(trianglePivot)
}

self.anchor.addChild(self.camera)
self.arView.scene.anchors.append(self.anchor)
}
}

enter image description here

关于ios - 如何用 6 个三角形 SCNNode 制作六边形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60484787/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com