Rotate Rectangle Around Its Upper Left Corner - iphone

Simply trying to rotate a rectangle around it's origin, or its upper left corner like so:
Am using the following:
panGestureRecognizer.view.transform = CGAffineTransformRotate(panGestureRecognizer.view.transform, (M_PI * angle) / 180);
But the rectangle is sort of rotating in a big loop. Is there some sort of translation I need to do to get this to work?

You just need to set the anchor point: https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instp/CALayer/anchorPoint
panGestureRecognizer.view.layer.anchorPoint = CGPointMake(0.0, 0.0);
Further Reading: For more advanced stuff you could try some of the tips detailed here for matrix transformations: https://stackoverflow.com/a/8536553/563381

Related

How do I calculate the changed value after rotating the canvas rectangle in Flutter?

Maybe it's simple math, but I'm asking a question because it's not easy to find a way to calculate.
I'm drawing a rectangle using canvas and I can rotate it using canvas.rotate.
If have Rect as follows and I rotate it 30 degrees, how can I calculate the Rect value(rect LTRB) after rotation?
Rect rect = Rect.fromLTRB(100,100,200,200);
final degrees = 30;
final radians = degrees * math.pi / 180;
canvas.translate(100,100); // left top pivot
canvas.rotate(radians);
canvas.translate(-100,-100)
// after rotate, rect left,rop, right, bottom value = ?
Let C be the rotation center. Any corner P maps to
(cos Θ (P.X-C.X) - sin Θ (P.Y-C.Y) + C.X, sin Θ (P.X-C.X) + cos Θ (P.Y-C.Y) + C.Y)
Take the minima and maxima for the four corners to get the bounding box.

Camera Bounds in perspective mode in Unity 3D

How Can I find extreme left, right, top, bottom points of perspective camera in Unity 3D. I am trying to do zooming and panning. I need those points to check if I am going out of my Bound. Is there any other way to find?
This unity manual entry directly answers your question:
FrustumSizeAtDistance
So to summarize:
To calculate the height of the view frustum at a given distance we can calculate it like so:
var frustumHeight = 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
If we already know the frustumHeight we can calculate the corresponding distance to the camera:
var distance = frustumHeight * 0.5f / Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
Once we have the frustumHeight at a given distance we can calculate its width by using the cameras aspect:
var frustumWidth = frustumHeight * camera.aspect;
This can also be reversed like so:
var frustumHeight = frustumWidth / camera.aspect;
Camera.ScreenToWorldPoint will assist you.
For instance, to find bottom-left point of the screen projected onto the world, use this:
camera.ScreenToWorldPoint(new Vector3(0, 0, distance_from_camera));

CGRectApplyAffineTransform Incorrect Result?

I have a bit of code that is trying to figure out the correct bounding box for a rectangle that is being rotated -5 degrees:
CGRect rectangleToRotate = CGRectMake(0,0,104.949, 131.017);
CGAffineTransform rotateTransform = CGAffineTransformMakeRotation((M_PI * -5) / 180);
CGRectApplyAffineTransform (rectangleToRotate, rotateTransform);
The result that is produced is a rectangle with size: {115.968, 139.664} which, for some reason is too huge and doesn't tightly encompass the rectangle. Yet when I go take this same scenario in Adobe Illustrator, the bounding box is: {104.659, 132.143} which is correct.
What exactly am I missing here?
I guess you are doing something wrong in illustrator. How should the bounding box be smaller (104.9 to 104.6) AFTER a 5 degree rotation.. thats just wrong.
The CGRect results are quite right. I tested it in Photoshop.
A 105x131px rect will result in a 117x141px bounding box after a -5 degree rotation.

iPhone - Carousel

I use open source, iCarousel in my application to bring the carousel control. The carousel type which I use is iCarouselTypeRotary and the images are arranged linearly in this type. But, I need the images to bring like the carousel in the attached images. What should I do to make my carousel little tilted to the top view as the style in the below images? Kindly help. Thanks in advance.
You can implement 3D tilt manually:
In iCarousel.m: 574
return CATransform3DTranslate(transform, radius * sin(angle), 0.0f, radius * cos(angle) - radius);
change to:
float tilt = MAX_TILT_VALUE * cos(angle); // greater angle means greater vertical offset
return CATransform3DTranslate(transform, radius * sin(angle), tilt, radius * cos(angle) - radius);
To make the code clear and reusable, implement tilt offset as option (similar to iCarouselOptionArc).
PS: If you want perspective scaling, you will need to add scale transform that depends on cos(angle) similarly to tilt.
Check by using the style:iCarouselTypeWheel use the horizontal wheel set the radius of the wheel as you want. I have done this in vertical wheel type. But i think it should the appearance as above using horizontal wheel type.

Car turning circle and moving the sprite

I would like to use Cocos2d on the iPhone to draw a 2D car and make it steer from left to right in a natural way.
Here is what I tried:
Calculate the angle of the wheels and just move it to the destination point where the wheels point to. But this creates a very unnatural feel. The car drifts half the time
After that I started some research on how to get a turning circle from a car, which meant that I needed a couple of constants like wheelbase and the width of the car.
After a lot of research, I created the following code:
float steerAngle = 30; // in degrees
float speed = 20;
float carWidth = 1.8f; // as in 1.8 meters
float wheelBase = 3.5f; // as in 3.5 meters
float x = (wheelBase / abs(tan(steerAngle)) + carWidth/ 2);
float wheelBaseHalf = wheelBase / 2;
float r = (float) sqrt(x * x + wheelBaseHalf * wheelBaseHalf);
float theta = speed * 1 / r;
if (steerAngle < 0.0f)
theta = theta * -1;
drawCircle(CGPointMake(carPosition.x - r, carPosition.y),
r, CC_DEGREES_TO_RADIANS(180), 50, NO);
The first couple of lines are my constants. carPosition is of the type CGPoint. After that I try to draw a circle which shows the turning circle of my car, but the circle it draws is far too small. I can just make my constants bigger, to make the circle bigger, but then I would still need to know how to move my sprite on this circle.
I tried following a .NET tutorial I found on the subject, but I can't really completely convert it because it uses Matrixes, which aren't supported by Cocoa.
Can someone give me a couple of pointers on how to start this? I have been looking for example code, but I can't find any.
EDIT After the comments given below
I corrected my constants, my wheelBase is now 50 (the sprite is 50px high), my carWidth is 30 (the sprite is 30px in width).
But now I have the problem, that when my car does it's first 'tick', the rotation is correct (and also the placement), but after that the calculations seem wrong.
The middle of the turning circle is moved instead of kept at it's original position. What I need (I think) is that at each angle of the car I need to recalculate the original centre of the turning circle. I would think this is easy, because I have the radius and the turning angle, but I can't seem to figure out how to keep the car moving in a nice circle.
Any more pointers?
You have the right idea. The constants are the problem in this case. You need to specify wheelBase and carWidth in units that match your view size. For example, if the image of your car on the screen has a wheel base of 30 pixels, you would use 30 for the WheelBase variable.
This explains why your on-screen circles are too small. Cocoa is trying to draw circles for a tiny little car which is only 1.8 pixels wide!
Now, for the matter of moving your car along the circle:
The theta variable you calculate in the code above is a rotational speed, which is what you would use to move the car around the center point of that circle:
Let's assume that your speed variable is in pixels per second, to make the calculations easier. With that assumption in place, you would simply execute the following code once every second:
// calculate the new position of the car
newCarPosition.x = (carPosition.x - r) + r*cos(theta);
newCarPosition.y = carPosition.y + r*sin(theta);
// rotate the car appropriately (pseudo-code)
[car rotateByAngle:theta];
Note: I'm not sure what the correct method is to rotate your car's image, so I just used rotateByAngle: to get the point across. I hope it helps!
update (after comments):
I hadn't thought about the center of the turning circle moving with the car. The original code doesn't take into account the angle that the car is already rotated to. I would change it as follows:
...
if (steerAngle < 0.0f)
theta = theta * -1;
// calculate the center of the turning circle,
// taking int account the rotation of the car
circleCenter.x = carPosition.x - r*cos(carAngle);
circleCenter.y = carPosition.y + r*sin(carAngle);
// draw the turning circle
drawCircle(circleCenter, r, CC_DEGREES_TO_RADIANS(180), 50, NO);
// calculate the new position of the car
newCarPosition.x = circleCenter.x + r*cos(theta);
newCarPosition.y = circleCenter.y + r*sin(theta);
// rotate the car appropriately (pseudo-code)
[car rotateByAngle:theta];
carAngle = carAngle + theta;
This should keep the center of the turning circle at the appropriate point, even if the car has been rotated.