How to Rotate Sprites Around a Joint

Is it possible to rotate a Node around an arbitrary point in SpriteKit?

Since you're asking for the best way, here's one that works well (best is subjective):

Create an SKNode and set its position to the center of rotation. Add the node that should rotate around that center as child to the center node. Set the child node's position to the desired offset (ie radius, say x + 100). Change the rotation property of the center node to make the child node(s) rotate around the center point. The same works for cocos2d btw.

How do you pass through a Spritekit joint anchor?

This was resolved by also setting the categoryBitMask to 0.

chunkHolder.physicsBody?.categoryBitMask = 0
chunkHolder.physicsBody?.collisionBitMask = 0

how to rotate an object from a point inside the object

Rotations in OpenGL rotate around an axis placed at the origin (0, 0, 0). In order to rotate around a specific point, you need first to translate that point to the origin, perform your rotation. In the OP, you would be rotating around the point (-50,-50, 0) (since translations move coordinate systems, and not specific points), and then rotating joint degrees around the Z axis.

From the OP, assuming that joint is updated each frame, I would expect that code to have the square orbiting around the point (-50, -50, 0).

Bendable arm rotation in SpriteKit - rotate at point

You want to use an SKPhysicsJointPin

Here are the available Sprite-Kit joints :https://developer.apple.com/reference/spritekit/skphysicsjoint

Sample Image

You add or remove joints using the physics world. When you create a joint, the points that connect the joint are always specified in the scene’s coordinate system. This may require you to first convert from node coordinates to scene coordinates before creating a joint.

To use a physics joint in your game, follow these steps:

  1. Create two physics bodies.
  2. Attach the physics bodies to a pair of SKNode objects in the scene.
  3. Create a joint object using one of the subclasses listed in the
    diagram above. If necessary, configure the joint object’s properties
    to define how the joint should operate.
  4. Retrieve the scene’s SKPhysicsWorld object.
  5. Call the physics world’s add(_:) method.

The following code pins two nodes, upperArm and lowerArm, together using a 'elbow' implemented via an , SKPhysicsJointPin joint. We calculate the 'elbow' position by taking the middle of the area where upperArm and lowerArm overlap - this is pretty crude and should be improved.

let elbowArea = lowerArm.frame.intersection(upperArm.frame)

let elbowPosition = CGPoint(x: elbowArea.midX, y: elbowArea.midY)

let elbowJoint = SKPhysicsJointPin.joint(withBodyA: upperArm.physicsBody!,
bodyB: lowerArm.physicsBody!,
anchor: elbowPosition)
scene.physicsWorld.add(elbowJoint)

You should also set rotation limits on the pin joint (elbow) via the joint's properties:

var shouldEnableLimits: Bool A Boolean value that indicates whether
the pin joint’s rotation is limited to a specific range of values.

var lowerAngleLimit: CGFloat The smallest angle allowed for the pin
joint, in radians.

var upperAngleLimit: CGFloat The largest angle allowed for the pin
joint, in radians.

Rotate and transform connected rigid bodies in unity3d


How can I achieve this effect?

Point to the object then rotate it.

First you want to find the GameObject.

GameObject g = GameObject.Find("Object Name");

Save the original rotation so you can return to it.

Quaternion originalPos = g.transform.rotation;

Then rotate it to your liking.

g.transform.rotation = new Quaternion(x,y,z,w);

In addition you could use iTween to smoothen out the rotation.

Rotating an Object properly around a pivot point given axis and angle

Question a)

Basically it works as expected:

    cylinder.position.set( options.x, 15, options.z );
pivot.position.x=options.x;
pivot.position.z=options.z;

see
https://jsfiddle.net/wf_bitplan_com/4f6ebs90/13/

Sample Image
Sample Image

Question b)

see
https://codepen.io/seppl2019/pen/zgJVKM

individually rotating arms

The key is to set the positions correctly. Instead of the proposal at https://stackoverflow.com/a/43837053/1497139 the size is computed in this case.

// create the pivot to rotate around/about
this.pivot = new THREE.Group();
this.pivot.add(this.mesh);
// shift the pivot position to fit my size + the size of the joint
this.pivot.position.set(
x,
y + this.size.y / 2 + this.pivotr,
z + this.size.z / 2
);
// reposition the mesh accordingly
this.mesh.position.set(0, this.size.y / 2, 0);

How to rotate pymunk joints at will?

From the servo example I took a hint and implemented this basic leg:

Sample Image

import sys

import pygame
from pygame.locals import USEREVENT, QUIT, KEYDOWN, KEYUP, K_s, K_r, K_q, K_ESCAPE, K_UP, K_DOWN, K_RIGHT, K_LEFT
from pygame.color import THECOLORS

import pymunk
from pymunk import Vec2d
import pymunk.pygame_util

class Simulator(object):

def __init__(self):
self.display_flags = 0
self.display_size = (600, 600)

self.space = pymunk.Space()
self.space.gravity = (0.0, -1900.0)
#self.space.damping = 0.999 # to prevent it from blowing up.

# Pymunk physics coordinates start from the lower right-hand corner of the screen.
self.ground_y = 100
ground = pymunk.Segment(self.space.static_body, (5, self.ground_y), (595, self.ground_y), 1.0)
ground.friction = 1.0
self.space.add(ground)

self.screen = None

self.draw_options = None

def reset_bodies(self):
for body in self.space.bodies:
if not hasattr(body, 'start_position'):
continue
body.position = Vec2d(body.start_position)
body.force = 0, 0
body.torque = 0
body.velocity = 0, 0
body.angular_velocity = 0
body.angle = body.start_angle

def draw(self):
self.screen.fill(THECOLORS["white"])### Clear the screen
self.space.debug_draw(self.draw_options)### Draw space
pygame.display.flip()### All done, lets flip the display

def main(self):
pygame.init()
self.screen = pygame.display.set_mode(self.display_size, self.display_flags)
width, height = self.screen.get_size()
self.draw_options = pymunk.pygame_util.DrawOptions(self.screen)

def to_pygame(p):
return int(p.x), int(-p.y+height) #Small hack to convert pymunk to pygame coordinates
def from_pygame(p):
return to_pygame(p)

clock = pygame.time.Clock()
running = True
font = pygame.font.Font(None, 16)

# Create the spider
chassisXY = Vec2d(self.display_size[0]/2, self.ground_y+100)
chWd = 70; chHt = 50
chassisMass = 10

legWd_a = 50; legHt_a = 5
legWd_b = 100; legHt_b = 5
legMass = 1
relativeAnguVel = 0

#---chassis
chassis_b = pymunk.Body(chassisMass, pymunk.moment_for_box(chassisMass, (chWd, chHt)))
chassis_b.position = chassisXY
chassis_shape = pymunk.Poly.create_box(chassis_b, (chWd, chHt))
chassis_shape.color = 200, 200, 200, 100
print("chassis position");print(chassis_b.position)

#---first left leg a
leftLeg_1a_body = pymunk.Body(legMass, pymunk.moment_for_box(legMass, (legWd_a, legHt_a)))
leftLeg_1a_body.position = chassisXY - ((chWd/2)+(legWd_a/2), 0)
leftLeg_1a_shape = pymunk.Poly.create_box(leftLeg_1a_body, (legWd_a, legHt_a))
leftLeg_1a_shape.color = 255, 0, 0, 100

#---first left leg b
leftLeg_1b_body = pymunk.Body(legMass, pymunk.moment_for_box(legMass, (legWd_b, legHt_b)))
leftLeg_1b_body.position = leftLeg_1a_body.position - ((legWd_a/2)+(legWd_b/2), 0)
leftLeg_1b_shape = pymunk.Poly.create_box(leftLeg_1b_body, (legWd_b, legHt_b))
leftLeg_1b_shape.color = 0, 255, 0, 100

#---first right leg a
rightLeg_1a_body = pymunk.Body(legMass, pymunk.moment_for_box(legMass, (legWd_a, legHt_a)))
rightLeg_1a_body.position = chassisXY + ((chWd/2)+(legWd_a/2), 0)
rightLeg_1a_shape = pymunk.Poly.create_box(rightLeg_1a_body, (legWd_a, legHt_a))
rightLeg_1a_shape.color = 255, 0, 0, 100

#---first right leg b
rightLeg_1b_body = pymunk.Body(legMass, pymunk.moment_for_box(legMass, (legWd_b, legHt_b)))
rightLeg_1b_body.position = rightLeg_1a_body.position + ((legWd_a/2)+(legWd_b/2), 0)
rightLeg_1b_shape = pymunk.Poly.create_box(rightLeg_1b_body, (legWd_b, legHt_b))
rightLeg_1b_shape.color = 0, 255, 0, 100

#---link left leg b with left leg a
pj_ba1left = pymunk.PinJoint(leftLeg_1b_body, leftLeg_1a_body, (legWd_b/2,0), (-legWd_a/2,0))#anchor point coordinates are wrt the body; not the space
motor_ba1Left = pymunk.SimpleMotor(leftLeg_1b_body, leftLeg_1a_body, relativeAnguVel)
#---link left leg a with chassis
pj_ac1left = pymunk.PinJoint(leftLeg_1a_body, chassis_b, (legWd_a/2,0), (-chWd/2, 0))
motor_ac1Left = pymunk.SimpleMotor(leftLeg_1a_body, chassis_b, relativeAnguVel)
#---link right leg b with right leg a
pj_ba1Right = pymunk.PinJoint(rightLeg_1b_body, rightLeg_1a_body, (-legWd_b/2,0), (legWd_a/2,0))#anchor point coordinates are wrt the body; not the space
motor_ba1Right = pymunk.SimpleMotor(rightLeg_1b_body, rightLeg_1a_body, relativeAnguVel)
#---link right leg a with chassis
pj_ac1Right = pymunk.PinJoint(rightLeg_1a_body, chassis_b, (-legWd_a/2,0), (chWd/2, 0))
motor_ac1Right = pymunk.SimpleMotor(rightLeg_1a_body, chassis_b, relativeAnguVel)

self.space.add(chassis_b, chassis_shape)
self.space.add(leftLeg_1a_body, leftLeg_1a_shape, rightLeg_1a_body, rightLeg_1a_shape)
self.space.add(leftLeg_1b_body, leftLeg_1b_shape, rightLeg_1b_body, rightLeg_1b_shape)
self.space.add(pj_ba1left, motor_ba1Left, pj_ac1left, motor_ac1Left)
self.space.add(pj_ba1Right, motor_ba1Right, pj_ac1Right, motor_ac1Right)

#---prevent collisions with ShapeFilter
shape_filter = pymunk.ShapeFilter(group=1)
chassis_shape.filter = shape_filter
leftLeg_1a_shape.filter = shape_filter
rightLeg_1a_shape.filter = shape_filter
leftLeg_1b_shape.filter = shape_filter
rightLeg_1b_shape.filter = shape_filter


simulate = False
rotationRate = 2
while running:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key in (K_q, K_ESCAPE)):
#running = False
sys.exit(0)
elif event.type == KEYDOWN and event.key == K_s:
# Start/stop simulation.
simulate = not simulate
elif event.type == KEYDOWN and event.key == K_r:
# Reset.
# simulate = False
self.reset_bodies()
elif event.type == KEYDOWN and event.key == K_UP:
motor_ba1Left.rate = rotationRate
elif event.type == KEYDOWN and event.key == K_DOWN:
motor_ba1Left.rate = -rotationRate
elif event.type == KEYDOWN and event.key == K_LEFT:
motor_ac1Left.rate = rotationRate
elif event.type == KEYDOWN and event.key == K_RIGHT:
motor_ac1Left.rate = -rotationRate
elif event.type == KEYUP:
motor_ba1Left.rate = 0
motor_ac1Left.rate = 0

self.draw()

### Update physics
fps = 50
iterations = 25
dt = 1.0/float(fps)/float(iterations)
if simulate:
for x in range(iterations): # 10 iterations to get a more stable simulation
self.space.step(dt)

pygame.display.flip()
clock.tick(fps)

if __name__ == '__main__':
sim = Simulator()
sim.main()

It can be controlled with the up, left, right and down arrow keys after first pressing the s key to start the simulation. I've also made sure the variables are created properly linked with each other and named well.

The part about making the joints move to a desired angle is yet to be implemented, but perhaps that could be calculated by taking the x,y positions of the ends of the joints and using a formula to calculate the angle and then move the motor until it reaches a desired angle.

If there's a better way, do let me know by posting an answer or editing this one.

DirectX 9 rotating around joints

There are two main steps for your requirements.

  1. Rotate joints 0, 1 and 2 around the origin by 90 degrees.
  2. Rotate joint 2 around joint 1 by 90 degrees.

I write some pseudo code, it almost done, but you still need some updates to use it. see comments in the code for details.

void Rotatation()
{
// Build up the rotation matrix for step 1
D3DXVECTOR3 rotAxis(0, 0, 1);
float angle = -(D3DX_PI / 2);
D3DXMATRIX rotMatrix;
D3DXMatrixRotationAxis(&rotMatrix, &rotAxis, angle);

// rotate joints 0, 1 and 2 by apply the matrix above
for (int i = 0; i < 3; i++)
{
joints[i].matrix *= rotMatrix;
}

// Build up the rotation matrix for joint 2
// Since joint 2 was not rotate around the origin(I mean the axis should pass the origin), so first you need to translate the rotation center to origin
// then rotate joint 2, and last move back

// After the rotation in step 1, joint 1 now locate at (0, 2, 0)
// to translate it to the origin.
D3DXMATRIX transMat;
D3DXMatrixTranslation(&transMat, 0, 2, 0);

// Now joint 2 can rotate around z-axis, so the rotate matrix is same as step 1

// after rotation, move back, this matrix is the inverse of transMat
D3DXMATRIX inverseTransMat;
D3DXMatrixTranslation(&transMat, 0, -2, 0);

// Combine the 3 matrix above
D3DXMATRIX rotMatjoin2 = transMat * rotMatjoin2 * inverseTransMat;

// rotate jonit 2
joints[2].matrix *= rotMatjoin2;
}


Related Topics



Leave a reply



Submit