zoukankan      html  css  js  c++  java
  • 刷题72——交点

    111.交点

    题目链接

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/intersection-lcci

    题目描述

    给定两条线段(表示为起点start = {X1, Y1}和终点end = {X2, Y2}),如果它们有交点,请计算其交点,没有交点则返回空值。

    要求浮点型误差不超过10^-6。若有多个交点(线段重叠)则返回 X 值最小的点,X 坐标相同则返回 Y 值最小的点。

    示例 1:

    输入:
    line1 = {0, 0}, {1, 0}
    line2 = {1, 1}, {0, -1}
    输出: {0.5, 0}
    示例 2:

    输入:
    line1 = {0, 0}, {3, 3}
    line2 = {1, 1}, {2, 2}
    输出: {1, 1}
    示例 3:

    输入:
    line1 = {0, 0}, {1, 1}
    line2 = {1, 0}, {2, 1}
    输出: {},两条线段没有交点
     

    提示:

    坐标绝对值不会超过 2^7
    输入的坐标均是有效的二维坐标

    重难点

    分析斜率判断两条直线相交情况

    题目分析

    作者:ari-5
    链接:https://leetcode-cn.com/problems/intersection-lcci/solution/wo-mei-you-wen-hua-yi-ju-ykxbzou-tian-xia-by-ari-5/

    1. 分析斜率k1和k2,判断交点;
    2. k1=0,k2=0;
    3. k1=0,k2不存在;
    4. k1不存在,k2=0;
    5. k1不存在,k2不存在;
    6. k1,k2都存在;
    var intersection = function (start1, end1, start2, end2, k = 0) {
        // 特殊k值前置,保证特殊都在前边,好处理
        if (k === 0) {
            if (start2[0] - end2[0] === 0 || start2[1] - end2[1] === 0)
                return intersection(start2, end2, start1, end1, k = 1)
        }
        // 这个是可能的交点
        let x = null, y = null
        // 第一条平行于Y轴
        if (start1[0] - end1[0] === 0) {
            if (start2[0] - end2[0] === 0) {
                // 两条线都平行Y轴
                if (start1[0] === start2[0] && Math.max(start1[1], end1[1]) >= Math.min(start2[1], end2[1]) && Math.min(start1[1], end1[1]) <= Math.max(start2[1], end2[1]))
                    return [start1[0], Math.max(Math.min(start2[1], end2[1]), Math.min(start1[1], end1[1]))]
            } else {
                // 第二条线不平行Y(未判断线段可交)
                let k = (end2[1] - start2[1]) / (end2[0] - start2[0])
                x = start1[0]
                y = (x - end2[0]) * k + end2[1]
            }
        } else if (start1[1] - end1[1] === 0) {
            // 第一条平行于X轴
            if (start2[1] - end2[1] === 0) {
                // 两条线都平行X轴
                if (start1[1] === start2[1] && Math.max(start1[0], end1[0]) >= Math.min(start2[0], end2[0]) && Math.min(start1[0], end1[0]) >= Math.max(start2[0], end2[0]))
                    return [Math.max(Math.min(start2[0], end2[0]), Math.min(start1[0], end1[0]), start1[1])]
            } else if (start2[0] - end2[0] === 0) {
                // 第二条线平行Y(未判断线段可交)
                x = start2[0]
                y = start1[1]
            } else {
                // 第二条线存在K
                let k = (end2[1] - start2[1]) / (end2[0] - start2[0])
                y = start1[1]
                x = (y - (start2[1] - (k * start2[0]))) / k
            }
        } else if ((end2[1] - start2[1]) / (end2[0] - start2[0]) === (end1[1] - start1[1]) / (end1[0] - start1[0])) {
            // 斜率不为0存在且相等
            let k = (end2[1] - start2[1]) / (end2[0] - start2[0])
            if ((end2[1] - k * end2[0]) === (end1[1] - k * end1[0])) {
                // b相等
                x = Math.max(Math.min(start1[0], end1[0]), Math.min(start2[0], end2[0]))
                y = Math.max(Math.min(start1[1], end1[1]), Math.min(start2[1], end2[1]))
            } else {
                // b不相等 没有交点
                return []
            }
        } else {
            // 两个都是正常的K
            let k2 = (end2[1] - start2[1]) / (end2[0] - start2[0])
            let k1 = (end1[1] - start1[1]) / (end1[0] - start1[0])
            let b2 = (start2[1] - k2 * start2[0])
            let b1 = (start1[1] - k1 * start1[0])
            x = (b2 - b1) / (k1 - k2)
            y = (x * k1) + b1
        }
        // 上下左右边界,确定所求出来的x,y是不是在线段上面
        let l = Math.max(Math.min(start1[0], end1[0]), Math.min(start2[0], end2[0]))
        let r = Math.min(Math.max(start1[0], end1[0]), Math.max(start2[0], end2[0]))
        let b = Math.max(Math.min(start1[1], end1[1]), Math.min(start2[1], end2[1]))
        let t = Math.min(Math.max(start1[1], end1[1]), Math.max(start2[1], end2[1]))
        if (x !== null && x >= l && x <= r && y <= t && y >= b) {
            return [x, y]
        } else {
            return []
        }
    };
  • 相关阅读:
    B.Icebound and Sequence
    Educational Codeforces Round 65 (Rated for Div. 2) D. Bicolored RBS
    Educational Codeforces Round 65 (Rated for Div. 2) C. News Distribution
    Educational Codeforces Round 65 (Rated for Div. 2) B. Lost Numbers
    Educational Codeforces Round 65 (Rated for Div. 2) A. Telephone Number
    Codeforces Round #561 (Div. 2) C. A Tale of Two Lands
    Codeforces Round #561 (Div. 2) B. All the Vowels Please
    Codeforces Round #561 (Div. 2) A. Silent Classroom
    HDU-2119-Matrix(最大匹配)
    读书的感想!
  • 原文地址:https://www.cnblogs.com/liu-xin1995/p/12702030.html
Copyright © 2011-2022 走看看