• 计算一元一次方程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
  • 相关阅读:
    php 微信调用扫一扫
    JavaSE常用API
    Java中的异常处理
    Java实现多态的机制是什么?
    JavaSE(下)
    JavaSE语法(中)
    JavaSE语法
    Java面向对象
    Java零基础入门之常用工具
    Java抽象类、接口、内部类
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3630012.html
Copyright © 2020-2023  润新知