在iOS中绘图时计算controlPoints [英] Calculate controlPoints while drawing in iOS

查看:106
本文介绍了在iOS中绘图时计算controlPoints的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用绘图应用程序,用户可以用手指或手写笔绘图/书写。为此,我在我的应用程序中引用了来自 https://github.com/yusenhan/Smooth-Line-View 的代码。

I am working on a drawing app, where user can draw/write with his finger or stylus. For this I have referred code from https://github.com/yusenhan/Smooth-Line-View, in my application.

我面临的问题是,有时写作时写得非常顺利。

The problem which I am facing is that, the writing sometimes when you write very closely is not very smooth.

所以我想,我正在制作一些获得控制点时出错。

So I think, I am making some mistake in getting the control point.

以下是我的代码

//找到中点

CGPoint midPoint(CGPoint p1, CGPoint p2)
{
    return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}

#pragma mark Gesture handle
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [touches anyObject];
    //LocationInView returns the current location of the reciever in coordinate system of the given View.
    m_previousPoint1 = [touch locationInView:self];
    m_previousPoint2 = [touch locationInView:self];
    m_currentPoint   = [touch locationInView:self];    

    [self touchesMoved:touches withEvent:event];}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{          
    //AnyObject:- Returns one of the objects in the set, or nil if the set contains no objects.
    UITouch *touch  = [touches anyObject];

    m_previousPoint2  = m_previousPoint1;
    m_previousPoint1  = m_currentPoint;
    m_currentPoint    = [touch locationInView:self];

    if(m_drawStep != ERASE)
    {
        m_drawStep = DRAW;
        m_drawing  = TRUE;        
    }    
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);//creates a graphics context suitable for use as an image(size of the image,opquae,scale, if scale = 0.0, means platform will take care of scaling)
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    m_curImage = UIGraphicsGetImageFromCurrentImageContext();// to turn the context into a UIImage    
    UIGraphicsEndImageContext();

 }

- (void)drawRect:(CGRect)rect
{
   CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2);
   CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);            

   [m_curImage drawAtPoint:CGPointMake(0, 0)];

   CGContextRef context = UIGraphicsGetCurrentContext();//Get a reference to current context(The context to draw)
   [self.layer renderInContext:context];
   //Simply keep referring to this context in below functions with proper arguments.
   CGContextMoveToPoint(context, mid1.x, mid1.y);//Position the current point
   CGContextAddQuadCurveToPoint(context, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y);     
   CGContextSetLineCap(context, kCGLineCapRound);
   CGContextSetBlendMode(context, kCGBlendModeNormal);
   CGContextSetLineJoin(context, kCGLineJoinRound);
   CGContextSetLineWidth(context, self.lineWidth);
   CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
   CGContextSetShouldAntialias(context, YES);
   CGContextSetAllowsAntialiasing(context, YES);
   CGContextSetAlpha(context, self.lineAlpha);           
   CGContextSetFlatness(context, 0.6);
   CGContextStrokePath(context);//paints(fills) the line along the current path.            
}

根据我的说法,我在<$ c $中传递的点数c> CGContextAddQuadCurveToPoint 可以调整,但如何调整,我没有得到。我阅读了文档以找到 Bezier Curve 的控制点,但我不理解。

According to me, the points which I am passing in the CGContextAddQuadCurveToPoint can be tweaked, but how to tweak that, I am not getting. I read docs to find control points for Bezier Curve, but I am not understanding.

所以朋友们,请帮忙我明白了我哪里出错了。

So friends, please help me out understanding where I am going wrong.

推荐答案

你遇到的问题是,当用户慢慢地拉动他的手指时,你得到的控制点相距太远,所以你会获得较大的线段,而不是小的像素变化,这会给你一个平滑的曲线。

The problem you're having is that when the user drags his finger slowly, the control points you get are too far apart, so you get large line segments rather than the small pixel changes that would give you a smooth-looking curve.

计算Bezier控制现有曲线的点非常难,因为控制点不在线上。

Calcualting Bezier control points from an existing curve is really hard, since the control points are not on the line.

最好使用Catmull-Rom曲线。 Erica Sadun的 OUTSTANDING 书籍高级iOS 6开发者手册中有一个很好的食谱,其中包括基于Catmull-Rom样条平滑的工作代码。 Catmull-Rom样条曲线使用曲线上的控制点。

Better to use Catmull-Rom curves. There is an excellent "Recipe" in Erica Sadun's OUTSTANDING book "The Advanced iOS 6 Developer's Cookbook" that includes working code on Catmull-Rom spline based smoothing. Catmull-Rom splines use control points that are on the curve.

我强烈推荐购买那本书。食谱4.3的示例代码将完全符合您的要求。

I highly recommend buying that book. The sample code for Recipe 4.3 will do exactly what you want.

这篇关于在iOS中绘图时计算controlPoints的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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