开发过程中用不到一元一次方程吗?非也,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