Skip to content

Instantly share code, notes, and snippets.

@Zbeyer
Last active November 1, 2016 00:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zbeyer/90670b3f6cf08b9cb15eee3c16958cae to your computer and use it in GitHub Desktop.
Save Zbeyer/90670b3f6cf08b9cb15eee3c16958cae to your computer and use it in GitHub Desktop.
Points of a Clockface in Swift
import SpriteKit
import XCPlayground
//SpriteKit and XCPlayground are required modules
//ZBeyer October 31st 2016
/*:Clock Face
# Clock Face
This Playground Uses Spritekit to generate the points of a clock face (where there are twelve equally spaced nodes in a circle)
*/
/**
circleGenerator
- Parameter size: The pixel size of the circle within the clock
- Parameter point: The x and y cooridantes within the scene where the circle will be placed
- Parameter scene: The scene in which the node will be placed
creates a SKShapeNode circle at a specified point within the specified scene
*/
func circleGenerator(size:CGFloat, point:CGPoint, scene:SKScene) -> SKShapeNode {
let c = SKShapeNode(circleOfRadius: size ) // Size of Circle
c.glowWidth = 1.0
c.fillColor = SKColor.orange
c.position = point
scene.addChild(c)
return c
}
//Basic dimensions that we will use more later
let frame = CGRect(x: 0,
y: 0,
width: 320,
height: 320)
//Center point of the frame
let midPoint = CGPoint(x: frame.size.width / 2.0,
y: frame.size.height / 2.0)
//radius of the planned clockface
let r = (min(frame.height, frame.width)) * 0.618 * 0.5
//Create a scene, add something to it
var scene = SKScene(size: frame.size)
//Set up the view and show the scene
let view = SKView(frame: frame)
view.presentScene(scene)
//Attatch the scene view to the live preview...
XCPlaygroundPage.currentPage.liveView = view
let kSize:CGFloat = 4 //Constant size of each node on the clock face
let kSqrtThreeOverTwo:CGFloat = sqrt(3) * 0.5 //Constant computed value used in placing the nodes of the various clock face
/*:quadrants
# Quadrants
Each node offsets from the center point of the scene. depending on how a node is offset will determine which quadrant it falls under. Communicating in quadrants is only used to help visualize how the scene will be arranged. Quadrants are arranged clockwise starting at the twelve O'clock (center-top) position.
## QI (+, +)
The first quadrant is the upper right quarter of the scene. Offset positive in the x axis and positive in the y axis.
## QII (+, -)
The second quadrant is the lower right quarter of the scene. Offeset positive in the x axis and negative in the y axis.
## QIII (-, -)
The third quadrant is the lower left quarter of the scene. Offset negative in the x axis and negative in the y axis.
## QIV (-, +)
The fourth quadrant is the upper left quarter of the scene. Offset negative in the x axis and positive in the y axis.
Computing the points of each node is simple: using basic geometry, one imagines two perfect hexegons of equal size anchored at the midpoint and positioned at center of the scene (0, 0). One hexegon is rotated at a 90 degree angle. The points of each hexegon become the positions that must be computed.
### Hexegon Geometry
A perfect hexegon with a side length of n has a total width of 2n and a total height of n multiplied by the square root of three. Because the hexegons are assumed to be at the center the points are halved.
Hexegon A
Height Offset:(√3 * SideLength)/2
Width Offset:(SideLength)
*-------*
/ \
/ \
* * *
\ /
\ /
*-------*
Above we computed the radius of our clock face. Assuming that the clock face has a Diameter equal to the total width of Hexegon A (2 * SideLength) then the Radius of the clock face is equal to the length of a hexagonal side. Thus SideLength becomes **r**
Hexegon B, being rotated by 90 degrees will use the same coordinate data, only reversed for each point within or touching a given quadrant...
If Hexegon A offset by (X:r, Y:0) Hexegon B will have a point at (X:0, Y:r)
For the purpose of this exercise, it is not important to keep track of which points would theoretically belong to a hexegon, as in reality the hexegon is not important... this is just an expanded way of determining the points of a twelve sided polygon anchored to the center of a cartesian space...
Below the points are plotted...
*/
//QI (+, +)
let twelve:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x + 0,
y:midPoint.y + r),
scene:scene)
let one:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x + r * 0.5,
y:midPoint.y + r * kSqrtThreeOverTwo),
scene:scene)
let two:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x + r * kSqrtThreeOverTwo,
y:midPoint.y + r * 0.5),
scene:scene)
//QII (+, -)
let three:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x + r,
y:midPoint.y + 0),
scene:scene)
let four:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x + r * kSqrtThreeOverTwo,
y:midPoint.y - r * 0.5),
scene:scene)
let five:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x + r * 0.5,
y:midPoint.y - r * kSqrtThreeOverTwo),
scene:scene)
//QIII (-, -)
let six:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x + 0,
y:midPoint.y - r),
scene:scene)
let seven:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x - r * 0.5,
y:midPoint.y - r * kSqrtThreeOverTwo),
scene:scene)
let eight:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x - r * kSqrtThreeOverTwo,
y:midPoint.y - r * 0.5),
scene:scene)
//QIV (-, +)
let nine:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x - r,
y:midPoint.y - 0),
scene:scene)
let ten:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x - r * kSqrtThreeOverTwo,
y:midPoint.y + r * 0.5),
scene:scene)
let eleven:SKShapeNode = circleGenerator(size: kSize,
point: CGPoint(
x:midPoint.x - r * 0.5,
y:midPoint.y + r * kSqrtThreeOverTwo),
scene:scene)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment