Wheel rotates and goes back to starting position iPhone - iphone

I am using
float theAngle = atan2( location.y-self.center.y, location.x-self.center.x );
to rotate a wheel at a certain angle.
and
self.transform = CGAffineTransformMakeRotation(angleRadians);
for the transformation to take place.
But everytime the user represses the wheel to turn it, it goes back to the original location and starts from there. How may I stop this from happening please?
Thanks!

You may setting the rotation angle value of the wheel rather than adding the value to the current angle.

I would hazzard a guess that the reason is that you are calculating based on the original position of the wheel rather than the previous position of the wheel.
i.e. Presuming that self.center represents the original position of the wheel as first displayed, location represents the users desired new rotation and looking up atan2 on wikipedia (trig is not my strong point :-) I would guess you need self.location to be updated each time to the be location so that the next rotation starts from the last rotation.
Just a guess :-)

Related

Add force to object by rotation

I want to add force to an object, by using its own rotation. For example, if I turn my object 90 degrees to the left. How can I add force towards, but consider the 90 degrees and not the local rotation?
I am not sure what exactly you want to do. What do you want to add force towards? Did you mean forwards?
Another question is also when do you add the force and 90° to left from what?
I assume this:
the object you want to add force to is at some angle in the world
the object rotates to 90° to the world's left
at some time after the rotation you want to add force to it based on the rotation
If that is what you want then you need to:
specify first what do you measure the angle change from (the original angle) and save it in a variable
have a vector in the direction you want to add the force when the object has the above-mentioned angle
when you want to add the force, you need to calculate the difference between the current angle and the saved angle
rotate the vector based on the angle difference
add the force in the direction of the vector

Determine the direction an object is actually moving

In unity I am trying to compare the players actual direction with the direction they are facing and wish to move in but having major issues trying to find the actual movement direction.
I can determine the facing direction very easily with:
wishDir = transform.localEulerAngles;
But I cannot figure out how to get the objects movement direction so that I can compare. I have tried:
transform.InverseTransformDirection(rb.velocity);
I would expect this to be equal to 0,90,0 when I move to the right however it is equal to 0,0,0 (although jumps when there is acceleration).
How can I determine the direction an object is moving in?
I can determine the facing direction very easily with:
wishDir = transform.localEulerAngles;
This is already quite odd to me. localEulerAngles is a rotation in Euler space notation in degrees per axis x,y,z .. this is no "direction".
Usually if you want the direction you are looking in you would rather use transform.forward
wishDir = transform.forward;
And then
transform.InverseTransformDirection(rb.velocity);
should indeed return the direction in local space.
Note that the Debug.Log beautifies (rounds) this value to make it more human readable. If you want the exact values you could try and log e.g.
var relative = transform.InverseTransformDirection(rb.velocity);
Debug.Log(relative.ToString(F4));
which should print the values always with 4 digits after the decimal point.

Camera movement using WASD on x/z plane only

I've been wearing my enter key down on google searches - I have a camera script based on the MouseOrbit.js asset. That's all working fine, but in addition to the basic orbiting and the zooming that I've added, I would like to use the WASD keys to move the camera around the world.
The W key would move the camera straight forward, however it would ignore the y axis. For example, using
transform.Translate(Vector3.Forward*Time.Delta*20);
moves the camera forward relative to the camera. This results in you quickly hitting the ground. Moving back oibviously does the opposite. The desired effect is sliding across the world without getting any closer/farther to it, regardless of the angle the camera is at.
The closest I can get is using the Space.World parameter of Translate(), but this does not take into account the rotation of my camera. I think if I could take that into account, this would be solved but I'm not clear on how to do that.
Thanks,
Chris
(From Tetrad on http://Gamedev.stackecxchange.com)
You don't need to use transform.Translate. Just calculate how much the camera should move forward for a given frame (something like if the W key is held down do deltaPos = transform.forward * Time.deltaTime * 20), set the Y value of that Vector3 to zero, then add that delta vector to the original position by adding it to the current position transform.position += deltaPos;

UIImageView rotation affecting position?

I have a UIImageView that is set to move up and down the screen with the value of the accelerometer, using the following code:
ship.center = CGPointMake(ship.center.x, ship.center.y+shipPosition.y);
Where shipPosition is a CGPoint set in the accelerometerDidAccelerate method using:
shipPosition.y = acceleration.x*60;
Obviously this works fine, it is very simple. I run into trouble when I try to something equally simple, vary the rotation of the image depending on its acceleration. I do this using:
ship.transform = CGAffineTransformMakeRotation(shipPosition.y);
For some reason this causes a very strange thing to happen, in that the image snaps back to its origin every time the main method is called. I can see frames where the image moves to where it should be, but then instantly snaps back.
This problem only happens when I have the rotation line in, commented out it works fine. I have no idea what is going on here, I have done this many times for different apps and i never had such a problem. In fact I copied my code from a different app I created where it works fine.
EDIT:
What really confuses me is when I change the angle of the rotation from the acceleration to the position of the ship using:
ship.transform = CGAffineTransformMakeRotation(ship.center.y/10);
When I do this, the ship actually rotates based on the accelerometer but does not move, which is crazy because a changing ship.center.y means the position of the ship is changing, but it's not!!
You should set the transform of you view back to CGAffineTransformIdentity before you set his center coordinates or frame and after that apply the new transformation.
The frame property returns the transformed coordinates of a view if it is transformed and not the true (well actually the transformed are true) coordinates.
Quote from the docs:
Warning: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
Update/Actual Answer:
Well the actual problem is
shipPosition.y = acceleration.x*60;
Since you set the y pos in accelerometerDidAccelerate.
The acceleration won't remember it's old value. So if you move your device it will get a peak and as you slow down it will decelerate again.
Your ship will be +/-60 at the highest acceleration speed but will be 0 when you stop moving your device and shipPosition.y will be 0.
CGAffineTransformMakeRotation expects angle in radians, not in degrees.
1 radian = M_PI / 180.0 degrees

rotating circle with swipe question

Okay so I'm making something that basically works as a knob, but only half on the screen -- so I just need horizontal swipes to cause it to rotate. I have it nearly all sorted with one exception: if you change direction of your swipe in mid-swipe, the rotation doesn't change direction. I even can see the problem, but not sure what to do about a solution.
So in my touchesMoved, I get the swipe into radians in the predictable way:
CGFloat radians = atan2f(location.y - centerY, location.x - centerX);
I then store radians, add/subtract it to previous rotation and then give the result to the CATransform3D.
So the prob is that even though the swipe changes direction, there is a "balance" which doesn't allow an immediate change of direction.
Does this make any sense?
First, I hope you get that atan() returns values in the range -π/2..+π/2, so you'll never get values in the other half of the circle. (If you deduce that the answer is on that side, you have to do your own flipping/mirroring.)
In your touches-moved, NSLog() what you've calculated the new difference to be, and be sure that it's the value you're expecting.
Of course, you keep the previous radians on touchesBegan, and save-off the current radians on init, touchesEnded and touchesCancelled, right?
(In many cases, touchesCancelled can just fwd the arguments to touchesEnded.)
If you do all of that, then the scheme you describe ought to work. If it does not, perhaps provide more information, like the NSLog() output for the various values when you think those values should be different.
For interactions like this, what I find usually works best is to save the state at the start of the interaction and the touch down location. Then, whenever you update, compute the new state based on the distance between the original touch and the current touch (applied as a difference from the original state).
For example, in the case you mention, what I would do on a touch down would be to store the current angle of the knob and the location of the touch. Then, on a touch move, I would compute the difference between the current touch location and the starting location. This will give you a delta value, which you can translate into an angle which you can add to the starting angle - update your knob graphic accordingly. This ought to allow you to change direction however you like throughout your behavior without worrying about keeping up with incremental changes to your angle. This also makes it extremely easy to handle things like resistance or dampening after a certain angle - far easier than it would be to handle that when updating things incrementally.
Be careful to use atan2 to avoid quadrant issues and division by zero. That's what it's there for.
// angle with +ve x-axis, in the range [0, 2π)
float getDirection(CGPoint V)
{
double theta = atan2(V.x, V.y); // angle with +ve x-axis, in the range (−π, π]
if (theta < 0)
theta = 2 * M_PI - theta;
return theta;
}
+ (CGPoint) vectorFrom: (CGPoint) A to: (CGPoint) B
{ return CGPointMake(B.x - A.x, B.y - A.y); }
i did something similar to this for simulating a turntable scratching motion. Try:
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithInt:0] forKey:kCATransactionAnimationDuration];
[myLayer setValue:[NSNumber numberWithFloat:radians] forKeyPath:#"transform.rotation.z"];
[CATransaction commit];
on the underlying layer of your view.