Skip to content

Instantly share code, notes, and snippets.

@kemalenver
Last active September 19, 2021 03:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kemalenver/79523e5606f62c5958fcf5e9bedc48a5 to your computer and use it in GitHub Desktop.
Save kemalenver/79523e5606f62c5958fcf5e9bedc48a5 to your computer and use it in GitHub Desktop.
An SCNNode that draws a circle of given detail
import Foundation
import SceneKit
class CircleNode: SCNNode {
init(detail: Int = 500) {
super.init()
let elements = self.generateElements(detail: detail)
let circleSources = self.generateCircleGeometrySources(detail: detail)
let materials = self.generateMaterials()
let circleGeometry = SCNGeometry(sources: circleSources, elements: elements)
self.geometry = circleGeometry
self.geometry?.materials = materials
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func generateMaterials() -> [SCNMaterial] {
let material = SCNMaterial()
material.isDoubleSided = true
material.lightingModel = .constant
material.blendMode = .add
material.diffuse.contents = UIImage(named: "art.scnassets/orbit_gradient.png")
return [material]
}
private func generateElements(detail: Int) -> [SCNGeometryElement] {
var indices: [Int32] = []
for i in 0..<detail-1 {
indices.append(Int32(i))
indices.append(Int32(i+1))
}
return [SCNGeometryElement(indices: indices, primitiveType: .line)]
}
private func generateCircleGeometrySources(detail: Int) -> [SCNGeometrySource] {
var verticesVectors = [SCNVector3]()
var textureCoordsPoints = [CGPoint]()
for i in 0..<detail {
let per = Float(i) / Float(detail-1)
let angle = per * (Float.pi * 2)
let vertice = SCNVector3(cos(angle), sin(angle), 0)
let texture = CGPoint(x: Double(per), y: 0.5)
verticesVectors.append(vertice)
textureCoordsPoints.append(texture)
}
let vertices = SCNGeometrySource(vertices: verticesVectors)
let textureCoords = SCNGeometrySource(textureCoordinates: textureCoordsPoints)
return [vertices, textureCoords]
}
}
@kemalenver
Copy link
Author

kemalenver commented Sep 6, 2019

Example use:

var circle = OrbitNode(detail: 1000)
circle.scale = SCNVector3(50, 50, 50)

@screenworker
Copy link

Hi, how can i change the line width so that it becomes significantly stronger?

@kemalenver
Copy link
Author

@screenworker - this is deliberately generating a circle using primitiveType: .line So it will always be a circle wireframe (which is what I needed). If you want something 'thicker' in a 3D scene then you need to use a geometry that makes sense, a cylinder, or a disk? In the code above where it generates the circle, you could generate points to make a disk instead, and change the primitive type to .triangle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment