SORU
2 Ocak 2012, PAZARTESİ


Çizim Yumuşak Eğriler - Yöntemler Gerekli

Herkes önce istedi, nasıl bir iOS taşırken app çizim noktaları bir dizi yumuşak mı? UİBezierpaths denedim ama ben sadece puan 1,2,3,4 - 2,3,4,5 vardiya onlar kesiştiği uçları sivri. Ayraç eğrileri ve tüm diğer türleri duymadım. İPhone programlama için oldukça yeni duyuyorum ve kuvars çizim uygulamam bu program için nasıl anlamıyorum. Sağlam bir örnek büyük mutluluk duyacağız, hafta etrafında geçirdim ve hiç iOS bu görev için kod bulmak için görünmüyor olabilir. Mesajların çoğu benim için bir şey yapar eğri uydurma ile ilgili java simulasyonu veya sayfalar Vikipedi bir bağlantı. Ayrıca openGL ES geçmek istemiyorum. Sonunda birisi kod dolaşan bu soruya cevap verebilir umarım.

Teşekkür Ederim, Yeni Yılınız Kutlu Olsun!!!

.....................................................................................................................................................................

Bu kavşakta kenarları/// bıraktı UİBezierPath için benim kod

AŞAĞIDA BİR CEVAP İÇİN GÜNCELLENDİ

#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]
#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]

- (UIBezierPath*)smoothedPathWithGranularity:(NSInteger)granularity
{
    NSMutableArray *points = [(NSMutableArray*)[self pointsOrdered] mutableCopy];

    if (points.count < 4) return [self bezierPath];

    // Add control points to make the math make sense
    [points insertObject:[points objectAtIndex:0] atIndex:0];
    [points addObject:[points lastObject]];

    UIBezierPath *smoothedPath = [self bezierPath];
    [smoothedPath removeAllPoints];

    [smoothedPath moveToPoint:POINT(0)];

    for (NSUInteger index = 1; index < points.count - 2; index  )
    {
        CGPoint p0 = POINT(index - 1);
        CGPoint p1 = POINT(index);
        CGPoint p2 = POINT(index   1);
        CGPoint p3 = POINT(index   2);

        // now add n points starting at p1   dx/dy up until p2 using Catmull-Rom splines
        for (int i = 1; i < granularity; i  )
        {
            float t = (float) i * (1.0f / (float) granularity);
            float tt = t * t;
            float ttt = tt * t;

            CGPoint pi; // intermediate point
            pi.x = 0.5 * (2*p1.x (p2.x-p0.x)*t   (2*p0.x-5*p1.x 4*p2.x-p3.x)*tt   (3*p1.x-p0.x-3*p2.x p3.x)*ttt);
            pi.y = 0.5 * (2*p1.y (p2.y-p0.y)*t   (2*p0.y-5*p1.y 4*p2.y-p3.y)*tt   (3*p1.y-p0.y-3*p2.y p3.y)*ttt);
            [smoothedPath addLineToPoint:pi];
        }

        // Now add p2
        [smoothedPath addLineToPoint:p2];
    }

    // finish by adding the last point
    [smoothedPath addLineToPoint:POINT(points.count - 1)];

    return smoothedPath;
}
- (PVPoint *)pointAppendingCGPoint:(CGPoint)CGPoint
{
    PVPoint *newPoint = [[PVPoint alloc] initInsertingIntoManagedObjectContext:[self managedObjectContext]];
    [newPoint setCGPoint:CGPoint];
    [newPoint setOrder:[NSNumber numberWithUnsignedInteger:[[self points] count]]];
    [[self mutableSetValueForKey:@"points"] addObject:newPoint];
    [(NSMutableArray *)[self pointsOrdered] addObject:newPoint];
    [[self bezierPath] addLineToPoint:CGPoint];
    return [newPoint autorelease];

    if ([self bezierPath] && [pointsOrdered count] > 3)
    {
        PVPoint *control1 = [pointsOrdered objectAtIndex:[pointsOrdered count] - 2];
        PVPoint *control2 = [pointsOrdered objectAtIndex:[pointsOrdered count] - 1];
        [bezierPath moveToPoint:[[pointsOrdered objectAtIndex:[pointsOrdered count] - 3] CGPoint]];
        [[self bezierPath] addCurveToPoint:CGPoint controlPoint1:[control1 CGPoint] controlPoint2:[control2 CGPoint]];

    }

}

- (BOOL)isComplete { return [[self points] count] > 1; }

- (UIBezierPath *)bezierPath
{
    if (!bezierPath)
    {
        bezierPath = [UIBezierPath bezierPath];
        for (NSUInteger p = 0; p < [[self points] count]; p  )
        {
            if (!p) [bezierPath moveToPoint:[(PVPoint *)[[self pointsOrdered] objectAtIndex:p] CGPoint]];
            else [bezierPath addLineToPoint:[(PVPoint *)[[self pointsOrdered] objectAtIndex:p] CGPoint]];
        }
        [bezierPath retain];
    }

    return bezierPath;
}

- (CGPathRef)CGPath
{
    return [[self bezierPath] CGPath];
}

CEVAP
4 Ocak 2012, ÇARŞAMBA


Ben sadece üzerinde çalıştığım bir projede benzer bir şey uyguladı. Benim çözüm Bezier eğrisi yerine Catmull-Rom bir ayraç kullanın. Bu set bir puan yerine bir bezier eğri '' puan. sonra çok düzgün bir eğri sağlar

// Based on code from Erica Sadun

#import "UIBezierPath Smoothing.h"

void getPointsFromBezier(void *info, const CGPathElement *element);
NSArray *pointsFromBezierPath(UIBezierPath *bpath);


#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]
#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]

@implementation UIBezierPath (Smoothing)

// Get points from Bezier Curve
void getPointsFromBezier(void *info, const CGPathElement *element) 
{
    NSMutableArray *bezierPoints = (__bridge NSMutableArray *)info;    

    // Retrieve the path element type and its points
    CGPathElementType type = element->type;
    CGPoint *points = element->points;

    // Add the points if they're available (per type)
    if (type != kCGPathElementCloseSubpath)
    {
        [bezierPoints addObject:VALUE(0)];
        if ((type != kCGPathElementAddLineToPoint) &&
            (type != kCGPathElementMoveToPoint))
            [bezierPoints addObject:VALUE(1)];
    }    
    if (type == kCGPathElementAddCurveToPoint)
        [bezierPoints addObject:VALUE(2)];
}

NSArray *pointsFromBezierPath(UIBezierPath *bpath)
{
    NSMutableArray *points = [NSMutableArray array];
    CGPathApply(bpath.CGPath, (__bridge void *)points, getPointsFromBezier);
    return points;
}

- (UIBezierPath*)smoothedPathWithGranularity:(NSInteger)granularity;
{
    NSMutableArray *points = [pointsFromBezierPath(self) mutableCopy];

    if (points.count < 4) return [self copy];

    // Add control points to make the math make sense
    [points insertObject:[points objectAtIndex:0] atIndex:0];
    [points addObject:[points lastObject]];

    UIBezierPath *smoothedPath = [self copy];
    [smoothedPath removeAllPoints];

    [smoothedPath moveToPoint:POINT(0)];

    for (NSUInteger index = 1; index < points.count - 2; index  )
    {
        CGPoint p0 = POINT(index - 1);
        CGPoint p1 = POINT(index);
        CGPoint p2 = POINT(index   1);
        CGPoint p3 = POINT(index   2);

        // now add n points starting at p1   dx/dy up until p2 using Catmull-Rom splines
        for (int i = 1; i < granularity; i  )
        {
            float t = (float) i * (1.0f / (float) granularity);
            float tt = t * t;
            float ttt = tt * t;

            CGPoint pi; // intermediate point
            pi.x = 0.5 * (2*p1.x (p2.x-p0.x)*t   (2*p0.x-5*p1.x 4*p2.x-p3.x)*tt   (3*p1.x-p0.x-3*p2.x p3.x)*ttt);
            pi.y = 0.5 * (2*p1.y (p2.y-p0.y)*t   (2*p0.y-5*p1.y 4*p2.y-p3.y)*tt   (3*p1.y-p0.y-3*p2.y p3.y)*ttt);
            [smoothedPath addLineToPoint:pi];
        }

        // Now add p2
        [smoothedPath addLineToPoint:p2];
    }

    // finish by adding the last point
    [smoothedPath addLineToPoint:POINT(points.count - 1)];

    return smoothedPath;
}


@end

Catmull-Rom orijinal uygulama onun kitaplarından birinde Erica Haluk Aytekin bazı kod dayalı, hafifçe tam düzgün bir eğri için izin verecek şekilde modifiye ettim. Bu UİBezierPath bir kategori olarak uygulanır ve benim için çok iyi oldu.

The original path is in red, the smoothed path is in green.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Andrey Menshikov

    Andrey Mensh

    28 Ocak 2012
  • ColdfusTion

    ColdfusTion

    3 Aralık 2007
  • PlayStation

    PlayStation

    16 Aralık 2005