Skip to content

Instantly share code, notes, and snippets.

@erkanyildiz
Last active June 7, 2017 18:25
Show Gist options
  • Save erkanyildiz/ae66289240002b6c23b31be09c6382d4 to your computer and use it in GitHub Desktop.
Save erkanyildiz/ae66289240002b6c23b31be09c6382d4 to your computer and use it in GitHub Desktop.
Colorful Hilbert Curves from Level 1 to Level 5
// erkanyildiz
// 20170608-0308+0900
//
// EYHilbertCurveView.h
#import <UIKit/UIKit.h>
@interface EYHilbertCurveView : UIView
- (void)drawWithLevel:(NSInteger)level;
- (void)drawWithLevel:(NSInteger)level color:(UIColor *)color lineWidth:(CGFloat)lineWidth;
- (void)drawWithLevel:(NSInteger)level color:(UIColor *)color lineWidth:(CGFloat)lineWidth unitSize:(CGFloat)unitSize animationDuration:(CGFloat)animationDuration;
@end
// erkanyildiz
// 20170608-0308+0900
//
// EYHilbertCurveView.m
#import "EYHilbertCurveView.h"
@interface EYHilbertCurveView ()
{
CGFloat size;
CGPoint current;
UIBezierPath* path;
}
@end
@implementation EYHilbertCurveView
- (void)drawWithLevel:(NSInteger)level
{
[self drawWithLevel:level color:nil lineWidth:1 unitSize:0.0 animationDuration:0.0];
}
- (void)drawWithLevel:(NSInteger)level color:(UIColor *)color lineWidth:(CGFloat)lineWidth
{
[self drawWithLevel:level color:color lineWidth:lineWidth unitSize:0.0 animationDuration:0.0];
}
- (void)drawWithLevel:(NSInteger)level color:(UIColor *)color lineWidth:(CGFloat)lineWidth unitSize:(CGFloat)unitSize animationDuration:(CGFloat)animationDuration
{
if (unitSize == 0)
{
CGFloat minSize = MIN(self.bounds.size.width, self.bounds.size.height);
size = minSize / powf(2.0, level + 1);
current = (CGPoint){0.5 * size, 0.5 * size};
if(minSize == self.bounds.size.width)
current.y += (self.bounds.size.height - minSize) * 0.5;
else
current.x += (self.bounds.size.width - minSize) * 0.5;
}
else
{
size = unitSize;
current = CGPointZero;
}
path = UIBezierPath.bezierPath;
[path moveToPoint:current];
[self hilbert:level x:0 y:1];
CAShapeLayer* layer = CAShapeLayer.layer;
layer.path = path.CGPath;
layer.fillColor = UIColor.clearColor.CGColor;
layer.strokeColor = (color ? color : UIColor.blackColor).CGColor;
layer.lineWidth = (lineWidth != 0.0) ? lineWidth : 1.0;
layer.lineCap = kCALineCapSquare;
[self.layer addSublayer:layer];
if(animationDuration != 0.0)
{
CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
anim.duration = animationDuration;
anim.repeatCount = 1.0;
anim.fillMode = kCAFillModeForwards;
anim.removedOnCompletion = NO;
anim.fromValue = @(0.0);
anim.toValue = @(1.0);
[layer addAnimation:anim forKey:@""];
}
}
-(void)hilbert:(NSInteger)level x:(NSInteger)x y:(NSInteger)y
{
if(level < 0)
return;
[self hilbert:level-1 x:y y:x];
[self path:x y:y];
[self hilbert:level-1 x:x y:y];
[self path:y y:x];
[self hilbert:level-1 x:x y:y];
[self path:-x y:-y];
[self hilbert:level-1 x:-y y:-x];
}
-(void)path:(NSInteger)x y:(NSInteger)y
{
[path addLineToPoint:current];
current.x += (x * size);
current.y += (y * size);
[path addLineToPoint:current];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment