項(xiàng)目里有一個(gè)需求要畫一個(gè)五角星,不想用圖片,自己純計(jì)算畫出一個(gè)五角星
image.png
本文所需知識點(diǎn):
1 UIBezierPath畫線
2 高中三角函數(shù)基礎(chǔ)知識,包括正弦函數(shù),余弦函數(shù),反正弦函數(shù),反余弦函數(shù),圓的參數(shù)方程等
溫馨提示:
1 湊熱鬧的直接復(fù)制代碼,直接代碼拿走;
2 想研究的可以逐行看一下什么意思,每一行都不能去掉
3 有問題歡迎留言,不吝賜教
示意圖奉上:
image.png
廢話不多說,直接上代碼:
FiveStarView.h
#import <UIKit/UIKit.h>
@interface FiveStarView : UIView
//五角星的中心點(diǎn)坐標(biāo)
@property (nonatomic, assign) CGPoint centerPoint;
/**
五角星一個(gè)角的坐標(biāo)
*/
@property (nonatomic, assign) CGPoint aCorner;
/**
給一個(gè)范圍畫一個(gè)最大的五角星,不能超出本視圖大小
* 如果設(shè)置了這個(gè)屬性,aCorner和centerPoint將失去效果
* 如果aCorner和centerPoint也沒有設(shè)置,將會有一個(gè)默認(rèn)的位置和大小
*/
@property (nonatomic, assign) CGRect contentRect;
@end
FiveStarView.m
#import "FiveStarView.h"
@implementation FiveStarView
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
CGPoint point1 = CGPointZero;
CGPoint center = CGPointZero;
if(self.contentRect.size.height != 0){
rect = self.contentRect;
point1 = CGPointMake(rect.origin.x, rect.origin.y+rect.size.height/2.0);
center = CGPointMake(rect.origin.x+rect.size.height/2.0, rect.origin.y+rect.size.height/2.0);
} else if (self.centerPoint.x != 0 && self.centerPoint.y != 0 && self.aCorner.x != 0 && self.aCorner.y != 0){
point1 = self.aCorner;
center = self.centerPoint;
}else{//默認(rèn)
//設(shè)五角星一點(diǎn)坐標(biāo)
// CGPoint point1 = CGPointMake(10, 40);
// CGPoint point1 = CGPointMake(10, 10);
// CGPoint point1 = CGPointMake(40, 40);
// point1 = CGPointMake(rect.size.width, rect.size.height/2.0);//右側(cè)中點(diǎn)
// point1 = CGPointMake(0, rect.size.height/2.0);//左側(cè)中點(diǎn)
// point1 = CGPointMake(rect.size.width/2, rect.size.height);//底部側(cè)中點(diǎn)
point1 = CGPointMake(rect.size.width/2, 0);//頂部中點(diǎn)
center = CGPointMake(rect.size.width/2.0, rect.size.height/2.0);
}
//計(jì)算圓半徑
CGFloat r = sqrt((center.x-point1.x)*(center.x-point1.x) + (center.y-point1.y)*(center.y-point1.y));
//首先判斷五角星所在圓是否在view內(nèi)
// if([self roundIfOutRectWithCenter:center r:r rect:rect]){//超出邊界不在畫五角星
NSAssert([self roundIfOutRectWithCenter:center r:r rect:rect] == NO, @"超出邊界不再畫五角星");
// return;
// }
//角度alpha
CGFloat alpha = asin((point1.y-center.y)/r);
CGFloat alpha1 = acos((point1.x-center.x)/r);
CGPoint point2 = CGPointZero;
CGPoint point3 = CGPointZero;
CGPoint point4 = CGPointZero;
CGPoint point5 = CGPointZero;
//這個(gè)是因?yàn)閍sin函數(shù)的象限決定的,反函數(shù)出來的角度不一定是真是的角度,所以有以下處理
if (point1.x < center.x && point1.y == center.y) {
alpha = alpha1;
}else if (point1.x > center.x && point1.y == center.y){
}else if(point1.x < center.x && point1.y < center.y){
alpha = -1 *alpha + M_PI;
}else if (point1.x < center.x && point1.y > center.y){
alpha = alpha1;
}
point2 = CGPointMake(r*cos(alpha+72.0/180.0*M_PI)+center.x, r*sin(alpha+72.0/180.0*M_PI)+center.y);
point3 = CGPointMake(r*cos(alpha+72.0*2/180.0*M_PI)+center.x, r*sin(alpha+72.0*2/180.0*M_PI)+center.y);
point4 = CGPointMake(r*cos(alpha+72.0*3/180.0*M_PI)+center.x, r*sin(alpha+72.0*3/180.0*M_PI)+center.y);
point5 = CGPointMake(r*cos(alpha+72.0*4/180.0*M_PI)+center.x, r*sin(alpha+72.0*4/180.0*M_PI)+center.y);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
[path moveToPoint:point1];
[path addLineToPoint:point3];
[path addLineToPoint:point5];
[path addLineToPoint:point2];
[path addLineToPoint:point4];
[path addLineToPoint:point1];
[[UIColor redColor] setStroke];
[path stroke];
// UIBezierPath *p = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(30-r, 30-r, r*2, r*2) cornerRadius:r];
// [p stroke];
}
-(BOOL)roundIfOutRectWithCenter:(CGPoint)center r:(CGFloat)r rect:(CGRect)rect{
CGFloat width = rect.size.width;
CGFloat height = rect.size.height;
CGPoint point1 =CGPointMake(width, center.y);
CGPoint point2 =CGPointMake(0, center.y);
CGPoint point3 =CGPointMake(center.x, height);
CGPoint point4 =CGPointMake(0, height);
if ([self isBiggerThan:r dis:[self distanceWith:point1 point:center]] &&
[self isBiggerThan:r dis:[self distanceWith:point2 point:center]] &&
[self isBiggerThan:r dis:[self distanceWith:point3 point:center]] &&
[self isBiggerThan:r dis:[self distanceWith:point4 point:center]]) {
return NO;
}
return YES;
}
-(CGFloat)distanceWith:(CGPoint)point1 point:(CGPoint)point2{
return sqrt((point1.x-point2.x) * (point1.x-point2.x) + (point1.y-point2.y)*(point1.y-point2.y));
}
- (BOOL)isBiggerThan:(CGFloat)r dis:(CGFloat)distace{
if (distace >= r) {
return YES;
}else{
return NO;
}
}
@end