题目描述

python 已知两条线 求夹角_python 已知两条线 求夹角

算法分析 这道题目看起来难度不高,判断多点共线问题似乎是高中数学里面就学过的算法思路。 所以一开始,我的算法思路和斜率有关。 可以根据“两点确定一条直线”,可以算出一个参考的斜率,根据参考的斜率预测下一个坐标点的位置(可以已知x坐标求y坐标)。 或者每个点都和第一个点进行斜率计算,得出的结果如果总是相同,则多点共线。

而大佬们的算法博客中,思路基本上也是如此:计算第i个点、第i-1个点、第i+1个点之间的斜率;【Java解法、C语言解法】 计算第0个点、第1个点、第i个点之间的斜率;【python解法】 利用直线方程进行求解【C++解法】

此外,需要注意的是,比较斜率时,为了避免除0这种特殊错误的产生,可以将除法式转化为乘法式,当这样比较斜率时,也可以说是运用了向量共线的基本性质。

代码实现 【C】

/*
采用向量之间的叉乘做法:
 * 叉乘 a * b
 * = | x1, y1 | = x1 * y2 - y1 * x2
 *   | x2, y2 |
 * 若结果小于 0,表示向量 b 在向量 a 的顺时针方向;
 * 若结果大于 0,表示向量 b 在向量 a 的逆时针方向;
 * 若结果为 0,表示向量 b 与向量 a 平行;
 */
bool checkStraightLine(int** coordinates, int coordinatesSize, int* coordinatesColSize)
{
    int x1 = coordinates[1][0] - coordinates[0][0];
    int y1 = coordinates[1][1] - coordinates[0][1];

    for (int i = 2; i < coordinatesSize; ++i) {
        int x2 = coordinates[i][0] - coordinates[0][0];
        int y2 = coordinates[i][1] - coordinates[0][1];
        if (x1 * y2 != x2 * y1) {//和比较斜率很相似,比较的是第i个、第0个、第1个点之间的斜率是否相同。
            return false;
        }
    }

    return true;
}

C语言参考网址

【C++】

/*
采用直线方程的求解方法。
设定一个线性方程,代入点坐标求解系数,得到一条参考的直线,之后在印证其他的点是不是在这条直线上。
为了线性方程的系数求解简单,该解法中先做了平移,简化直线方程
*/
class Solution {
public:
    bool checkStraightLine(vector<vector<int>> &coordinates) {
        int deltaX = coordinates[0][0], deltaY = coordinates[0][1];//平移程度
        int n = coordinates.size();
        for (int i = 0; i < n; ++i) {//将所有的点进行平移,数组中第一点此时位于原点,这样做是为了简化方程。
            coordinates[i][0] -= deltaX;
            coordinates[i][1] -= deltaY;
        }
        int A = coordinates[1][1], B = -coordinates[1][0];//Ax+By=0的方程中,带入point[0]和point[1],得到A、B两个系数大小。
        for (int i = 2; i < n; ++i){//对于point[2]及之后的点,进行直线位置判断
            int x = coordinates[i][0], y = coordinates[i][1];
            if (A * x + B * y != 0) {
                return false;
            }
        }
        return true;
    }
};

C++参考网址

【Java】

/*
利用斜率进行判断,如果相邻线段之间斜率总是相等,则点共线
*/
class Solution {
    public boolean checkStraightLine(int[][] coordinates) {
        int len = coordinates.length;
        for (int i = 1; i < len - 1; ++i) {//遍历点坐标数组
            int y1 = coordinates[i][1] -coordinates[i-1][1];//第i个点和第i-1个点之间的纵坐标差
            int x1 = coordinates[i][0] -coordinates[i-1][0];//第i个点和第i-1个点之间的横坐标差
            int y2 = coordinates[i+1][1] -coordinates[i][1]; //第i+1个点和第i个点之间的纵坐标差        
            int x2 = coordinates[i+1][0] -coordinates[i][0];//第i+1个点和第i个点之间的横坐标差
            if (y1*x2 != y2*x1) {//y1/x1 y2/x2是两个斜率,此处进行化简,也就是判断两线段斜率是否相同,如果不同,则不共线
                return false;
            }
        }
        return true;

    }
}

Java参考网址

【python】

#比较第0个,第1个和第i个点的斜率
class Solution:
    def checkStraightLine(self, coordinates):
        
        for i in range(2,len(coordinates)):
            if (coordinates[i][1] - coordinates[1][1])*(coordinates[1][0]-coordinates[0][0])  != (coordinates[1][1] - coordinates[0][1]) * (coordinates[i][0] - coordinates[1][0]):#将除法转为乘法,目的是为了避免除0的情况
                return False
        return True

python参考网址