【问题标题】:Limiting CGAffineTransform Scale限制 CGAffineTransform 规模
【发布时间】:2011-03-19 01:56:37
【问题描述】:

我正在使用 CGAffineTransformMake 转换视图。它旋转、缩放和平移。这工作得很好。但我想不出办法将比例限制为最大尺寸。

如果超出比例,我仍然需要应用当前的旋转和平移。

非常感谢任何建议!

来源:

UITouch *touch1 = [sortedTouches objectAtIndex:0];
UITouch *touch2 = [sortedTouches objectAtIndex:1];

CGPoint beginPoint1 = *(CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch1);
CGPoint currentPoint1 = [touch1 locationInView:self.superview];
CGPoint beginPoint2 = *(CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch2);
CGPoint currentPoint2 = [touch2 locationInView:self.superview];

double layerX = self.center.x;
double layerY = self.center.y;

double x1 = beginPoint1.x - layerX;
double y1 = beginPoint1.y - layerY;
double x2 = beginPoint2.x - layerX;
double y2 = beginPoint2.y - layerY;
double x3 = currentPoint1.x - layerX;
double y3 = currentPoint1.y - layerY;
double x4 = currentPoint2.x - layerX;
double y4 = currentPoint2.y - layerY;

// Solve the system:
//   [a b t1, -b a t2, 0 0 1] * [x1, y1, 1] = [x3, y3, 1]
//   [a b t1, -b a t2, 0 0 1] * [x2, y2, 1] = [x4, y4, 1]

double D = (y1-y2)*(y1-y2) + (x1-x2)*(x1-x2);
if (D < 0.1) {
    return CGAffineTransformMakeTranslation(x3-x1, y3-y1);
}

double a = (y1-y2)*(y3-y4) + (x1-x2)*(x3-x4);
double b = (y1-y2)*(x3-x4) - (x1-x2)*(y3-y4);
double tx = (y1*x2 - x1*y2)*(y4-y3) - (x1*x2 + y1*y2)*(x3+x4) + x3*(y2*y2 + x2*x2) + x4*(y1*y1 + x1*x1);
double ty = (x1*x2 + y1*y2)*(-y4-y3) + (y1*x2 - x1*y2)*(x3-x4) + y3*(y2*y2 + x2*x2) + y4*(y1*y1 + x1*x1);

return   CGAffineTransformMake(a/D, -b/D, b/D, a/D, tx/D, ty/D);

【问题讨论】:

    标签: iphone scale multi-touch uitouch cgaffinetransform


    【解决方案1】:

    做这样的事情:

    CGAffineTransform transform = self.view.transform;
    float scale = sqrt(transform.a*transform.a + transform.c*transform.c);
    if (scale > SCALE_MAX)
        self.view.transform = CGAffineTransformScale(transform, SCALE_MAX/scale, SCALE_MAX/scale);
    else if (scale < SCALE_MIN)
        self.view.transform = CGAffineTransformScale(transform, SCALE_MIN/scale, SCALE_MIN/scale);
    

    在您的 touchesMoved:withEvent: 和 updateOriginalTransformForTouches 方法结束时。基本上,您检查当前比例是否超过某个 SCALE_MAX 值,然后将变换矩阵乘以反向比例值。

    【讨论】:

    • 完美!!!非常感谢!我无法投票赞成您的答案,因为我没有足够的声誉。有人可以为我投票吗?如果可以的话,我会投票 10 次!再次感谢。
    • 顺便说一句:我有一个线性代数文本,我正在努力学习这类东西。
    • 它也非常适合我的情况,如果是现代实现(例如:iOS 5.0 及更高版本),请尝试使用 UIPanGestureRecognizer。
    【解决方案2】:

    如果有人需要 @Enzo Tran 在 Swift 中使用 UIPanGestureRecognizer 的答案:

    func handlePinch(recognizer : UIPinchGestureRecognizer) {
        if let view = recognizer.view {
            view.transform = CGAffineTransformScale(view.transform,
                                                       recognizer.scale, recognizer.scale)
            let transform = view.transform
            let maxScale: CGFloat = 1.7 //Anything
            let minScale: CGFloat = 0.5 //Anything
            let scale = sqrt(transform.a * transform.a + transform.c * transform.c)
            if scale > maxScale {
                view.transform = CGAffineTransformScale(transform, maxScale / scale, maxScale / scale)
            }
            else if scale < minScale {
                view.transform = CGAffineTransformScale(transform, minScale / scale, minScale / scale)
            }
    
            recognizer.scale = 1
        }
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 2019-08-04
      • 1970-01-01
      • 2015-01-20
      • 1970-01-01
      相关资源
      最近更新 更多