2013-06-12 64 views
2

我試圖重新創建這樣的形狀 - http://www.creativeapplications.net/wp-content/uploads/2010/09/horizon_02_1024x768.png - 在iOS上使用UIKit或CoreGraphics。帶漸變填充的Delaunay三角測量?

圖片中的圖片是用openFrameworks完成的,它在iOS上運行。不過,我希望在不使用oF的情況下構建相同的應用程序,因此我可以保留所有本地應用程序。

我假設這個形狀是通過Delaunay三角剖分創建的,我可以在Objective-C中做這個。問題是用漸變填充形狀而不是普通的UIColor!

有沒有像這樣的東西可以在本地完成在iPad上的良好性能,或者我應該只使用openFrameworks做到這一點,並將它作爲一個層帶入應用程序?

+0

我不知道爲什麼你幾次downvoted,所以這裏是一個+1,讓你再次。 – Michael

+0

感謝邁克爾,感謝它;) – Andre

回答

2

你問如何用漸變填充三角形?以下代碼就是這樣做的。爲了得到它的工作,你需要添加QuartzCore框架,

#import <QuartzCore/QuartzCore.h> 

的代碼創建一個三角形的形狀,形狀圖層,然後使用這個作爲掩模的梯度層。希望這可以幫助。

- (void)drawRect:(CGRect)rect 
{ 
    CGFloat w = self.bounds.size.width/4; 
    CGFloat h = self.bounds.size.height/4; 
    CGFloat x = w * 2; 
    CGFloat y = h; 
    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathMoveToPoint(path,NULL, x, y); 
    CGPathAddLineToPoint(path, NULL, x+w, y+2*h); 
    CGPathAddLineToPoint(path, NULL, x-w, y+2*h); 
    CGPathCloseSubpath(path); 


    CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
    shapeLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); 
    [shapeLayer setPath:path]; 

    CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
    gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); 
    gradientLayer.startPoint = CGPointMake(0.25, 1.0); 
    gradientLayer.endPoint = CGPointMake(0.75, 0.0); 
    UIColor *startColour = [UIColor redColor]; 
    UIColor *endColour = [UIColor greenColor]; 
    gradientLayer.colors = [NSArray arrayWithObjects:(id)[startColour CGColor], (id)[endColour CGColor], nil]; 

    [gradientLayer setMask:shapeLayer]; 

    [self.layer addSublayer:gradientLayer]; 

    CGPathRelease(path); 
} 
+0

嗨邁克爾。我想知道如何用不同的漸變填充填充多個三角形,考慮到它們可能都共享一個視圖/上下文 – Andre

+0

聽起來不像你,因此需要一個漸變層數組,每個三角形都是單個三角形,每個都有自己的面具?最難的部分將是制定出哪個最重要的部分。 – Michael

+0

如果這在同一個環境中是可能的,這種分層方法可能是我需要的!特別是因爲他們永遠不會重疊!將試試 – Andre

1

我打算做一個三角形,但你可以做多用重複:爲線性漸變的繪製代碼

//Create the triangle Path and clip the drawing to it 
CGContextSaveGState(context); 
CGContextBeginPath(context); 
CGContextMoveToPoint(context, self.bounds.size.width * .4, self.bounds.size.height * 1/6.); 
CGContextAddLineToPoint(context,self.bounds.size.width * .4, self.bounds.size.height * 3/6.); 
CGContextAddLineToPoint(context,self.bounds.size.width * .2, self.bounds.size.height * 3/6.); 
CGContextClosePath(context); 
CGContextClip(context); 

//Now call the linear gradient drawing function 
[self drawLinearGradient:context withRect:self.bounds startColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:.3] endColor:[UIColor colorWithRed:.5 green:.5 blue:.5 alpha:.3] startFraction:.3 stopFraction:1]; 

//And now restore so that we can clip the next triangle 
CGContextRestoreGState(context); 

現在:

- (void) drawLinearGradient: (CGContextRef) context withRect: (CGRect) rect startColor: (UIColor*) startColor endColor: (UIColor*) endColor startFraction:(float)start stopFraction:(float)stop 
{ 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGFloat locations[] = { start, stop }; 

    CGGradientRef myGradient; 
    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); 

    CGColorRef startColorRef = [startColor CGColor]; 
    CGColorRef endColorRef = [endColor CGColor]; 

    const CGFloat *components = CGColorGetComponents(startColorRef); 
    CGFloat red  = components[0]; 
    CGFloat green = components[1]; 
    CGFloat blue = components[2]; 
    CGFloat alpha = components[3]; 

    const CGFloat *components2 = CGColorGetComponents(endColorRef); 
    CGFloat red2  = components2[0]; 
    CGFloat green2 = components2[1]; 
    CGFloat blue2 = components2[2]; 
    CGFloat alpha2 = components2[3]; 

    CGFloat colors[] = 
    { 
     red, green, blue, alpha, 
     red2, green2, blue2, alpha2 
    }; 

    myGradient = CGGradientCreateWithColorComponents(rgb, colors, locations, 2); 
    CGColorSpaceRelease(rgb); 

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect)); 
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)); 

    CGContextSaveGState(context); 
    CGContextAddRect(context, rect); 
    CGContextClip(context); 
    CGContextDrawLinearGradient(context, myGradient, startPoint, endPoint, 0); 
    CGContextRestoreGState(context); 

    CGGradientRelease(myGradient); 
    CGColorSpaceRelease(colorSpace); 
} 

你可以設置這個線性漸變函數可以處理兩個以上的位置/顏色,如果你願意的話。這是非常基本的,但如果你知道每個三角形的開始和停止顏色和位置,你應該能夠使用這個代碼(沒有數百個子圖層)完成你想要的(本地繪圖)。雖然圖層可能畫得更快,但我不知道。

+0

感謝普茨。會放棄它! – Andre