2014-01-02 4 views
3

Я работаю над графическим приложением, где пользователь может рисовать/писать пальцем или стилусом. Для этого в моей заявке был указан код от https://github.com/yusenhan/Smooth-Line-View.Вычислить контрольные точки при рисовании в iOS

Проблема, с которой я столкнулся, заключается в том, что письмо иногда, когда вы пишете очень близко, не очень гладко.

Так что я думаю, что я ошибаюсь в получении контрольной точки.

Ниже мой код

// Найти серединой

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.    
} 

По мне, точки, которые я передаю в CGContextAddQuadCurveToPoint может быть изменен, но как настроить это, я не получение. Я читал документы, чтобы найти контрольные точки для Bezier Curve, но я не понимаю.

Так что друзья, пожалуйста, помогите мне понять, куда я иду не так.

+1

Вы можете использовать сплайн Catmull-Rom вместо кривой bezeire, чтобы иметь гладкую кривую http://stackoverflow.com/questions/8702696/drawing-smooth-curves-methods-needed – amar

+0

@amar, можете ли вы предложить, как этот код может быть изменен – Ranjit

+0

ranjit проверить этот URL http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-advanced-freehand-drawing-techniques/ может это поможет вам и даст вам возможность сделать эффективные кривые с использованием кривой Безье –

ответ

3

Проблема, с которой вы сталкиваетесь, заключается в том, что, когда пользователь медленно тащит палец, контрольные точки, которые вы получаете, слишком далеки друг от друга, поэтому вы получаете большие сегменты линии, а не небольшие изменения в пикселях, что даст вам гладкий вид кривая.

Вычисление контрольных точек Безье из существующей кривой действительно сложно, так как контрольные точки не находятся на линии.

Лучше использовать кривые Catmull-Rom. В «Erica Sadun» есть отличный «Рецепт» ВЫДАЮЩАЯСЯ книга «Продвинутая книга для разработчиков iOS 6», которая включает рабочий код сглаживания на основе сплаймов Catmull-Rom. Сплавы Catmull-Rom используют контрольные точки, которые находятся на кривой.

Я настоятельно рекомендую купить эту книгу. Пример кода для Рецепта 4.3 сделает именно то, что вы хотите.

+0

Здесь, здесь. Книги Эрики Садун являются удивительными. Деньги хорошо потрачены. – uchuugaka

+0

Здравствуйте, @ Duncan C Спасибо за ваш ответ. Поэтому вы предлагаете мне использовать сплайны Catmull-Rom, а затем находить контрольные пинты и передавать их в функцию quadCurve, поэтому все остается таким же, только мне нужно рассчитать контрольные точки и пройти. Это то, что вы имели в виду, или это что-то другое. – Ranjit

+0

Нет. Катки Catmull-Rom имеют контрольные точки вдоль кривой. Вы использовали бы сплайны Catmull-Rom, чтобы разбить свою кривую на более прямые сегменты линии и не использовать кубические или квадратичные кривые Безье. –

Смежные вопросы