Ios 如何准确地放大夹点手势上的特定点(使用多个夹点)?

Ios 如何准确地放大夹点手势上的特定点(使用多个夹点)?,ios,objective-c,matrix,uigesturerecognizer,transformation,Ios,Objective C,Matrix,Uigesturerecognizer,Transformation,我正在尝试缩放iOS应用程序中的四边形。它不需要基于四边形的中心进行缩放,而是基于收缩的质心进行缩放 我能够正确地执行此操作-但仅限于第一个捏手势。在随后的挤压动作中,它是有效的,但它有一点漂移,看起来不太准确。我不知道该怎么办。 关于这一点,有几个问题,我已经讨论了大部分,如果不是全部的话。没有一个能准确地解决我的问题 还请注意,我正在缩放和转换四边形(渲染为GLKView),而不是视图本身。我见过的大多数解决方案都是直接转换视图的 以下是挤压手势和操作的代码: viewDidLoad中的第一

我正在尝试缩放iOS应用程序中的四边形。它不需要基于四边形的中心进行缩放,而是基于收缩的质心进行缩放

我能够正确地执行此操作-但仅限于第一个捏手势。在随后的挤压动作中,它是有效的,但它有一点漂移,看起来不太准确。我不知道该怎么办。

关于这一点,有几个问题,我已经讨论了大部分,如果不是全部的话。没有一个能准确地解决我的问题

还请注意,我正在缩放和转换四边形(渲染为GLKView),而不是视图本身。我见过的大多数解决方案都是直接转换视图的

以下是挤压手势和操作的代码: viewDidLoad中的第一个:

UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc]
                                             initWithTarget:self action:@selector(respondToPinchGesture:)];
pinchRecognizer.cancelsTouchesInView = YES;
pinchRecognizer.delaysTouchesEnded = NO;
[glView addGestureRecognizer:pinchRecognizer];
其中glView是GLKView对象。 和处理程序:

- (IBAction)respondToPinchGesture:(UIPinchGestureRecognizer *)recognizer{

    if (recognizer.state == UIGestureRecognizerStateEnded || [recognizer numberOfTouches] < 2) return;

    if (recognizer.state == UIGestureRecognizerStateBegan) {
        point = [recognizer locationInView:glView];
        point.x *= glView.contentScaleFactor;
        point.y *= glView.contentScaleFactor;
        point.y = height - point.y;

        anchor = GLKVector3Make(point.x, point.y, 0);
        lastScale = 1.0;
    }

    if (fabs(recognizer.scale - lastScale) > 0.01){

        GLfloat scale = 1.0 - (lastScale - recognizer.scale);
        lastScale = recognizer.scale;

        new_anchor_point = anchor;
        new_anchor_point = GLKVector3MultiplyScalar(new_anchor_point, scale);
        GLKVector3 translate = GLKVector3Subtract(anchor, new_anchor_point);

        path.transform = GLKMatrix4TranslateWithVector3(path.transform, translate);
        path.transform = GLKMatrix4Scale(path.transform, scale, scale, 0);

        cumulative_translate = GLKVector3Add(cumulative_translate, translate);
    }

}
-(iAction)响应topinch手势:(UIPinchGestureRecognizer*)识别器{
if(recognizer.state==UIgestureRecognitizerStateEnded | |[recognizer numberoftoffices]<2)返回;
if(recognizer.state==UIgestureRecognitizerStateStart){
点=[识别器位置视图:glView];
point.x*=glView.contentScaleFactor;
point.y*=glView.contentScaleFactor;
点y=高度-点y;
锚定=GLKVector3Make(点x,点y,0);
lastScale=1.0;
}
if(fabs(识别器刻度-最后刻度)>0.01){
GLfloat scale=1.0-(lastScale-recognizer.scale);
lastScale=recognizer.scale;
新锚定点=锚定点;
新锚定点=GLKVector3多重刻度(新锚定点,刻度);
GLKVector3 translate=GLKVector3子域(锚定、新锚定点);
path.transform=GLKMatrix4TranslateWithVector3(path.transform,translate);
path.transform=glkmarix4scale(path.transform,scale,scale,0);
累计翻译=GLKVector3Add(累计翻译,翻译);
}
}
欢迎指点。我已经做了两天了,即使是一个模糊的建议也可能会有帮助。

你必须这样做

  • 记住识别器开始时的上一个变换矩阵
  • 假设视图或对象之前未进行变换,则为收缩缩放构造新的变换矩阵
  • 然后,将两个矩阵连接在一起。这将是变换对象或视图的最终矩阵
    • 你必须

      • 记住识别器开始时的上一个变换矩阵
      • 假设视图或对象之前未进行变换,则为收缩缩放构造新的变换矩阵
      • 然后,将两个矩阵连接在一起。这将是变换对象或视图的最终矩阵

      我通过以下方法解决了这个问题:

      -(GLKVector3)get_touch_point_on_view:(UIGestureRecognizer *)recognizer{
          CGRect bounds = [glView bounds];
          CGPoint point = [recognizer locationInView:glView];
          point.y = bounds.size.height - point.y;
          return GLKVector3Make((point.x * glView.contentScaleFactor - total_translation.x)/total_scale,
                                         (point.y * glView.contentScaleFactor - total_translation.y)/total_scale, 0);
      }
      - (void)respondToPinchGesture:(UIPinchGestureRecognizer *)recognizer{
          if (recognizer.state == UIGestureRecognizerStateBegan) {
              lastScale = 1.0;
          }
      
          [self get_touch_point_on_view:recognizer];
      
          if (fabs(recognizer.scale - lastScale) > 0.01){
      
              GLfloat scale = 1.0 - (lastScale - recognizer.scale);
              lastScale = recognizer.scale;
              total_scale *= scale;
      
              path.transform = GLKMatrix4TranslateWithVector3(path.transform, centroid);
              path.transform = GLKMatrix4Scale(path.transform, scale, scale, 0);
              path.transform = GLKMatrix4TranslateWithVector3(path.transform, GLKVector3Negate(centroid));
              total_translation = [self get_total_translation];
      
          }
      }
      

      我通过以下方法解决了这个问题:

      -(GLKVector3)get_touch_point_on_view:(UIGestureRecognizer *)recognizer{
          CGRect bounds = [glView bounds];
          CGPoint point = [recognizer locationInView:glView];
          point.y = bounds.size.height - point.y;
          return GLKVector3Make((point.x * glView.contentScaleFactor - total_translation.x)/total_scale,
                                         (point.y * glView.contentScaleFactor - total_translation.y)/total_scale, 0);
      }
      - (void)respondToPinchGesture:(UIPinchGestureRecognizer *)recognizer{
          if (recognizer.state == UIGestureRecognizerStateBegan) {
              lastScale = 1.0;
          }
      
          [self get_touch_point_on_view:recognizer];
      
          if (fabs(recognizer.scale - lastScale) > 0.01){
      
              GLfloat scale = 1.0 - (lastScale - recognizer.scale);
              lastScale = recognizer.scale;
              total_scale *= scale;
      
              path.transform = GLKMatrix4TranslateWithVector3(path.transform, centroid);
              path.transform = GLKMatrix4Scale(path.transform, scale, scale, 0);
              path.transform = GLKMatrix4TranslateWithVector3(path.transform, GLKVector3Negate(centroid));
              total_translation = [self get_total_translation];
      
          }
      }
      

      这是显而易见的。很明显我可以做变焦。问题在于随后的夹击的漂移。你真的应该仔细阅读这个问题,这是显而易见的。很明显我可以做变焦。问题在于随后的夹击的漂移。你真的应该仔细阅读这个问题。