Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
@erkanyildiz

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.