开发过程中用不到一元一次方程吗?非也,iOS开发中经常会遇到根据某个ScrollView动态偏移量的值来实时设置一个View的透明度,你敢说你不用一元一次方程你能搞定?
想把一个动画效果做好,经常会遇到实时设置的问题,本人遇到过多次,总结出经验,提供方法来专门计算一元一次方程的K值以及b值,方便开发.
BinaryLinearEquation.h + BinaryLinearEquation.m 提供内联函数以及类方法
// Copyright (c) 2014年 Y.X. All rights reserved. // #import <Foundation/Foundation.h> NS_INLINE CGFloat calculateSlope(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { return (y2 - y1) / (x2 - x1); } NS_INLINE CGFloat calculateConstant(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1); } @interface BinaryLinearEquation : NSObject /** * 计算一元一次方程的斜率 K * * Y = kX + b,输入两个点坐标的值(x1, y1), (x2, y2)来计算斜率k的值 * * @param 坐标值 两个点的坐标值(x1, y1), (x2, y2) * @return 计算得出的斜率值 */ + (CGFloat)calculateSlopeWithX1:(CGFloat)x1 Y1:(CGFloat)y1 X2:(CGFloat)x2 Y2:(CGFloat)y2; /** * 计算一元一次方程的常数 b * * Y = kX + b,输入两个点坐标的值(x1, y1), (x2, y2)来计算常数b的值 * * @param 坐标值 两个点的坐标值(x1, y1), (x2, y2) * @return 计算得出的常数值 */ + (CGFloat)calculateConstantWithX1:(CGFloat)x1 Y1:(CGFloat)y1 X2:(CGFloat)x2 Y2:(CGFloat)y2; @end
// Copyright (c) 2014年 Y.X. All rights reserved. // #import "BinaryLinearEquation.h" @implementation BinaryLinearEquation + (CGFloat)calculateSlopeWithX1:(CGFloat)x1 Y1:(CGFloat)y1 X2:(CGFloat)x2 Y2:(CGFloat)y2 { return (y2 - y1) / (x2 - x1); } + (CGFloat)calculateConstantWithX1:(CGFloat)x1 Y1:(CGFloat)y1 X2:(CGFloat)x2 Y2:(CGFloat)y2 { return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1); } @end
测试:
y = 7x - 9
k = 7
b = -9
两个点(0, -9),(9/7, 0)
---------------------------------------------------------------------------------------------
NSLog(@"%f", calculateSlope(0.f, -9.f, 9.f/7.f, 0.f));
NSLog(@"%f", calculateConstant(0.f, -9.f, 9.f/7.f, 0.f));
NSLog(@"%f", [BinaryLinearEquation calculateSlopeWithX1:0.f Y1:-9.f
X2:9.f/7.f Y2:0.f]);
NSLog(@"%f", [BinaryLinearEquation calculateConstantWithX1:0.f Y1:-9.f
X2:9.f/7.f Y2:0.f]);
---------------------------------------------------------------------------------------------
2014-03-28 09:46:00.898 woobooWall[1440:60b] 7.000000
2014-03-28 09:46:00.899 woobooWall[1440:60b] -9.000000
2014-03-28 09:46:00.899 woobooWall[1440:60b] 7.000000
2014-03-28 09:46:00.899 woobooWall[1440:60b] -9.000000
使用时请将数据转换为CGFloat型.
附录1:
附录2:
根据一元一次方程组计算所有的红绿蓝透明度的斜率以及常数值
CalculateColor.h + CalculateColor.m
// // CalculateColor.h // Animation // // Copyright (c) 2014年 Y.X. All rights reserved. // #import <Foundation/Foundation.h> typedef struct ColorParam { CGFloat redSlope; // 红色的斜率 k CGFloat redConstant; // 红色的常数 b CGFloat greenSlope; // 绿色的斜率 k CGFloat greenConstant; // 绿色的常数 b CGFloat blueSlope; // 蓝色的斜率 k CGFloat blueConstant; // 蓝色的常数 b CGFloat alphaSlope; // 透明度的斜率 k CGFloat alphaConstant; // 透明度的常数 b } SColorParam; /** 根据一元一次方程组计算所有的红绿蓝透明度的斜率以及常数值 这是用来设计做动态设定动画效果的,需要提供起始点的UIColor,起始点的一个值,终点的UIColor,终点的一个值,然后计算 出动画过程中需要的一些设置参数. @param oldColor 起始点的color @param oldPoint 起始点的值 @param newColor 终点的color @param newPoint 终点的值 @param param 计算好的值存储于结构体SColorParam中 @return none */ void calculateUIColorAndPoint(UIColor *oldColor,CGFloat oldPoint, UIColor *newColor, CGFloat newPoint, SColorParam *param);
// // CalculateColor.m // Animation // // Copyright (c) 2014年 Y.X. All rights reserved. // #import "CalculateColor.h" #pragma mark - 计算斜率 k CGFloat calculateSlope(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { return (y2 - y1) / (x2 - x1); } #pragma mark - 计算常数 b CGFloat calculateConstant(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1); } #pragma mark - 根据一元一次方程组计算所有的红绿蓝透明度的斜率以及常数值 void calculateUIColorAndPoint(UIColor *oldColor,CGFloat oldPoint, UIColor *newColor, CGFloat newPoint, SColorParam *param) { // 获取旧颜色 CGFloat oldRed = 0; CGFloat oldGreen = 0; CGFloat oldBlue = 0; CGFloat oldAlpha = 0; [oldColor getRed:&oldRed green:&oldGreen blue:&oldBlue alpha:&oldAlpha]; // 获取新颜色 CGFloat newRed = 0; CGFloat newGreen = 0; CGFloat newBlue = 0; CGFloat newAlpha = 0; [newColor getRed:&newRed green:&newGreen blue:&newBlue alpha:&newAlpha]; // 计算每一个k值和b值 param->redSlope = calculateSlope(oldPoint, oldRed, newPoint, newRed); param->redConstant = calculateConstant(oldPoint, oldRed, newPoint, newRed); param->greenSlope = calculateSlope(oldPoint, oldGreen, newPoint, newGreen); param->greenConstant = calculateConstant(oldPoint, oldGreen, newPoint, newGreen); param->blueSlope = calculateSlope(oldPoint, oldBlue, newPoint, newBlue); param->blueConstant = calculateConstant(oldPoint, oldBlue, newPoint, newBlue); param->alphaSlope = calculateSlope(oldPoint, oldAlpha, newPoint, newAlpha); param->alphaConstant = calculateConstant(oldPoint, oldAlpha, newPoint, newAlpha); }
以下是实现动态改变颜色的方法
#import "YX_2_ViewController.h" #import "CalculateColor.h" @interface YX_2_ViewController ()<UIScrollViewDelegate> @property (strong, nonatomic) UIScrollView *mainScrollView; @end @implementation YX_2_ViewController - (void)viewDidLoad { [super viewDidLoad]; _mainScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; _mainScrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 2, self.view.bounds.size.height); _mainScrollView.backgroundColor = [UIColor cyanColor]; _mainScrollView.delegate = self; [self.view addSubview:_mainScrollView]; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { static SColorParam paramVe2 = {0}; // 只计算一次 static int flag = 0; if (flag == 0) { calculateUIColorAndPoint([UIColor cyanColor], 0, [UIColor redColor], 320, ¶mVe2); flag = 1; } UIColor *color = [UIColor colorWithRed:scrollView.contentOffset.x * paramVe2.redSlope + paramVe2.redConstant green:scrollView.contentOffset.x * paramVe2.greenSlope + paramVe2.greenConstant blue:scrollView.contentOffset.x * paramVe2.blueSlope + paramVe2.blueConstant alpha:1]; scrollView.backgroundColor = color; } @end