3

我正在接近解决这个问题,但有一部分给我带来了麻烦。我试图模仿一个标尺对象,用户可以在画布上旋转、缩放和放置它,然后沿着边缘追踪以在画布上做一个标记。我遇到的问题是无论用户的手指走到哪里,都可以在线获得下一个点。我可以将法线从该点追溯到我拥有的边缘的一个小的透明视图,但是由于混叠(或其他原因),线在以纯直线以外的任何角度(0、90、180)绘制时会抽搐, 270)。我也试过写一个像 CGRectContainsPoint 这样的函数,除了它需要一个任意旋转的矩形,但我没有成功。

下面是根据用户的触摸计算点的代码:

- (CGPoint)perpendicularPointFromPoint:(CGPoint)point
{
    CGPoint testPoint1 = point;
    CGPoint testPoint2 = testPoint1;
    CGPoint pointToUse = CGPointZero;

    //Get the right angle to the current rotation, and make 
    //a unit vector in that direction
    CGFloat rightAngle = mCurRotation + M_PI_2;
    CGFloat xInc = cosf(rightAngle);
    CGFloat yInc = sinf(rightAngle);

    //Check both "forward" and "backward"
    int counter = 0;
    while(pointToUse.x == 0)
    {
        testPoint1.x += xInc;
        testPoint1.y += yInc;
        testPoint2.x -= xInc;
        testPoint2.y -= yInc;

        //mLineOutline is a small view on top of the ruler (transparent)
        if([self.superview hitTest:testPoint1 withEvent:nil] == mLineOutline)
        {
            pointToUse = testPoint1;
        }
        else if([self.superview hitTest:testPoint2 withEvent:nil] == mLineOutline)
        {
            pointToUse = testPoint2;
        }
        else if(counter++ > 1000) //Neither ray intersects the ruler
            pointToUse.x = -1.f;
    }

    return CGPointMake(roundf(pointToUse.x), roundf(pointToUse.y));
}

但是,由于某种原因,线条在我绘制时会抖动(上下只有几个像素,但非常明显)。我能做些什么来对抗这个?另外,有没有更尴尬的方法?

4

1 回答 1

3

Josh Caswell 的评论给了我一个想法。在本文中,它表示子节点中的坐标存储在本地空间中。我以前知道这一点,但不知何故,这意味着无论您如何旋转视图,视图始终朝上。它仅根据其在世界空间(或父空间)中的坐标进行旋转。

因此,我不是在超级视图上获取接触点然后进行计算,而是在子视图上获取接触点。将它的 y 值更改为 -2 或我想要的任何值(就在标尺上方,因为它总是在本地空间中面朝上),然后[self convertPoint:point toView:self.superview];让视图层次结构处理困难的部分。

于 2012-07-18T06:10:56.833 回答