目标-c:如何旋转CGRect [英] Objective-c: How to rotate CGRect

查看:101
本文介绍了目标-c:如何旋转CGRect的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试旋转矩形,但是无法正常工作.

I've 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);
}

即使我从视图中找不到新的矩形,原点也发生了很大变化. 旧的原点是(x = 263.3,y = 502.8),新的原点是(x = 506.1,y = 1132.0)这个系统如何工作,尤其是如何分配旋转角度?如果可能的话,你们能帮我简要解释一下吗.非常感谢!!!

And the origin changed a lot even I can not find my new rectangle from the view. Old origin is (x = 263.3, y = 502.8) and the new origin is (x=506.1, y=1132.0) How does this system work especially how to assign the angle of rotation? If possible, could you guys help me brief explain it. Thanks a lot!!!!

推荐答案

正如其他人所说,NSRectCGRect始终是与轴对齐的矩形. CGRectApplyAffineTransform返回转换后的矩形的与轴对齐的边界框:

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.

相反,您需要变换图形上下文的坐标系.这样想:您正在桌上的一张纸上画画.您总是绘制一个与桌子边缘对齐的矩形.要绘制旋转的矩形,请旋转纸张,然后照常绘制一个矩形.更改CTM就像旋转(或移动,缩小或扩展)纸张.

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);

}

这篇关于目标-c:如何旋转CGRect的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆