沿着标尺对象的边缘绘制

时间:2012-07-18 04:45:31

标签: objective-c ios algorithm trigonometry

我已经接近解决这个问题,但有一部分给我带来了麻烦。我试图模仿用户可以旋转,缩放和放置在画布上的标尺对象,然后沿着边缘进行跟踪以在画布上做标记。我遇到的问题是无论用户的手指在哪里,都会在线上获得下一个点。我可以沿着我所拥有的边缘将法线从点返回到一个小的透明视图,但由于锯齿(或其他),线条在以纯直线(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));
}

然而,由于任何原因,线条在我绘制时抖动(上下几个像素,但非常明显)。我该怎么做才能打击这个?还有,不那么尴尬吗?

1 个答案:

答案 0 :(得分:3)

Josh Caswell的评论给了我一个想法。在this文章中,它表明子项中的坐标存储在本地空间中。我之前知道这一点,但它不知何故让我不知道这意味着无论你如何旋转它,视图总是面朝上。它仅根据其在世界空间(或父空间)中的坐标进行旋转。

因此,不是在superview上获取触摸点然后计算,而是在子视图上获得触摸点。将其y值更改为-2或我想要的任何值(在标尺上方,因为它始终面向局部空间),然后[self convertPoint:point toView:self.superview];让视图层次结构处理困难部分。