I am trying to move two lines joint to a fixed position sprite in a way similar to that of a pendulum. I would like the lines to swing from end to end each time. The image below shows what I want to achieve:

enter image description here

I'm moving the lines using angular velocity, but I'm not getting the pendulum/swinging effect (a cycle of the lines generally swinging faster as they move to the center and slowing down a bit when they change from one direction to another). I rather get some brisk movement then it slows down till the movement stops. Please see my SpriteKit code below:

extension Int {
  var degreesToRadians: Double { return Double(self) * .pi / 180 }
extension FloatingPoint {
  var degreesToRadians: Self { return self * .pi / 180 }
  var radiansToDegrees: Self { return self * 180 / .pi }

class GameScene: SKScene, SKPhysicsContactDelegate {

var anchorSprite = SKSpriteNode(imageNamed: "swingPin")
var armLeft = SKSpriteNode(imageNamed: "swingArm")
var armRight = SKSpriteNode(imageNamed: "swingArm")

override func didMove(to view: SKView) {

self.physicsWorld.gravity = CGVector(dx: 0, dy: -1.8)
self.physicsWorld.contactDelegate = self

var tealBg = SKSpriteNode(imageNamed: "tealBg")
tealBg.position = CGPoint(x: frame.midX, y: frame.midY)
tealBg.zPosition = 10

anchorSprite.position = CGPoint(x: frame.midX, y: frame.midY + frame.midY/2)
anchorSprite.zPosition = 20

anchorSprite.physicsBody = SKPhysicsBody(rectangleOf: anchorSprite.frame.size)
anchorSprite.physicsBody?.categoryBitMask = pinCategory
anchorSprite.physicsBody?.isDynamic = false

armRight.anchorPoint = CGPoint(x: 0.5, y: 1)
armRight.position = anchorSprite.position
armRight.zPosition = 20
armRight.physicsBody = SKPhysicsBody(rectangleOf: armRight.frame.size)
armRight.zRotation = CGFloat(Double(15).degreesToRadians)//CGFloat(Double.pi/6)
armRight.physicsBody!.isDynamic = true


armLeft.anchorPoint = CGPoint(x: 0.5, y: 1)
armLeft.position = anchorSprite.position
armLeft.zPosition = 20
armLeft.physicsBody = SKPhysicsBody(rectangleOf: armRight.frame.size)
armLeft.zRotation = CGFloat(Double(-15).degreesToRadians)//CGFloat(-Double.pi/6)
armLeft.physicsBody!.isDynamic = true

// Create joint between two objects
//Pin joint
var pinAndRightArmJoint = SKPhysicsJointPin.joint(withBodyA: anchorSprite.physicsBody!, bodyB: armRight.physicsBody!, anchor: CGPoint(x: anchorSprite.position.x, y: self.armRight.frame.maxY))

var pinAndLeftArmJoint = SKPhysicsJointPin.joint(withBodyA: anchorSprite.physicsBody!, bodyB: armLeft.physicsBody!, anchor: CGPoint(x: anchorSprite.position.x, y: self.armLeft.frame.maxY))

var fixArms = SKPhysicsJointFixed.joint(withBodyA: armLeft.physicsBody!, bodyB: armRight.physicsBody!, anchor: CGPoint.zero)

pinAndRightArmJoint.shouldEnableLimits = true
pinAndRightArmJoint.lowerAngleLimit = CGFloat(Double(-60).degreesToRadians)
pinAndRightArmJoint.upperAngleLimit = CGFloat(Double(60).degreesToRadians)


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
armRight.physicsBody?.angularVelocity = -100.0


Please note that though I believe this is the most appropriate approach to my problem, I'm open to another approach that would help me achieve the same result.


Use a sine wave:

angle = 45 * sin(time)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.