Objective-c: How to Rotate CGRect

I tried to rotate my rectangle, but it does not work properly.

Here is part of my code, I found it in another post:

#define DEGREES_TO_RADIANS(x) (M_PI * x / 180.0) -(void)drawRect:(NSRect)rect { CGContextRef cRef = [[NSGraphicsContext currentContext] graphicsPort]; // points[] - this is a CGPoints array, length_one is a double value CGRect rect_one = CGRectMake(points[0].x, points[0].y, (CGFloat)length_one, 40); // I've print out the origin of old one and new one NSLog(@"old rect -- %f, %f", rect_one.origin.x, rect_one.origin.y); float centerX = rect_one.origin.x + (rect_one.size.width / 2.0); float centerY = rect_one.origin.y + (rect_one.size.height / 2.0); CGAffineTransform rotation = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(10)); CGAffineTransform moveAnchor = CGAffineTransformMakeTranslation(centerX, centerY); CGAffineTransform centeredRotation = CGAffineTransformConcat(moveAnchor, rotation); CGRect rotatedRect = CGRectApplyAffineTransform(rect_one, centeredRotation); CGContextAddRect(cRef, rotatedRect); // new one NSLog(@"new rect -- %f, %f", rotatedRect.origin.x, rotatedRect.origin.y); } 

And the origin has changed a lot, even I can’t find my new rectangle from the view. The old origin (x = 263.3, y = 502.8), and the new origin - (x = 506.1, y = 1132.0). How does this system work, especially how to set the angle of rotation? If possible, could you guys help me explain this briefly. Many thanks!!!!

+4
source share
2 answers

As others have said, NSRect or CGRect always a rectangle with an axis . CGRectApplyAffineTransform returns the axis-aligned bounding box of the translated rectangle:

diagram of rectangles

Note that the new rectangle (bounding box) may have different sizes than the original rectangle if you applied the rotation. This means that using a rectangle to transform a transformed rectangle is useless.

Instead, you need to transform the coordinate system of the graphics context. Think of it this way: you draw a piece of paper on a table. You always draw a rectangle that is aligned with the edges of the table. To draw a rotating rectangle, you rotate the paper and then draw a rectangle, as usual. Changing the CTM is like turning (or moving or squeezing or expanding) a sheet of paper.

 -(void)drawRect:(NSRect)rect { CGContextRef gc = [[NSGraphicsContext currentContext] graphicsPort]; // points[] - this is a CGPoints array, length_one is a double value CGRect rect = CGRectMake(points[0].x, points[0].y, (CGFloat)length_one, 40); CGFloat xMid = CGRectGetMidX(rect); CGFloat yMid = CGRectGetMidY(rect); CGContextSaveGState(gc); { // Translate the origin to the midpoint of the rectangle, because rotations // always happen around the origin. CGContextTranslateCTM(gc, xMid, yMid); // Rotate the coordinate system by 10 degrees. CGContextRotateCTM(gc, 10 * M_PI / 180); // Prepare a new rectangle, with the same size as the original rectangle // but centered on the origin. CGRect newRect = rect; newRect.origin.x = -newRect.size.width / 2; newRect.origin.y = -newRect.size.height / 2; // Add the rectangle to the context path. CGContextAddRect(gc, newRect); // Draw the new rectangle. CGContextSetFillColorWithColor(gc, [NSColor lightGrayColor].CGColor); CGContextSetStrokeColorWithColor(gc, [NSColor blackColor].CGColor); CGContextSetLineWidth(gc, 2); CGContextSetLineJoin(gc, kCGLineJoinMiter); CGContextDrawPath(gc, kCGPathFillStroke); } CGContextRestoreGState(gc); } 
+3
source
 override func drawRect(rect: CGRect) { super.drawRect(rect) let context : CGContextRef = UIGraphicsGetCurrentContext() var rect = CGRectMake(100, 100, 120, 180) CGContextSaveGState(context); var path :CGMutablePathRef = CGPathCreateMutable(); var midX : CGFloat = CGRectGetMidX(rect); var midY : CGFloat = CGRectGetMidY(rect); var transfrom: CGAffineTransform = CGAffineTransformConcat( CGAffineTransformConcat(CGAffineTransformMakeTranslation(-midX, -midY),CGAffineTransformMakeRotation(0.3)), CGAffineTransformMakeTranslation(midX, midY)); CGPathAddRect(path, &transfrom, rect); CGContextSetFillColorWithColor(context, UIColor.blueColor().CGColor); CGContextAddPath(context, path); CGContextFillPath(context); CGContextRestoreGState(context); } 
0
source

All Articles