Objective-C中的贝塞尔曲线算法需要调整 [英] Bezier curve algorithm in objective-c needs a tweak

查看:75
本文介绍了Objective-C中的贝塞尔曲线算法需要调整的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问了一个简短的问题 Objective-c中的贝塞尔曲线算法似乎解决了我的问题.我问这个新问题是因为我认为它足够不同,而不是重新提出旧问题.

I asked a quick question Bezier curve algorithm in objective-c that seemed to solve my issues. I'm asking this new question as I think its different enough rather than repurposing the old one.

我的Bezier曲线算法似乎有效,但是与内置的NSBezierPath版本相比,存在一些主要问题.似乎某些类型的曲线非常扭曲.

I have what seems like a working Bezier Curve algorithm but when compared to built in NSBezierPath version there are some major issues. It looks as though certain types of curves are very much distorted.

从上图可以看到差异,红线是我的功能,浅色是内置的版本.我不是期望和检查匹配,一个像素接一个像素,但是如您所见,红线有时会偏离路线.

You can see from the above image the differences, the red line is my function and the lighter color is the built in version. I am not expecting and exat match, pixel for pixel, but as you can see the red lines go way off course at times.

我列出的第一个方法就是所谓的2个Bezier方法,它表明两个版本的输入都相同.

The first method I'm listing is what calls the 2 Bezier methods, it shows that the inputs are the same to both versions.

- (void)MakeBezier
{
    int x1 = [self getMegaNumber:2];
    int y1 = self.frame.size.height - [self getMegaNumber:2];
    int x2 = [self getMegaNumber:2];
    int y2 = self.frame.size.height - [self getMegaNumber:2];
    int x3 = [self getMegaNumber:2];
    int y3 = self.frame.size.height - [self getMegaNumber:2];
    int x4 = [self getMegaNumber:2];
    int y4 = self.frame.size.height - [self getMegaNumber:2];
    int cnt = [self getMegaNumber:2]; 

    NSBezierPath *bezierPath = [[NSBezierPath alloc] init];
    [bezierPath setLineWidth:1.0f];
    [bezierPath moveToPoint:NSMakePoint(x1, y1)];
    [bezierPath curveToPoint:NSMakePoint(x4, y4) controlPoint1:NSMakePoint(x2, y2) controlPoint2:NSMakePoint(x3, y3)];

    // Draw path to image with build in NSBezierPath
    [self drawPath:bezierPath fill:NO];

    // Draw path with custom algorithm    
    [self drawBezierFrom:NSMakePoint(x1, y1) to:NSMakePoint(x4, y4) controlA:NSMakePoint(x2, y2) controlB:NSMakePoint(x3, y3) sections:cnt color:4];
}

下一个方法是自定义算法,该算法用于在样本图像中绘制红线.

This next method is the custom algorithm thats used to draw the red lines in the sample image.

- (void)drawBezierFrom:(NSPoint)from to:(NSPoint)to controlA:(NSPoint)a controlB:(NSPoint)b sections:(NSUInteger)cnt color:(NSUInteger)color
{
    float qx, qy;
    float q1, q2, q3, q4;
    int lastx = - 1, lasty;
    int plotx, ploty;
    float t = 0.0;

    while (t <= 1)
    {
        q1 = t*t*t*-1 + t*t*3 + t*-3 + 1;
        q2 = t*t*t*3 + t*t*-6 + t*3;
        q3 = t*t*t*-3 + t*t*3;
        q4 = t*t*t;

        qx = q1*from.x + q2*a.x + q3*to.x + q4*b.x;
        qy = q1*from.y + q2*a.y + q3*to.y + q4*b.y;

        plotx = round(qx);
        ploty = round(qy);

        if (lastx != -1)
            [self drawLineFrom:NSMakePoint(lastx, lasty) to:NSMakePoint(plotx, ploty) color:color];
        else
            [self drawLineFrom:NSMakePoint(from.x, from.y) to:NSMakePoint(plotx, ploty) color:color];

        lastx = plotx;
        lasty = ploty;
        t = t + (1.0/(cnt + 0.0f));
    }
    [self drawLineFrom:NSMakePoint(lastx, lasty) to:NSMakePoint(to.x, to.y) color:color];
}

所以我的问题是;定制算法是可行的方法还是只是缺少特定种类的线的边缘情况?无论哪种方式,都非常感谢您对修复算法的任何帮助.重申一下,我不是在寻找像素完美匹配的对象,但我希望曲线能够对齐.

So my question is; is the custom algorithm way off or is it just missing an edge case for specific kinds of lines, or something else? Either way any help in fixing the algorithm would be very appreciated. To reiterate, I am not looking for a pixel perfect match, but I am expecting the curves to lineup together.

推荐答案

查看Wikipedia页面

Looking at the Wikipedia page here it seems that your coefficients for the q1-q4 are incorrect. Shouldn't they be symmetric?

似乎还应该交换to.x和b.x:

It also seems that to.x and b.x should be swapped:

qx = q1*from.x + q2*a.x + q3*to.x + q4*b.x;
qy = ...

这篇关于Objective-C中的贝塞尔曲线算法需要调整的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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