1.问题或需求描述:

计算两条直线交点

2.解决方法或原理:

已知两条直线信息, 计算直线的交点。无论是根据直线公式计算交点,还是根据直线上的已知点计算交点,方法都 是基本相似的。

本文介绍已知两条直线上的各两点坐标,计算直线的交点坐标,如下:

计算两条直线交点_交点坐标

计算两条直线交点_交点_02

C#源码:

public static System.Drawing.PointF GetLinesCrossPoint(
System.Drawing.PointF line1_p1, //直线1 上的 点1
System.Drawing.PointF line1_p2, //直线1 上的 点2
System.Drawing.PointF line2_p1, //直线2 上的 点1
System.Drawing.PointF line2_p2 //直线2 上的 点2
)
{
System.Drawing.PointF crossPoint = new PointF();
double? k1 = null; //line1 斜率
double? k2 = null; //line2 斜率
double b1 = 0; //line1 位移
double b2 = 0; //line2 位移

if (line1_p2.X != line1_p1.X) k1 = (line1_p2.Y - line1_p1.Y) / (line1_p2.X - line1_p1.X);
if ((line2_p2.X != line2_p1.X)) k2 = (line2_p2.Y - line2_p1.Y) / (line2_p2.X - line2_p1.X);
if (k1 == k2) throw new Exception("平行线无交点");
if (k1 != null) b1 = (line1_p2.X * line1_p1.Y - line1_p1.X * line1_p2.Y) / (line1_p2.X - line1_p1.X);
if (k2 != null) b2 = (line2_p2.X * line2_p1.Y - line2_p1.X * line2_p2.Y) / (line2_p2.X - line2_p1.X);

if (k1 == null)
{
crossPoint.X = line1_p1.X;
crossPoint.Y = (float)(k2 * crossPoint.X + b2);
}
else if (k2 == null)
{
crossPoint.X = line2_p1.X;
crossPoint.Y = (float)(k1 * crossPoint.X + b1);
}
else if (k1 == 0)
{
crossPoint.X = (float)((line1_p1.Y - b2) / k2);
crossPoint.Y = line1_p1.Y;
}
else if (k2 == 0)
{
crossPoint.X = (float)((line2_p1.Y - b1) / k1);
crossPoint.Y = line2_p1.Y;
}
else
{
crossPoint.X = (float)((b2 - b1) / (k1 - k2));
crossPoint.Y = (float)((k2 * b1 - k1 * b2) / (k2 - k1));
}

return crossPoint;
}

完整测试代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Drawing;

namespace ConsoleApp5
{
class Program
{
public static System.Drawing.PointF GetLinesCrossPoint(
System.Drawing.PointF line1_p1, //直线1 上的 点1
System.Drawing.PointF line1_p2, //直线1 上的 点2
System.Drawing.PointF line2_p1, //直线2 上的 点1
System.Drawing.PointF line2_p2 //直线2 上的 点2
)
{
System.Drawing.PointF crossPoint = new PointF();
double? k1 = null; //line1 斜率
double? k2 = null; //line2 斜率
double b1 = 0; //line1 位移
double b2 = 0; //line2 位移

if (line1_p2.X != line1_p1.X) k1 = (line1_p2.Y - line1_p1.Y) / (line1_p2.X - line1_p1.X);
if ((line2_p2.X != line2_p1.X)) k2 = (line2_p2.Y - line2_p1.Y) / (line2_p2.X - line2_p1.X);
if (k1 == k2) throw new Exception("平行线无交点");
if (k1 != null) b1 = (line1_p2.X * line1_p1.Y - line1_p1.X * line1_p2.Y) / (line1_p2.X - line1_p1.X);
if (k2 != null) b2 = (line2_p2.X * line2_p1.Y - line2_p1.X * line2_p2.Y) / (line2_p2.X - line2_p1.X);

if (k1 == null)
{
crossPoint.X = line1_p1.X;
crossPoint.Y = (float)(k2 * crossPoint.X + b2);
}
else if (k2 == null)
{
crossPoint.X = line2_p1.X;
crossPoint.Y = (float)(k1 * crossPoint.X + b1);
}
else if (k1 == 0)
{
crossPoint.X = (float)((line1_p1.Y - b2) / k2);
crossPoint.Y = line1_p1.Y;
}
else if (k2 == 0)
{
crossPoint.X = (float)((line2_p1.Y - b1) / k1);
crossPoint.Y = line2_p1.Y;
}
else
{
crossPoint.X = (float)((b2 - b1) / (k1 - k2));
crossPoint.Y = (float)((k2 * b1 - k1 * b2) / (k2 - k1));
}

return crossPoint;
}
static void Main(string[] args)
{
const int img_w = 800;
const int img_h = 800;
const int border_size = 50;
Random random = new Random();
PointF[] points = new PointF[5];
PointF pointF = GetLinesCrossPoint(
points[0] = new PointF(random.Next(border_size, img_w/2), random.Next(border_size, img_h/2)),
points[1] = new PointF(random.Next(img_w/2 + border_size, img_w - border_size), random.Next(img_h/2 + border_size, img_h - border_size)),
points[2] = new PointF(random.Next(border_size, img_w/2), random.Next(img_h/2 + border_size, img_h - border_size)),
points[3] = new PointF(random.Next(img_w/2 + border_size, img_w - border_size), random.Next(border_size, img_h/2))
);
points[4] = GetLinesCrossPoint(points[0],points[1],points[2],points[3]);


const int point_size = 6;
Bitmap bitmap = new Bitmap(img_w, img_h);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.Clear(Color.Black);
foreach (var v in points)
{
g.FillEllipse(Brushes.Red, new RectangleF(v.X - point_size / 2, v.Y - point_size / 2, point_size, point_size));
g.DrawString(
string.Format("({0},{1})", v.X, v.Y),
new Font("Times new roman", 12),
Brushes.White,
new PointF(v.X, v.Y + 10)
);
}
g.DrawLine(Pens.Lime, points[0], points[1]); //draw line1
g.DrawLine(Pens.Lime, points[2], points[3]); //draw line2
}
bitmap.Save("test.png");
}
}
}

3.测试结果展示:

计算两条直线交点_交点_03

计算两条直线交点_直线交点_04

计算两条直线交点_直线交点_05

计算两条直线交点_交点_06

计算两条直线交点_交点坐标_07