首页 > 解决方案 > 如何将一系列拖动点与一系列 CGPoint 路径匹配?

问题描述

我一直致力于将一系列拖动点与预先绘制的路径相匹配,以帮助人们学习如何写出像“A”这样的字符。

我很难理解我应该如何可视化/处理这个创建算法的问题,该算法会给我“是的,用户正确地绘制了角色”。或“不,用户没有正确绘制字符。”

我在这里发表了另一篇文章:如何以编程方式查找点和线之间的距离?关于找到点和线之间的距离。对于每个拖动点,我计算距离并通过它回答“它们是否离我创建的路径集太远了”的问题。

但是,我对第二部分有困难,即“他们画了每一条线吗?”。例如,使用“A”,他们可以只绘制一条像 / 这样的对角线,并且算法将输出正确的结果,因为距离计算很好,但它们缺少所有其他线。

我希望能够实现一些东西,看看一系列用户绘制的 CGPoint,然后是一个代表角色路径的 CGPoint 数组和

  1. 确认点的距离(完成)
  2. 确认他们画出了所有必要的线条

这是我现在遇到问题的第二部分,我想出的唯一一件事是生成一系列点,本质上是角色被炸毁,然后确保用户点与大量生成的点重叠. 但是,这非常缓慢,并且确实减慢了绘图/确认的速度。

func generateAllPointsOnStraightPath(points: [CGPoint]) -> [CGPoint] {
    // generates all points on straight path + adds border points
    // y = mx + b
    // linspace is min/max x-coordinates
    var allPointsOnStraightPath: [CGPoint] = []
    
    var prevPoint = points.first
    
    for point in points {
        let x1 = Int(prevPoint!.x)
        let y1 = Int(prevPoint!.y)
        let x2 = Int(point.x)
        let y2 = Int(point.y)

        // linspace
        let minX = min(x1, x2)
        let maxX = max(x1, x2)
        
        // y = mx + b, first solve for m
        if (x2 - x1) == 0 {
            // vertical line so just append same x and y increments
            if (y2 < y1) {
                // need to go up
                for y in stride(from: y1, to: y2 + 1, by: -1) {
                    allPointsOnStraightPath.append(CGPoint(x: x1, y: y))
                    
                    for i in 1...20 {
                        // this moves the line up
                        allPointsOnStraightPath.append(CGPoint(x: x1 + i, y: y)) // add border point right
                        // this moves the line down
                        allPointsOnStraightPath.append(CGPoint(x: x1 - i, y: y)) // add border point left
                    }
                }
            } else {
                // line going down
                for y in stride(from: y1, to: y2 + 1, by: +1) {
                    // these are the straight line points
                    allPointsOnStraightPath.append(CGPoint(x: x1, y: y))
                    
                    for i in 1...20 {
                        // this moves the line up
                        allPointsOnStraightPath.append(CGPoint(x: x1 + i, y: y)) // add border point right
                        // this moves the line down
                        allPointsOnStraightPath.append(CGPoint(x: x1 - i, y: y)) // add border point left
                    }
                }
            }
        } else {
            let m = (y2 - y1) / (x2 - x1)
            
            // solve for b (y-intercept)
            // y = mx + b
            // y - mx = b
            // this will be a horizontal line e.g. m = 0, so b will just be y1
            // 0 * x = 0 + b where b = y1
            let b = y1 - m * x1
            
            for x in stride(from: minX, to: maxX + 1, by: +1) {
                allPointsOnStraightPath.append(CGPoint(x: x, y: (m * x + b)))
                
                for i in 1...20 {
                    allPointsOnStraightPath.append(CGPoint(x: x, y: ((m * x) + b) + i)) // add border point down
                    allPointsOnStraightPath.append(CGPoint(x: x, y: ((m * x) + b) - i)) // add border point up
                }
            }
        }
            
        prevPoint = point
    }
    
    return allPointsOnStraightPath
}

我知道存在一个解决方案,因为我已经看到了这些语言学习应用程序,但是我很难找到一个资源来概述它的工作原理/方法是什么。任何帮助或见解表示赞赏!

标签: iosswiftswiftui

解决方案


推荐阅读