I'm building a relatively simple game in SpriteKit where you can bounce a ball based on a user's touch location, using something like ball.physicsBody.applyImpulse(someVector).
I've been trying to understand how to gravity and vectors work by playing with the values of the physicsWorld.gravity vector and the vector of impulse I apply on the ball and I think I need some clarification;
If I use this code:
self.physicsWorld.gravity = CGVectorMake(0, -10)
ball.physicsBody.applyImpulse(CGVectorMake(0, 10))
Shouldn't the ball, based on this code and according to common sense not move at all, as the pulling and pushing forces are equal, or at least go up the exact distance of 10 before starting to fall in this case?
In reality what happens is that the ball does bounce up and is going a distance of over 10 pixels up.
Why is it behaving like that, and what exact value do I need to use for the vectors to cancel out so that the ball remains completely still?
I'd be happy for any sort of explanation, Thanks in advance.
That 10 is not pixels, for gravity, it is meters per second, so you need to take the 10 and divide by FPS to get 1 frame, (1/6 meter) and then you need to figure out what meter to pixel ratio is, and that will get you the number of pixels. For impulse, it is Newton seconds, which is pushing 1 kilogram 1 meter per second. So you need to figure out the mass of the item to figure out how many meters it is really moving per second. So if your objects mass was 1 KG, then it would balance to 0. I am not going to do the actual math to tell you how to calculate this stuff, you will have to research on your own.
In Summary:
Gravity unit is meters per second
Impulse unit is newtown second AKA kilogram meter per second
You need to match units in order for things to balance out to 0
See https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKPhysicsBody_Ref/#//apple_ref/occ/instm/SKPhysicsBody/applyImpulse: and https://developer.apple.com/library/mac/documentation/SpriteKit/Reference/SKPhysicsWorld_Ref/index.html#//apple_ref/occ/instp/SKPhysicsWorld/gravity if you want to learn more.
Related
I'm trying to implement a russian roulette game and want it to brute-force the solution for it. Here is my problem. I'm going to hard code the relative angles of the numbers on the wheel (eg. there are 36 numbers and each number would have 10 degree offset to each other, the one on the top, 12 o'clock position, will have the 0 and the next 10 and vice versa). I will rotate the wheel randomly and then determine the rotation of it based on some values that I can calculate (startPosition to finishedPosition). The wheel is an ImageView. Is there a way to actually do this? For example, get the top left x,y pos for its start and end, then by some formula to calculate how much it rotated. Or is there a better way to do this? There is not much of a source code to show it, so this is more like a mathematical question rather than a swift one. Any feedback is much appreciated.
To calculate rotation, you need coordinates of three points: start location sx, sy, end location ex, ey of the same point after rotation and center of rotation cx, cy
Then you can find angle using atan2 function
rot_angle = atan2((ex-cx)*(sx-cx)+(ey-cy)*(sy-cy), (ex-cx)*(sy-cy)-(ey-cy)*(sx-cx))
Note - I used argument order (x,y) from here, while most languages use reverse order (y,x), so check what order you really need (I have no experience in IOS languages). Also result value might be in radians or in degrees (above link doesn't specify it clearly)
Your question doesn't make much sense. If you rotate the wheel randomly, calculate the random value as an angle. If you want to change the previous rotation by some random angle, then do the math on the starting rotation and ending rotation. That is just adding and subtracting angles (modulo 2π). Then you will know how far it is rotated, and not have to calculate it.
Assuming you're talking about a roulette wheel, and not "Russian Roulette" (In American English at least, that term involves pointing a loaded revolver at your head) you'll need to track both the wheel rotation and the ball rotation. To apply the rotation to the wheel, you'll just take the image of the wheel and rotate it on the Z axis around it's x/y center point.
To plot the ball, you'll need to use trig to calculate the center of the ball based on the radius of the track the ball follows and the angle. But again, always track the angle, and then convert the angle to an x/y center point for the ball to plot it. Don't forget the angle and then have to convert back from the ball position to its angle. That's silly.
I have done a tiny bit of 3d graphics in the past. When you move or rotate a Scene Kit sprite does it automatically update its translation matrix, or do you have to make it yourself?
Are "position" and "eulerAngles" both properties that are... absolute.
For example if I am in sprite kit and set the translation to (1, 0) it will be at that point relative to the origin.
And if I set the z rotation to 90 it will be rotated 90 degrees.
And if I incrament the translation (with +=) x it will start going in a line.
And same for zRotation if incremented it will rotate. In scene kit if I do similar things to the translation and euler angle values will they do the same thing?
Also what exactly does the accelerometer think its measuring, it is like the amount of motion in a certain period? So basically is it the delta between the two simultaneous points that the device was in.
Yes, this question is definitely broad, however they are much better placed here, then scattered in three tiny posts.
Doe, let me see if I can help
Translation matrix? It has a TRANSFORM matrix that includes translation, scale and rotation, and yes, it is automatically updated when you change one of these 3, and vice-versa.
If I understood well, yes, just like in SpriteKit. They are related to their parent coordinates. The position (1,0,0) would mean the Node (its center, unless you change its pivot (anchorPoint in spriteKit)) will be at distance 1 along the X axis of its parent from its parent origin).
The same works for the rotation, if a NodeA has 30 degrees rotation at axis X and you add a NodeB with 20 degrees rotation at X in NodeA, you would have the NodeA having visually a 50 degrees rotation at X.
Accelerometer measures the acceleration forces given to the device in a specific moment, in the three axis of the device. Its unit is not [m^2/s] but [Gravity/s] (would be approximately [10m^2/s]). An important detail is that this measure includes the gravity acceleration as well.
So, if you try to measure the acceleration with the device standing ortogonal to the ground, you would expect (0, 0, -1) (or 0,0,1, if upside down).
Lying down the device on the ground it would be (0, 1or-1, 0) (depending if the screen is facing the ground or the ceiling)
For for every tick (of update rate of the accelerometer) it calculates what was the acceleration imposed to the device at that moment. That's not the delta itself, but it can be easily calculated if you store the values.
I know that you can define a sprite's mass and density with SpriteKit. If I had 2 sprites laying on top of a 3rd sprite, like a scale, is there a way to measure the total weight that is lying on the 3rd node?
Sure. Just define your own gravity in the z direction, multiply it by the mass of the node on top, and you've got its weight. No need to take density into account (it's not like my scale says I weigh any different if I stand on it or lay down on it). Pressure is force/area, so just divide the weight by the area if you want to get that.
Alright, so I'm trying to create my own Physics engine for a 3D XNA game, and I'm having troubles calculating how much I should move my object by for gravity.
XNA's game timer occurs every 16 milliseconds, so after some calculations, and using 9.81m/s as my gravitational velocity, you can see that you should increase the velocity of the object that has gravity by:
0.15696 meters/16milliseconds
- basically every update call should increase the object by 0.15696 meters
The questions is, how do I convert 0.15696 meters into pixels. Obviously if I just use a 1:1 relationship the object will only move 9.81 pixels/second. Which does not really simulate gravity :P Does anyone have a good idea on how I can determine how many pixels I should move the object by?
Thanks for all the help!
Although 2d game dev is more pixel-centric, 3d game dev doesn't concern itself with pixels for this kind of stuff, but rather units. Unit size is completely arbitrary.
Typically, you have a velocity vector whose magnitude is equivalent to the meters(or feet or ??) per second that your object is going. That way the position is updated each frame by adding this velocity * the elapsed time since last frame (the 16.6666 ms). The acceleration from gravity is added to the velocity vector in the same way:
Vector3 gravity = Vector3.Down * 9.81f;
//in the update loop
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;//0.01666667 (or 16.67 ms) # 60FPS
velocity += gravity * elapsed;
position += velocity * elapsed;
In this example, I've arbitrarily established that 1 xna unit == 1 meter.
You just have to figure out how large an "area" your screen represents; then its simple scaling. If you have a 2D representation of a satellite orbiting earth, then your "Y" pixels represent ground to satellite (approximately 35,000 meters).
Use your equations from classical physics (http://en.wikipedia.org/wiki/List_of_equations_in_classical_mechanics), and then just scale real dimensions to your screen.
I have a rotating sphere that the user rotates by applying a virtual force, like a virtual accelerator. I want to be able to simulate a nice momentum effect so that when they lift off the accelerator the ball winds down in speed in a natural and realistic way, as if due to friction and/or gravity. I don't want to get into any deep physics equations. I'd like to do this quick so if I could find a code sample that shows how to do this, or even a page of formulas clear enough that I could encode, that would be great.
I'd like a formula that has one or two adjustable coefficients that I could tune to make the ball decelerate faster or slower depending on my needs. I don't want to get into anything heavy like an open source physics library or the like. Just something simple.
I'm using Delphi 6 Pro but I also know C/C++, Basic, Java, and Javascript.
Velocity is change in displacement. Acceleration is change in velocity.
Gravity or friction just causes an acceleration (possibly negative).
So all you need to do is apply a negative acceleration when they do not activate the accelerator.
So lets assume you have an angle that is changing. Applying the accelerator increases the amount the angle changes by each iteration or time step. If your angle is t and your change in angle is called dt (angular velocity) then when the accelerator is applied you'll have:
t = t + dt
dt = dt + a
where a depends on how much force you're applying, or how much they've 'pressed' the accelerator (i.e. this is the acceleration).
You'll probably want to limit dt (i.e. speed of rotation) - if you only want to spin in one direction you'll have an upper positive limit and a lower limit of 0. If you want both directions, you can have a lower negative limit and an upper positive limit.
All you need to do is make a some negative number when the accelerator is not applied (if dt is positive - make a positive if dt is negative), and ensure you don't 'wrap' (i.e. make dt 0 when it gets near 0).
It has been some time ago, but according to my dynamics study books the Mass Moment of Inertia for a sphere is defined as I=(2/5)m*r^2. m is the mass, r is the radius of the sphere (all in SI untis). On this page you'll find some examples to use the mass moment of inertia to calculate deceleration of the sphere as a result of the applied negative torque. This toqrue is a result of the friction. Since you are not defining the material of the surface of the sphere and the surroudings you cannot calculate the friction and will have to choose a good force yourself.
As long as you are not solving stellar problems, I don't see how gravity has much to do with decelerating the rotation.
Friction is almost proportional to the current rotation speed (actually the speed on the surface of the sphere).
So a formula for the current rotation speed over time w(t) may be something like this:
w(t) = w0*exp(-c*(t - t0))
with t0 being the time the friction starts, wt being the rotation speed at that time.
The coefficient c > 0 determines how fast the speed will decrease - the higher c, the faster the speed will go down. This formula is valid for all t >= t0.
Note that for t = t0 the exp function returns 1 and you get the initial speed, while for t -> ∞ the exp function (and so the resulting speed) returns -> 0 (the minus in front of the c guarantees this).
You've already accepted an answer, but I'll put in my piece.
I'll assume you already know how to make the sphere spin at a constant rate, and how to make it accelerate under the applied torque. Making it decellerate is just a matter of applying another torque, one that must be calculated.
When an object slides on a solid surface, the rate of deceleration is constant. The force is in the direction opposite to motion, and its magnitude depends on a couple of things but not speed. When the object comes to a full stop, the force vanishes. The same applies to a globe turning on a solid pivot.
When an object passes through a fluid, the force of decelleration increases with speed, so the faster the object the greater the drag. As the object slows down, decelleration grows weaker, and the object keeps slowing down but never stops. This describes a globe spinning in air or water. At reasonably high speeds, drag is proporional to v2, and at very low speeds it is proportional to v (I don't know about the transition between these domains).
So I suggest t = -a wb, where w is angular velocity. The parameter a is the strength of the friction, and b describes the kind of decelleration; b=0 is like friction on a solid pivot, b=2 is like spinning in air, and b=1 is like rotating in syrup. Other values of b may or may not look realistic or be realistic.