适用于UILongPressGestureRecognizer的更精确的CGPoint [英] More Precise CGPoint for UILongPressGestureRecognizer

查看:73
本文介绍了适用于UILongPressGestureRecognizer的更精确的CGPoint的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的UILongPressGestureRecognizer可以很好地工作,但是我得到的数据对于我的用例来说不够精确。我认为我得到的CGPoint值是四舍五入的。

I am using a UILongPressGestureRecognizer which works perfectly but the data I get is not precise enough for my use case. CGPoints that I get are rounded off I think.

我得到的示例点:100.5、103.0等。小数部分是.5或.0。有没有办法获得更精确的分数?我希望像.xxxx这样的东西在'100.8745'中,但是.xx可以。

Example points that I get: 100.5, 103.0 etc. The decimal part is either .5 or .0 . Is there a way to get more precise points? I was hoping for something like .xxxx as in '100.8745' but .xx would do to.

我需要这个的原因是因为我有一个圆形UIBezierPath,我想要将拖动手势限制为仅该圆形路径。该项目只能沿该圆的圆周拖动。为此,我使用半径计算了圆边界上的720个点。现在这些点是.xxxx数字。如果我将它们四舍五入,则在圆的中间部分周围的拖动不会那么平滑,这是因为在中间部分(赤道),x坐标上的点非常靠近。因此,当我四舍五入y坐标时,我损失了很多点,因此失去了不太平滑的拖动动作。

The reason I need this is because I have a circular UIBezierPath, I want to restrict a drag gesture to only that circular path. The item should only be draggable along the circumference of this circle. To do this I calculated 720 points on the circle's boundary using it's radius. Now these points are .xxxx numbers. If I round them off, the drag is not as smooth around the middle section of the circle.This is because in the middle section, the equator, the points on the x-coordinate are very close together. So when I rounded of the y-coordinate, I lost a lot of points and hence the "not so smooth" drag action.

这是我计算点的方式

for (CGFloat i = -154;i<154;i++) {

    CGPoint point = [self pointAroundCircumferenceFromCenter:center forX:i];
    [bezierPoints addObject:[NSValue valueWithCGPoint:point]];
    i = i - .5;
}

- (CGPoint)pointAroundCircumferenceFromCenter:(CGPoint)center forX:(CGFloat)x
{
CGFloat radius = 154;
CGPoint upperPoint = CGPointZero;
CGPoint lowerPoint = CGPointZero;

//theta used to be the x variable. was first calculating points using the angle
/* point.x = center.x + radius * cosf(theta);
point.y = center.y + radius * sinf(theta);*/

CGFloat y = (radius*radius) - (theta*theta);
upperPoint.x = x+156;
upperPoint.y = 230-sqrtf(y);
lowerPoint.x = x+156;
lowerPoint.y = sqrtf(y)+230;

NSLog(@"x = %f, y = %f",upperPoint.x, upperPoint.y);
[lowerPoints addObject:[NSValue valueWithCGPoint:lowerPoint]];
[upperPoints addObject:[NSValue valueWithCGPoint:upperPoint]];
return upperPoint;
}

我知道代码很奇怪,我为什么要将点添加到数组中并返回一个点。

I know the code is weird I mean why would I add the points into arrays and return one point back.

这是我限制运动的方式

-(void)handleLongPress:(UILongPressGestureRecognizer *)recognizer{
    CGPoint finalpoint;
    CGPoint initialpoint;
    CGFloat y;
    CGFloat x;
    CGPoint tempPoint;
    if(recognizer.state == UIGestureRecognizerStateBegan){
        initialpoint = [recognizer locationInView:self.view];
        CGRect rect = CGRectMake(initialpoint.x, initialpoint.y, 40, 40);
        self.hourHand.frame = rect;
        self.hourHand.center = initialpoint;
        NSLog(@"Long Press Activated at %f,%f",initialpoint.x, initialpoint.y );
    }
    else if (recognizer.state == UIGestureRecognizerStateChanged){
        CGPoint currentPoint = [recognizer locationInView:self.view];
        x = currentPoint.x-initialpoint.x;
        y = currentPoint.y-initialpoint.y;
        tempPoint = CGPointMake( currentPoint.x,  currentPoint.y);
        NSLog(@"temp point ::%f, %f", tempPoint.x, tempPoint.y);
        tempPoint = [self givePointOnCircleForPoint:tempPoint];
        self.hourHand.center = tempPoint;
     }
    else if (recognizer.state == UIGestureRecognizerStateEnded){
    //   finalpoint = [recognizer locationInView:self.view];
        CGRect rect = CGRectMake(tempPoint.x, tempPoint.y, 20, 20);
        self.hourHand.frame = rect;
        self.hourHand.center = tempPoint;
        NSLog(@"Long Press DeActivated at %f,%f",tempPoint.x, tempPoint.y );
    }
}

-(CGPoint)givePointOnCircleForPoint:(CGPoint) point{
CGPoint resultingPoint;
for (NSValue *pointValue in allPoints){
    CGPoint pointFromArray = [pointValue CGPointValue];
    if (point.x == pointFromArray.x) {
       // if(point.y > 230.0){
            resultingPoint = pointFromArray;
            break;
       // }
    }
}

基本上, 接触点的x坐标,并通过将其与我之前计算的点数组进行比较来返回y。

Basically, I taking the x-coordinate of the "touched point" and returning the y by comparing it to the array of points I calculated earlier.

当前,此代码仅适用于半圈因为每个x都有2个y值,因为它是一个圆,请忽略它,因为我认为这很容易处理。

Currently this code works for half a circle only because, each x has 2 y values because it's a circle, Ignore this because I think this can be easily dealt with.

在图片中,白色圆圈是原始圆圈,黑色圆圈是我从代码中获取的要点+对其进行格式化以消除精度以适应我得到的输入。如果您环顾赤道(红色突出显示的部分),您将看到下一个点之间的缝隙。这个差距是我的问题。

In the picture, the white circle is the original circle, the black circle is the circle of the points I have from the code+formatting it to remove precision to fit the input I get. If you look around the equator(red highlighted part) you will see a gap between the next points. This gap is my problem.

推荐答案

要回答您的原始问题:在配备Retina显示屏的设备上,一个像素为0.5点,因此 0.5 是使用此硬件可获得的最佳分辨率。
(在非视网膜设备上,1像素== 1点。)

To answer your original question: On a device with a Retina display, one pixel is 0.5 points, so 0.5 is the best resolution you can get on this hardware. (On non-Retina devices, 1 pixel == 1 point.)

但是在我看来,您根本不需要该点数组。如果正确理解了问题,则可以使用以下代码将
限制(或投影)到圆的圆周上的任意点:

But it seems to me that you don't need that points array at all. If understand the problem correctly, you can use the following code to "restrict" (or "project") an arbitrary point to the circumference of the circle:

CGPoint center = ...; // Center of the circle
CGFloat radius = ...; // Radius of the circle
CGPoint point = ...;  // The touched point
CGPoint resultingPoint; // Resulting point on the circumference

// Distance from center to point:
CGFloat dist = hypot(point.x - center.x, point.y - center.y);
if (dist == 0) {
    // The touched point is the circle center.
    // Choose any point on the circumference:
    resultingPoint = CGPointMake(center.x + radius, center.y);
} else {
    // Project point to circle circumference:
    resultingPoint = CGPointMake(center.x + (point.x - center.x)*radius/dist,
                     center.y + (point.y - center.y)*radius/dist);
}

这篇关于适用于UILongPressGestureRecognizer的更精确的CGPoint的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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