zoukankan      html  css  js  c++  java
  • Swift实时画箭头的实现

    iOS上实现画箭头,如果是指定了坐标点,那是很简单的,但如果需要做到实时绘制,就需要计算一下了

    需求:

    在白板上,根据手势落下点和移动点,实时绘制一条箭头直线(如下图)

    实现代码:

    /// 获取箭头的点位置
        ///
        /// - Parameters:
        ///   - fPoint: <#fPoint description#>
        ///   - tPoint: <#tPoint description#>
        /// - Returns: <#return value description#>
        func getArrowPoint(fPoint:CGPoint,tPoint:CGPoint) -> (CGPoint,CGPoint,CGPoint) {
            var p1 = CGPoint.zero           //箭头点1
            var p2 = CGPoint.zero           //箭头点2
            var p3 = CGPoint.zero           //箭头最前面点
            //假设箭头边长20,箭头是一个等腰三角形
            let line = sqrt(pow(fabs(tPoint.x-fPoint.x), 2)+pow(fabs(tPoint.y-fPoint.y), 2))
            let arrowH:CGFloat = line>40 ? 20 : line/3
            //线与水平方向的夹角
            let angle = getAnglesWithThreePoints(p1: fPoint, p2: tPoint, p3: CGPoint(x: fPoint.x, y: tPoint.y))
            let _x = CGFloat(fabs(sin(angle)))*arrowH/2
            let _y = CGFloat(fabs(cos(angle)))*arrowH/2
            //向右上角、水平向右
            if tPoint.x >= fPoint.x && tPoint.y <= fPoint.y{
                p1.x = tPoint.x-_x
                p1.y = tPoint.y-_y
                
                p2.x = tPoint.x+_x
                p2.y = tPoint.y+_y
                
                p3.x = tPoint.x+_y*2
                p3.y = tPoint.y-_x*2
                
            }else if tPoint.x > fPoint.x && tPoint.y > fPoint.y{
                //向右下角
                p1.x = tPoint.x+_x
                p1.y = tPoint.y-_y
                
                p2.x = tPoint.x-_x
                p2.y = tPoint.y+_y
                
                p3.x = tPoint.x+_y*2
                p3.y = tPoint.y+_x*2
            }else if tPoint.x < fPoint.x && tPoint.y < fPoint.y{
                //向左上角
                p1.x = tPoint.x-_x
                p1.y = tPoint.y+_y
                
                p2.x = tPoint.x+_x
                p2.y = tPoint.y-_y
                
                p3.x = tPoint.x-_y*2
                p3.y = tPoint.y-_x*2
                
            }else if tPoint.x < fPoint.x && tPoint.y >= fPoint.y{
                //向左下角,水平向左
                p1.x = tPoint.x-_x
                p1.y = tPoint.y-_y
                
                p2.x = tPoint.x+_x
                p2.y = tPoint.y+_y
                
                p3.x = tPoint.x-_y*2
                p3.y = tPoint.y+_x*2
            }else if fPoint.x==tPoint.x {
                //竖直方向
                p1.x=tPoint.x-arrowH/2
                p1.y=tPoint.y
                p2.x=tPoint.x+arrowH/2
                p2.y=tPoint.y
                p3.x=tPoint.x
                p3.y = tPoint.y>fPoint.y ? tPoint.y+arrowH : tPoint.y-arrowH
            }
            
            return (p1,p2,p3)
        }

    其中,获取夹角方法:getAnglesWithThreePoints

    /// 计算三点之间的角度
        ///
        /// - Parameters:
        ///   - p1: 点1
        ///   - p2: 点2(也是角度所在点)
        ///   - p3: 点3
        /// - Returns: 角度(180度制)
        func getAnglesWithThreePoints(p1:CGPoint,p2:CGPoint,p3:CGPoint) -> Double {
            //排除特殊情况,三个点一条线
            if (p1.x == p2.x && p2.x == p3.x) || ( p1.y == p2.x && p2.x == p3.x){
                return 0
            }
            
            let a = fabs(p1.x - p2.x)
            let b = fabs(p1.y - p2.y)
            let c = fabs(p3.x - p2.x)
            let d = fabs(p3.y - p2.y)
            
            if (a < 1.0 && b < 1.0) || (c < 1.0 && d < 1.0){
                return 0
            }
            let e = a*c+b*d
            let f = sqrt(a*a+b*b)
            let g = sqrt(c*c+d*d)
            let r = Double(acos(e/(f*g)))
            return r        //弧度值
            
    //        return (180*r/Double.pi)      //角度值
    
        }
    View Code

    最后得到三个点,即箭头的三个点坐标

  • 相关阅读:
    Http方法:Get请求与Post请求的区别
    udev和rules使用规则
    c++中的动态内存分配
    c++中重载运算符
    c++中静态成员函数
    c++中值传递,址传递,引用传递
    c++中实现单例模式singleton class
    [Windows篇] 在windows 10上源码编译gtest 并编写CMakeLists.txt
    [Ubuntu篇] 在ubuntu上源码编译gtest,编写gtest-config.cmake并测试
    使用boost data_time模块来获取毫秒级时间并转换为string字符串
  • 原文地址:https://www.cnblogs.com/yajunLi/p/9231159.html
Copyright © 2011-2022 走看看