CGPoint rotation changes distance from origin - iphone

I want to rotate a CGPoint(red rect) around another CGPoint(blue rect) but it changes distance from the origin(blue rect)...when i give 270 in angle it creates the point right above the origin but when i give 90 as angle value it comes down the origin BUT CHANGES THE DISTANCE ALSO almost three times more....I want to keep the distance same and want to rotate CGPoint around another. Please guide any approach for rotation of cgpoints...
distance = 100;
angle = 270*M_PI/180;
rotatedPoint.x = initialPoint.x+distance*cos(angle);
rotatedPoint.y = initialPoint.y+distance*sin(angle);
//rotatedPoint.x = initialPoint.x+tan(angle);
[test setCenter:rotatedPoint];
[test setBackgroundColor:[UIColor redColor]];
Thanks

CGAffineTransform is a handy tool when it comes to rotation, translation, and scaling. To make sure a point is rotated properly, you must translate it to the origin, rotate it, and then translate it back.
To complete your transformation, something like the following should do the trick:
CGPoint pointToRotate = CGPointMake(30, 30);
float angleInRadians = DEGREES_TO_RADIANS(90);
CGPoint distanceFromOrigin = CGPointMake(0 - pointToRotate.x, 0 - pointToRotate.y);
CGAffineTransform translateToOrigin = CGAffineTransformMakeTranslation(distanceFromOrigin.x, distanceFromOrigin.y);
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(angleInRadians);
CGAffineTransform translateBackFromOrigin = CGAffineTransformInvert(translateToOrigin);
CGAffineTransform totalTransform = CGAffineTransformConcat(translateToOrigin, rotationTransform);
totalTransform = CGAffineTransformConcat(totalTransform, translateBackFromOrigin);
pointToRotate = CGPointApplyAffineTransform(pointToRotate, totalTransform);
And here is the documentation on CGAffineTransform, if you'd like to review it further: http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html
Please let me know if you need anything else if this doesn't solve your problem!

Related

Rotate CGRect property of a CCSprite ?

I have a sublclass of a CCSprite that rotates throughout the game and there is a shield that has to rotate around the sprite according to the sprite's rotation. So if the sprite's rotation is 75 degrees there should be a CGRect located at 75 degrees. The dimensions of the CGRect are subordinate as it almost resembles a square.
What I did is:
I subclassed CCSprite and added a property called shieldArea.
Upon initialization I set this rect to be
self.shieldArea = CGRectMake(self.position.x-30, self.position.y, 8, 10);
Then I rotate the sprite itself, however, the rect stays at its initial position.
I hoped that the CGrect would be affected by the rotation, but I kind of expected it not to affect it, of course, why should it ? So, my question is, how do I rotate a CGRect at all ? Or do I have to add a new CGRect all the time ?
Side notes: I do not want to use Box2d or anything the like. I handle collision detection myself.
Have you tried CGAffineTransform?
Something like this:
float centerX = myOldRect.origin.x + (myOldRect.size.width / 2.0);
float centerY = myOldRect.origin.y + (myOldRect.size.height / 2.0);
CGAffineTransform rotation = CGAffineTransformMakeRotation(someAngleInRadians);
CGAffineTransform moveAnchor = CGAffineTransformMakeTranslation(centerX, centerY);
CGAffineTransform centeredRotation = CGAffineTransformConcat(moveAnchor, rotation);
CGRect rotatedRect = CGRectApplyAffineTransform(myOldRect, centeredRotation);
Note, this is NOT tested. Use at your own risk :p

CGAffineTransformMakeTranslation Movement

I am using CGAffineTransformMakeTranslation with UIPanGestureRecognizer to pan a UIView.
Does CGAffineTransformMakeTranslation take delta x and delta y or the absolute value of the new position? Here's what I have:
- (void)swipeDetected:(UIPanGestureRecognizer *)recognizer
{
CGPoint newTranslation = [recognizer translationInView:self.view];
self.navController.view.transform = CGAffineTransformMakeTranslation(newTranslation.x, 0);
.....
}
This works from left to right but not from right to left. I'm pretty sure "translation" means delta x and delta y and not absolute value.
Any suggestions?
Thanks
Setting the transform is an immediate operation as it is just matrix multiplication of the view's location.
If you need to revert back from your current position, you can save the transform to an ivar, and use an inverse transform, ie:
_currentTransform = CGAffineTransformMakeTranslation(newTranslation.x, 0);
and later:
CGAffineTransform inverse = CGAffineTransformInvert(_currentTransform);
If you want to remove all transforms you can do self.transform = CGAffineTransformIdentity
Hope this helps!

Retrieving all 4 coordinates of a rotated UIImageView

How does one get the 4 coordinates for a UIImageView?
I know the CGRect can be obtained and the origin.x and origin.y, but how can all 4 corners be found?
EDIT: I am rotating the UIImageViews, thats why I asked :P
You could add width and height of the rectangle to get the coordinates of the other 3 points.
CGRect rect = view.bounds;
CGPoint topLeft = rect.origin;
CGPoint topRight = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y);
CGPoint bottomLeft =CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);
CGPoint bottomRight = CGPointMake(rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height);
Then you could use CGPointApplyAffineTransform to get the transformed coordinates of them under your specified transform.
CGPoint center = view.center;
CGAffineTransform transf = CGAffineTransformMakeTranslation(-rect.size.width/2,
-rect.size.height/2);
transf = CGAffineTransformConcat(transf, view.transform);
transf = CGAffineTransformTranslate(transf, center.x, center.y);
topLeft = CGPointApplyAffineTransform(topLeft, transf);
//...
(note: not tested.)
This is my solution:
[self] is a subclass of UIImageView
[self.transform] is the transform i make on [self]:
CGAffineTransform transform = CGAffineTransformMakeTranslation(-center.x, -center.y);
transform = CGAffineTransformConcat(transform, self.transform);
CGAffineTransform transform1 = CGAffineTransformMakeTranslation(center.x, center.y);
transform = CGAffineTransformConcat(transform, transform1);
CGPoint leftTopPoint = CGPointApplyAffineTransform(leftTopPoint, transform);
CGPoint rightTopPoint = CGPointApplyAffineTransform(rightTopPoint, transform);
CGPoint rightBottomPoint = CGPointApplyAffineTransform(rightBottomPoint, transform);
CGPoint leftBottomPoint = CGPointApplyAffineTransform(leftBottomPoint, transform);
You can get the size.width and size.height. Adding those to the x and y will give you the other coordinates.
Whilst these are (of course) relative to the superview, you can use the frame property to obtain a CGRect containing the origin and size of the UIImageView. You can then simply add the relevant size to the relevant origin point to obtain the full set of coordinates.
See the frame section in the UIView class reference for more information.
Construct a rotation matrix http://en.wikipedia.org/wiki/Rotation_matrix. You should calculate the initial positions of the corners relative to the point which is the center of rotation. Store those positions in an array and keep them all the time. You calculate new positions by passing the angle in a 2x2 rotation matrix and multiplying them with initial positions.
Well, given you know the angle of rotation, this is the maths to get the y coordinate of the top right corner:
Sin (angle of rotation) = height difference y / width
Therefore if you're rotating the rectangle by 10 deg and it has a width of 20pt:
Sin 10 = yDiff / 20
Which means you can do this:
yDiff = Sin 10 * 20
This gives you the difference in y from the y coordinate of the origin to the y coordinate of the top right corner. Add this value to the current y origin of your rectangle to get the actual y coordinate of your top right corner. The next step is to use pythagoras on your width and the yDiff to get the xDiff and do the same (add it to the x coordinate) to get the x coordinate of your right hand corner. I hope this makes sense.
Now you just need to do it again for each other corner - imagine, if you will, that the rectangle has rotated through 90 deg, you can just reapply the logic, however x is y and vice versa. :) etc

how to rotate a UIView to face a point

I have a UIView that I want to rotate when I move my finger across the screen (like in a circle). I want the UIView to rotate so that it faces my touchpoint. I then want to shoot something from my UIView (like a bullet) in the direction that the UIView is facing. Any Ideas???
Glad I remember triginometry
-(void)degreesToRotateObjectWithPosition:(CGPoint)objPos andTouchPoint:(CGPoint)touchPoint{
float dX = touchPoint.x-objPos.x; // distance along X
float dY = touchPoint.y-objPos.y; // distance along Y
float radians = atan2(dY, dX); // tan = opp / adj
//Now we have to convert radians to degrees:
float degrees = radians*M_PI/360;
return degrees;
}
Once you have your nice method, just do this:
CGAffineTransform current = view.transform;
[view setTransform:CGAffineTransformRotate(current, [view degreesTorotateObjectWithPosition:view.frame.origin andTouchPoint:[touch locationInView:parentView]]
//Note: parentView = The view that your object to rotate is sitting in.
This is pretty much all the code that you'll need.The math is right, but I'm not sure about the setTransform stuff. I'm at school writing this in a browser. You should be able to figure it out from here.
Good luck,
Aurum Aquila

Convert CGPoint between iPhone & CA planes

I have a UIView subclass that I'm drawing a PDF onto (using a CATiledLayer). I also need to draw on a specific region of that PDF, however the coordinate plane of the CATiledLayer when using CG to draw is way screwy.
See image:
I have a point (200,200), that I need to convert to the CATiledLayer's coordinate system, which is the 2nd plane shown above. I've tried doing this with some transforms, but nothing seems to work.
Thanks!
Here is what I had to do (using the example points/plane above):
//rotatation origin
CGPoint rotateOrigin = CGPointMake(0,0);
//rotatation transform
CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(rotateOrigin.x, rotateOrigin.y);
//rotate the plane 90 degrees
float radians = 90 * (M_PI / 180);
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(radians); CGAffineTransform customRotation = CGAffineTransformConcat(CGAffineTransformConcat( CGAffineTransformInvert(translateTransform), rotationTransform), translateTransform);
CGAffineTransform m1 = CGAffineTransformIdentity;
CGPoint startPoint = CGPointApplyAffineTransform(CGPointMake(200,200),m1);
//rotated point
CGPoint rotatedPoint = CGPointApplyAffineTransform(startPoint, customRotation);
//final rotated point- after adjusting for the rotation
rotatedPoint = CGPointApplyAffineTransform(rotatedPoint, CGAffineTransformMakeTranslation(500,-500));