As others have said, an NSRect
or CGRect
is always an axis-aligned rectangle. CGRectApplyAffineTransform
returns the axis-aligned bounding box of the translated rectangle:
Note that the new rectangle (the bounding box) is likely to have different dimensions than the original rectangle, if you applied a rotation. This means it's useless to apply a transform to a rectangle if you want to draw the transformed rectangle.
Instead, you need to transform the coordinate system of the graphics context. Think of it like this: you're drawing on a sheet of paper on a desk. You always draw a rectangle that is aligned to the edges of the desk. To draw a rotated rectangle, you rotate the paper, then draw a rectangle as usual. Changing the CTM is like rotating (or moving or shrinking or expanding) the 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's 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);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…