//以下是一个直线类 ,其中包括了一个方法(Cross),用于求直线的交点 , 其实求直线交点不难,但有时在斜率不存在时不好处理,
//所以可以用AX + BX + C =0 这个一般式来描述直线。而不用 Y = KX + B
using
System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace 相交
{
/// <summary>
/// 定义一条直线,这条直线有三个参数,用一般式:AX+BY+C=0。
/// 所以这三个参数分别为A、B、C
/// 之所以这样定义是因为直线有时会出现斜率不存在的情况,如果使用Y=KX+B
/// 就描述不了这条直线。
/// 但使用一般式时会出现两个点,两点不好求三个参数,所以分为两种情况
/// 1、直线的斜率存在:则直接令B=1
/// 2、直线的斜率不存在:则直接令B=0
/// 这样就相当于两点两个参数。应可以解决直线斜率不存在的情况。
/// --hbhbice
/// </summary>
public class HBLine
{
PointD pt1, pt2;
double A, B, C;
/// <summary>
/// 使用两点构造一条线。
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
public HBLine(PointD p1, PointD p2)
{
this .pt1 = p1;
this .pt2 = p2;
try
{
if (pt1.Y == pt2.Y && pt1.X == pt2.X)
{
// 两点相同,确定不了直线。
System.Windows.Forms.MessageBox.Show( " 两相同点,不能确定同一直线,请查实! "
, " 错误 "
, System.Windows.Forms.MessageBoxButtons.OK
, System.Windows.Forms.MessageBoxIcon.Exclamation
, System.Windows.Forms.MessageBoxDefaultButton.Button1);
}
else if (pt1.X == pt2.X)
{
this .B = 0 ;
this .A = 1 ;
this .C = - (pt1.X);
}
else
{
this .B = 1 ;
this .A = - ( this .pt2.Y - this .pt1.Y) / ( this .pt2.X - this .pt1.X);
this .C = this .pt1.X * ( this .pt2.Y - this .pt1.Y) / ( this .pt2.X - this .pt1.X) - this .pt1.Y;
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 求两条直线交点
/// </summary>
/// <param name="otherLine"></param>
/// <returns> 平行,return null ; 相交,return 交点 </returns>
public PointD Cross(HBLine otherLine)
{
try
{
double x = 0 ;
double y = 0 ;
if ( this .B == 0 && otherLine.B == 0 ) // 两直线都无斜率,平行
{
System.Windows.Forms.MessageBox.Show( " 两直线平行,无交点! " );
return null ;
}
else if ( this .B == 0 ) // 其中一条无斜率
{
x = - this .C;
y = - (otherLine.A * x + otherLine.C) / otherLine.B;
}
else if (otherLine.B == 0 ) // 其中一条无斜率
{
x = - otherLine.C;
y = - ( this .A * x + this .C) / this .B;
}
else // 两条都有斜率,所以 B 都自动为1
{
if (( this .A / this .B) == (otherLine.A / this .B))
{
System.Windows.Forms.MessageBox.Show( " 两直线平行,无交点! " );
return null ;
}
else
{
// y = -(otherLine.C / otherLine.A - this.C / this.A) / (otherLine.B / otherLine.A - this.B / this.A);
// x = -(this.B * y / this.A + this.C / this.A);
x = ( this .C - otherLine.C) / (otherLine.A - this .A );
y = - ( this .A * x) - this .C;
}
}
PointD point = new PointD(x, y);
return point;
}
catch (Exception ex)
{
MessageBox.Show( " Cross 异常 " );
System.Windows.Forms.MessageBox.Show(ex.Message);
return null ;
}
}
}
public class PointD
{
public double X;
public double Y;
public PointD( double x , double y)
{
this .X = x;
this .Y = y;
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace 相交
{
/// <summary>
/// 定义一条直线,这条直线有三个参数,用一般式:AX+BY+C=0。
/// 所以这三个参数分别为A、B、C
/// 之所以这样定义是因为直线有时会出现斜率不存在的情况,如果使用Y=KX+B
/// 就描述不了这条直线。
/// 但使用一般式时会出现两个点,两点不好求三个参数,所以分为两种情况
/// 1、直线的斜率存在:则直接令B=1
/// 2、直线的斜率不存在:则直接令B=0
/// 这样就相当于两点两个参数。应可以解决直线斜率不存在的情况。
/// --hbhbice
/// </summary>
public class HBLine
{
PointD pt1, pt2;
double A, B, C;
/// <summary>
/// 使用两点构造一条线。
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
public HBLine(PointD p1, PointD p2)
{
this .pt1 = p1;
this .pt2 = p2;
try
{
if (pt1.Y == pt2.Y && pt1.X == pt2.X)
{
// 两点相同,确定不了直线。
System.Windows.Forms.MessageBox.Show( " 两相同点,不能确定同一直线,请查实! "
, " 错误 "
, System.Windows.Forms.MessageBoxButtons.OK
, System.Windows.Forms.MessageBoxIcon.Exclamation
, System.Windows.Forms.MessageBoxDefaultButton.Button1);
}
else if (pt1.X == pt2.X)
{
this .B = 0 ;
this .A = 1 ;
this .C = - (pt1.X);
}
else
{
this .B = 1 ;
this .A = - ( this .pt2.Y - this .pt1.Y) / ( this .pt2.X - this .pt1.X);
this .C = this .pt1.X * ( this .pt2.Y - this .pt1.Y) / ( this .pt2.X - this .pt1.X) - this .pt1.Y;
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 求两条直线交点
/// </summary>
/// <param name="otherLine"></param>
/// <returns> 平行,return null ; 相交,return 交点 </returns>
public PointD Cross(HBLine otherLine)
{
try
{
double x = 0 ;
double y = 0 ;
if ( this .B == 0 && otherLine.B == 0 ) // 两直线都无斜率,平行
{
System.Windows.Forms.MessageBox.Show( " 两直线平行,无交点! " );
return null ;
}
else if ( this .B == 0 ) // 其中一条无斜率
{
x = - this .C;
y = - (otherLine.A * x + otherLine.C) / otherLine.B;
}
else if (otherLine.B == 0 ) // 其中一条无斜率
{
x = - otherLine.C;
y = - ( this .A * x + this .C) / this .B;
}
else // 两条都有斜率,所以 B 都自动为1
{
if (( this .A / this .B) == (otherLine.A / this .B))
{
System.Windows.Forms.MessageBox.Show( " 两直线平行,无交点! " );
return null ;
}
else
{
// y = -(otherLine.C / otherLine.A - this.C / this.A) / (otherLine.B / otherLine.A - this.B / this.A);
// x = -(this.B * y / this.A + this.C / this.A);
x = ( this .C - otherLine.C) / (otherLine.A - this .A );
y = - ( this .A * x) - this .C;
}
}
PointD point = new PointD(x, y);
return point;
}
catch (Exception ex)
{
MessageBox.Show( " Cross 异常 " );
System.Windows.Forms.MessageBox.Show(ex.Message);
return null ;
}
}
}
public class PointD
{
public double X;
public double Y;
public PointD( double x , double y)
{
this .X = x;
this .Y = y;
}
}
}
下在是一个界面,用于测试效果, 以下左图是斜率为0和斜率不存在的两条直线的相交效果。 右图是 一般的直线的相交效果
界面部分代码如下:
using
System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace 相交
{
public partial class Form1 : Form
{
PointD []pt = new PointD[ 4 ];
int MouseDownCount = 0 ;
public Form1()
{
InitializeComponent();
}
private void Form1_MouseMove( object sender, MouseEventArgs e)
{
toolStripStatusLabel1.Text = " x = " + e.X + " \t " + " y = " + e.Y;
}
private void Form1_MouseDown( object sender, MouseEventArgs e)
{
switch (MouseDownCount % 4 )
{
case 0 :
for ( int i = 0 ; i < pt.Length ; i ++ )
{
pt[i] = null ;
}
pt[ 0 ] = new PointD(e.X, e.Y);
break ;
case 1 :
pt[ 1 ] = new PointD(e.X, e.Y);
break ;
case 2 :
pt[ 2 ] = new PointD(e.X, e.Y);
break ;
case 3 :
pt[ 3 ] = new PointD(e.X, e.Y);
break ;
default :
MessageBox.Show( " switch case 出错 " );
break ;
}
MouseDownCount ++ ;
this .Invalidate();
}
private void Form1_Paint( object sender, PaintEventArgs e)
{
if (pt.Length > 1 )
{
if (pt[ 0 ] != null && pt[ 1 ] != null )
{
e.Graphics.DrawLine(Pens.Black
, new Point( ( int )pt[ 0 ].X ,( int )pt[ 0 ].Y )
, new Point ( ( int )pt[ 1 ].X ,( int )pt[ 1 ].Y ));
}
if (pt[ 2 ] != null && pt[ 3 ] != null )
{
e.Graphics.DrawLine(Pens.Black
, new Point(( int )pt[ 2 ].X, ( int )pt[ 2 ].Y)
, new Point(( int )pt[ 3 ].X, ( int )pt[ 3 ].Y));
HBLine oneLine = new HBLine(pt[ 0 ], pt[ 1 ]);
PointD pd = oneLine.Cross( new HBLine(pt[ 2 ], pt[ 3 ]));
e.Graphics.FillEllipse( new SolidBrush(Color.Red),
new Rectangle(( int )pd.X - 3 , ( int )pd.Y - 3 , 7 , 7 ));
}
}
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace 相交
{
public partial class Form1 : Form
{
PointD []pt = new PointD[ 4 ];
int MouseDownCount = 0 ;
public Form1()
{
InitializeComponent();
}
private void Form1_MouseMove( object sender, MouseEventArgs e)
{
toolStripStatusLabel1.Text = " x = " + e.X + " \t " + " y = " + e.Y;
}
private void Form1_MouseDown( object sender, MouseEventArgs e)
{
switch (MouseDownCount % 4 )
{
case 0 :
for ( int i = 0 ; i < pt.Length ; i ++ )
{
pt[i] = null ;
}
pt[ 0 ] = new PointD(e.X, e.Y);
break ;
case 1 :
pt[ 1 ] = new PointD(e.X, e.Y);
break ;
case 2 :
pt[ 2 ] = new PointD(e.X, e.Y);
break ;
case 3 :
pt[ 3 ] = new PointD(e.X, e.Y);
break ;
default :
MessageBox.Show( " switch case 出错 " );
break ;
}
MouseDownCount ++ ;
this .Invalidate();
}
private void Form1_Paint( object sender, PaintEventArgs e)
{
if (pt.Length > 1 )
{
if (pt[ 0 ] != null && pt[ 1 ] != null )
{
e.Graphics.DrawLine(Pens.Black
, new Point( ( int )pt[ 0 ].X ,( int )pt[ 0 ].Y )
, new Point ( ( int )pt[ 1 ].X ,( int )pt[ 1 ].Y ));
}
if (pt[ 2 ] != null && pt[ 3 ] != null )
{
e.Graphics.DrawLine(Pens.Black
, new Point(( int )pt[ 2 ].X, ( int )pt[ 2 ].Y)
, new Point(( int )pt[ 3 ].X, ( int )pt[ 3 ].Y));
HBLine oneLine = new HBLine(pt[ 0 ], pt[ 1 ]);
PointD pd = oneLine.Cross( new HBLine(pt[ 2 ], pt[ 3 ]));
e.Graphics.FillEllipse( new SolidBrush(Color.Red),
new Rectangle(( int )pd.X - 3 , ( int )pd.Y - 3 , 7 , 7 ));
}
}
}
}
}