Pinch scaling, but not using conversion methods

I am trying to enlarge a drawing to a context based on infringement. This works fine, but will always increase from the beginning (top left). This does not give the pleasant effect that you get in other applications and is really annoying. The old scaling method is as follows:

- (IBAction)handlePinchGesture:(UIGestureRecognizer *)sender { UIPinchGestureRecognizer *pinch = (UIPinchGestureRecognizer *)sender; if ([pinch scale] > zoomLevel + MAX_ZOOM_PER_CALL) { [pinch setScale: zoomLevel + MAX_ZOOM_PER_CALL]; } if ([pinch scale] < zoomLevel - MAX_ZOOM_PER_CALL) { [pinch setScale:zoomLevel - MAX_ZOOM_PER_CALL]; } float prevZoomLevel = zoomLevel; CGFloat factor = [pinch scale]; zoomLevel = factor; if (zoomLevel < MIN_ZOOM_LEVEL) { zoomLevel = MIN_ZOOM_LEVEL; } if (zoomLevel > MAX_ZOOM_LEVEL) { zoomLevel = MAX_ZOOM_LEVEL; } //The next piece of code is added here [self setNeedsDisplay]; } 

Actual scaling is done in the methods of drawing the parts that are shown in context. I was thinking about changing the origin of the screen (i.e. the relative origin of the objects that need to be drawn) so that it mimics this. But it does not work at all, this is what I have right now:

 float dZoomLevel = zoomLevel - prevZoomLevel; if (dZoomLevel != 0) { CGPoint touchLocation = [pinch locationInView:self]; CGPoint zoomedTouchLocation = CGPointMake(touchLocation.x * prevZoomLevel, touchLocation.y * prevZoomLevel); CGPoint newLocation = CGPointMake(touchLocation.x * zoomLevel, touchLocation.y * zoomLevel); float dX = ( newLocation.x - zoomedTouchLocation.x ); float dY = ( newLocation.y - zoomedTouchLocation.y ); _originX += roundf(dX); _originY += roundf(dY); } 

The origin is taken from xml (the smallest x and y of all elements). Usually it will be between 12000 and 20000, but theoretically it can be between 0 and 100000.

I'm not sure if I am clear, but if you need any information or I don’t understand something, just ask me and I will try to answer as soon as possible. Thanks in advance!

+1
source share
1 answer

I myself found the answer. The way I need to scale my case is scaling from the point of touch. Therefore, when the x and y coordinates increase, do the following:

 x -= pinchLocation.x; y -= pinchLocation.y; x *= zoomLevel; y *= zoomLevel; x += pinchLocation.x; y += pinchLocation.y; 

or briefly:

 x = (x - pinchLocation.x) * zoomLocation + pinchLocation.x; y = (y - pinchLocation.y) * zoomLocation + pinchLocation.y; 

now x and y are in the right place!

0
source

Source: https://habr.com/ru/post/1439993/


All Articles