计算一元一次方程Y=kX+b

开发过程中用不到一元一次方程吗?非也,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, &paramVe2);
        
        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
原文地址:https://www.cnblogs.com/YouXianMing/p/3630012.html