zoukankan      html  css  js  c++  java
  • 求两直线的交点

    直线与直线的位置关系

    平面上的两条直线如果不平行,那么他们一定相交,并且有唯一的交点
    

    Ax+By+C = 0

    直线一般式适用平面上任意直线
    

    根据两点求解一般式的系数

    设两个点为 (x1, y1) , (x2, y2),则有:
    A = y2 - y1
    B = x1 - x2
    C = x2y1-x1y2
    

    直线标准式求系数

    Ax + By = C

    A = y2 - y1
    B = x1 - x2
    C = Ax1 + By1
    

    直线一般式求交点

    首先设交点坐标为 (x, y),两线段对应直线的一般式为:
    
    a1x + b1y + c1 = 0
    a2x + b2y + c2 = 0
    
    那么对 1 式乘 a2,对 2 式乘 a1 得:
    a2*a1x + a2*b1y + a2*c1 = 0
    a1*a2x + a1*b2y + a1*c2 = 0
    两式相减得:
    y = (c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1)
    
    同样可以推得:
    x = (c2 * b1 - c1 * b2) / (a1 * b2 - a2 * b1)
    
    如果(x,y)在两线段上,则(x,y)即为答案,否则交点不存在。
    
    

    直线标准式求交点

    首先设交点坐标为(x,y),两线段对应直线的标准式为
    
    A1x + B1y = C1 
    A2x + B2y = C2
    
    将1式成以B2,将2式乘以B1在相减
    
      A1B2x + B1B2y = B2C1
    - A2B1x + B1B2y = B1C2 
    
    x = ( B2C1 - B1C2 ) / ( A1B2 - A2B1)
    
    同理可得
    
    y = (A1C2 - A2C1) / ( A1B2 - A2B1)
    
    

    判断线段是否平行

    如果两直线平行,则有 A1/B1 == A2/B2。
    为了避免除零的问题,可转化为 A1*B2 == A2*B1    
    

    利用一般式求两直线的交点

    	function lineIntersect(p0, p1, p2, p3) {
    		var A1 = p1.y - p0.y,
    			B1 = p0.x - p1.x,
    			C1 = A1 * p0.x + B1 * p0.y,
    			A2 = p3.y - p2.y,
    			B2 = p2.x - p3.x,
    			C2 = A2 * p2.x + B2 * p2.y,
    			denominator = A1 * B2 - A2 * B1;
    
    		return {
    			x: (B2 * C1 - B1 * C2) / denominator,
    			y: (A1 * C2 - A2 * C1) / denominator
    		}
    	}
    
    
    window.onload = function() {
    	var canvas = document.getElementById("canvas"),
    		context = canvas.getContext("2d"),
    		width = canvas.width = window.innerWidth,
    		height = canvas.height = window.innerHeight;
    
    	var p0 = {
    			x: 100,
    			y: 100
    		},
    		p1 = {
    			x: 500,
    			y: 500
    		},
    		p2 = {
    			x: 600,
    			y: 50
    		},
    		p3 = {
    			x: 80,
    			y: 600
    		};
    
    	context.beginPath();
    	context.moveTo(p0.x, p0.y);
    	context.lineTo(p1.x, p1.y);
    	context.moveTo(p2.x, p2.y);
    	context.lineTo(p3.x, p3.y);
    	context.stroke();
    
    	var intersect = lineIntersect(p0, p1, p2, p3);
    
    	context.beginPath();
    	context.arc(intersect.x, intersect.y, 20, 0, Math.PI * 2, false);
    	context.stroke();
    
    
    
    	function lineIntersect(p0, p1, p2, p3) {
    		var A1 = p1.y - p0.y,
    			B1 = p0.x - p1.x,
    			C1 = A1 * p0.x + B1 * p0.y,
    			A2 = p3.y - p2.y,
    			B2 = p2.x - p3.x,
    			C2 = A2 * p2.x + B2 * p2.y,
    			denominator = A1 * B2 - A2 * B1;
    
    		return {
    			x: (B2 * C1 - B1 * C2) / denominator,
    			y: (A1 * C2 - A2 * C1) / denominator
    		}
    	}
    
    };
    

    判断直线平行和相交的情况

    交点在一条直线的延长线上或者交点在两条直线的延长线上不画出交点

    function segmentIntersect(p0, p1, p2, p3) {
    		var A1 = p1.y - p0.y,
    			B1 = p0.x - p1.x,
    			C1 = A1 * p0.x + B1 * p0.y,
    			A2 = p3.y - p2.y,
    			B2 = p2.x - p3.x,
    			C2 = A2 * p2.x + B2 * p2.y,
    			denominator = A1 * B2 - A2 * B1;
    
            // 如果分母为0 则平行或共线, 不相交  
    		if(denominator == 0) {
    			return null;
    		}
    
         
    		var intersectX = (B2 * C1 - B1 * C2) / denominator,
    			intersectY = (A1 * C2 - A2 * C1) / denominator,
    			rx0 = (intersectX - p0.x) / (p1.x - p0.x),
    			ry0 = (intersectY - p0.y) / (p1.y - p0.y),
    			rx1 = (intersectX - p2.x) / (p3.x - p2.x),
    			ry1 = (intersectY - p2.y) / (p3.y - p2.y);
    
            /** 2 判断交点是否在两条线段上 **/  
    		if(
                // 交点在线段1上  
                ((rx0 >= 0 && rx0 <= 1) || (ry0 >= 0 && ry0 <= 1)) && 
                // 且交点也在线段2上  
    		   ((rx1 >= 0 && rx1 <= 1) || (ry1 >= 0 && ry1 <= 1))) {
    			return {
    				x: intersectX,
    				y: intersectY
    			};
    		}
    		else {
    			return null;
    		}
    	}
    
  • 相关阅读:
    注意力机制在CV领域的应用之SEnet
    知识蒸馏技术原理
    batchsize如何影响模型的性能
    docker网络 macvlan
    docker pull使用 代理
    auditd重启失败
    3.Golang的包导入
    2.golang应用目录结构和GOPATH概念
    使用git版本管理时的免密问题
    1.go语言目录结构
  • 原文地址:https://www.cnblogs.com/pluslius/p/13800167.html
Copyright © 2011-2022 走看看