- UID
- 769950
- 积分
- 64
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2017-7-25
- 最后登录
- 1970-1-1
|
楼主 |
发表于 2017-8-4 08:08:08
|
显示全部楼层
/// <summary>
/// 计算两条直线的交点
/// </summary>
/// <param name="lineFirstStar">L1的点1坐标</param>
/// <param name="lineFirstEnd">L1的点2坐标</param>
/// <param name="lineSecondStar">L2的点1坐标</param>
/// <param name="lineSecondEnd">L2的点2坐标</param>
/// <returns></returns>
///
public static Point2d GetIntersection(Point2d lineFirstStar, Point2d lineFirstEnd, Point2d lineSecondStar, Point2d lineSecondEnd)
{
/*
* L1,L2都存在斜率的情况:
* 直线方程L1: ( y - y1 ) / ( y2 - y1 ) = ( x - x1 ) / ( x2 - x1 )
* => y = [ ( y2 - y1 ) / ( x2 - x1 ) ]( x - x1 ) + y1
* 令 a = ( y2 - y1 ) / ( x2 - x1 )
* 有 y = a * x - a * x1 + y1 .........1
* 直线方程L2: ( y - y3 ) / ( y4 - y3 ) = ( x - x3 ) / ( x4 - x3 )
* 令 b = ( y4 - y3 ) / ( x4 - x3 )
* 有 y = b * x - b * x3 + y3 ..........2
*
* 如果 a = b,则两直线平等,否则, 联解方程 1,2,得:
* x = ( a * x1 - b * x3 - y1 + y3 ) / ( a - b )
* y = a * x - a * x1 + y1
*
* L1存在斜率, L2平行Y轴的情况:
* x = x3
* y = a * x3 - a * x1 + y1
*
* L1 平行Y轴,L2存在斜率的情况:
* x = x1
* y = b * x - b * x3 + y3
*
* L1与L2都平行Y轴的情况:
* 如果 x1 = x3,那么L1与L2重合,否则平等
*
*/
double a = 0, b = 0;
int state = 0;
if (lineFirstStar.X != lineFirstEnd.X)
{
a = (lineFirstEnd.Y - lineFirstStar.Y) / (lineFirstEnd.X - lineFirstStar.X);
state |= 1;
}
if (lineSecondStar.X != lineSecondEnd.X)
{
b = (lineSecondEnd.Y - lineSecondStar.Y) / (lineSecondEnd.X - lineSecondStar.X);
state |= 2;
}
switch (state)
{
case 0: //L1与L2都平行Y轴
{
if (lineFirstStar.X == lineSecondStar.X)
{
//throw new Exception("两条直线互相重合,且平行于Y轴,无法计算交点。");
return new Point2d(0, 0);
}
else
{
//throw new Exception("两条直线互相平行,且平行于Y轴,无法计算交点。");
return new Point2d(0, 0);
}
}
case 1: //L1存在斜率, L2平行Y轴
{
double x = lineSecondStar.X;
double y = (lineFirstStar.X - x) * (-a) + lineFirstStar.Y;
return new Point2d(x, y);
}
case 2: //L1 平行Y轴,L2存在斜率
{
double x = lineFirstStar.X;
//网上有相似代码的,这一处是错误的。你可以对比case 1 的逻辑 进行分析
//源code:lineSecondStar * x + lineSecondStar * lineSecondStar.X + p3.Y;
double y = (lineSecondStar.X - x) * (-b) + lineSecondStar.Y;
return new Point2d(x, y);
}
case 3: //L1,L2都存在斜率
{
if (a == b)
{
// throw new Exception("两条直线平行或重合,无法计算交点。");
return new Point2d(0, 0);
}
double x = (a * lineFirstStar.X - b * lineSecondStar.X - lineFirstStar.Y + lineSecondStar.Y) / (a - b);
double y = a * x - a * lineFirstStar.X + lineFirstStar.Y;
return new Point2d(x, y);
}
}
// throw new Exception("不可能发生的情况");
return new Point2d(0, 0);
}
[CommandMethod("MyInter")]
public static void MyInter()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptSelectionResult result = ed.GetSelection();
SelectionSet set = result.Value;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
//以读方式打开块表..
BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
//以写方式打开模型空间块表记录
BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
if (set != null && set.Count > 0)
{
List<Polyline> textlist = new List<Polyline>();
ObjectId[] idlist = set.GetObjectIds();
foreach (ObjectId id in set.GetObjectIds())
{
Entity ent = (Entity)id.GetObject(OpenMode.ForRead);
//获取所有的Polyline
if (ent is Polyline)
{
Polyline sp = (Polyline)ent;
//多边形闭合,则加入到列表
if (sp.Closed)
{
textlist.Add(sp);
}
else//不闭合,则取两边的端点
{
{
Point2d p1 = sp.GetPoint2dAt(0);
Point2d p2 = sp.GetPoint2dAt(1);
for (int i = 0; i < idlist.Length; i++)
{
//是自己的线,不用比较
if (idlist[i] == id)
{
continue;
}
Polyline pl = (Polyline)idlist[i].GetObject(OpenMode.ForRead);
List<double> dislist = new List<double>();
List<Point2d> ptlist = new List<Point2d>();
for (int j = 0; j < pl.NumberOfVertices - 1; j++)
{
Point2d p3 = pl.GetPoint2dAt(j);
Point2d p4 = pl.GetPoint2dAt(j + 1);
//获取交点
Point2d pt = GetIntersection(p1, p2, p3, p4);
//交点在线段上,则不用这条pl
if (IsOnLine(p1, p2, pt))
{
break;
}
//交点在比较的多段线上才做记录
if (IsOnLine(p3, p4, pt))
{
//记录交点和最小距离
dislist.Add(GetMinDis(p1, p2, pt));
ptlist.Add(pt);
}
}
//最近的交点的点
if (dislist.Count > 0)
{
Point2d mypt = ptlist[GetMinIndex(dislist)];
Point3d pt1 = new Point3d(p1.X, p1.Y, 0);
Point3d pt2 = new Point3d(mypt.X, mypt.Y, 0);
Line line = new Line(pt1, pt2);
////将图形对象的信息添加到块表记录中,并返回ObjectId对象.
btr.AppendEntity(line);
////把对象添加到事务处理中.
trans.AddNewlyCreatedDBObject(line, true);
}
}
}
{
Point2d p1 = sp.GetPoint2dAt(sp.NumberOfVertices-1);
Point2d p2 = sp.GetPoint2dAt(sp.NumberOfVertices -2);
for (int i = 0; i < idlist.Length; i++)
{
//是自己的线,不用比较
if (idlist[i] == id)
{
continue;
}
Polyline pl = (Polyline)idlist[i].GetObject(OpenMode.ForRead);
List<double> dislist = new List<double>();
List<Point2d> ptlist = new List<Point2d>();
for (int j = 0; j < pl.NumberOfVertices - 1; j++)
{
Point2d p3 = pl.GetPoint2dAt(j);
Point2d p4 = pl.GetPoint2dAt(j + 1);
//获取交点
Point2d pt = GetIntersection(p1, p2, p3, p4);
//交点在线段上,则不用这条pl
if (IsOnLine(p1, p2, pt))
{
break;
}
//交点在比较的多段线上才做记录
if (IsOnLine(p3, p4, pt))
{
//记录交点和最小距离
dislist.Add(GetMinDis(p1, p2, pt));
ptlist.Add(pt);
}
}
//最近的交点的点
if (dislist.Count > 0)
{
Point2d mypt = ptlist[GetMinIndex(dislist)];
Point3d pt1 = new Point3d(p1.X, p1.Y, 0);
Point3d pt2 = new Point3d(mypt.X, mypt.Y, 0);
Line line = new Line(pt1, pt2);
////将图形对象的信息添加到块表记录中,并返回ObjectId对象.
btr.AppendEntity(line);
////把对象添加到事务处理中.
trans.AddNewlyCreatedDBObject(line, true);
}
}
}
}
}
}
trans.Commit();
}
}
}
public static int GetMinIndex(List<double> list)
{
double min = list[0];
int index = 0;
for (int i = 0; i < list.Count; i++)
{
if (min > list[i])
{
min = list[i];
index = i;
}
}
return index;
}
//获取最小的距离
public static double GetMinDis(Point2d p1,Point2d p2,Point2d pt)
{
double d1 = pt.GetDistanceTo(p1);
double d2 = pt.GetDistanceTo(p2);
if (d1 < d2)
{
return d1;
}
return d2;
}
public static bool IsOnLine(Point2d p1,Point2d p2,Point2d pt)
{
if(IsBetween (p1.X,p2.X,pt.X)&& IsBetween (p1.Y,p2.Y,pt.Y))
{
return true;
}
return false;
}
public static bool IsBetween(double x1,double x2,double x)
{
if(x>=x1 && x<= x2)
{
return true;
}
if(x<=x1 && x>=x2)
{
return true;
}
return false;
} |
|