|
C#打断曲线的方法
一直就不喜欢在程序里用AutoCAD命令,在.Net里还有AutoCAD命令与Editor及事务提交之间纠缠不清的关系,特别是三者的次序我实在搞不清楚,托管类里没有打断曲线的方法,AutoCAD的Break命令用起来不顺手,而且还担心不可靠.只好自己写一个打断曲线的方法,各位或许会用得上.花了一个很晚的晚上和一个很早的早上.可以打断直线,圆弧,圆,椭圆,椭圆弧,轻型多义线(封闭和开口的),Xline及射线.
源代码 : 叶开.Sieben
/// <summary>
/// curveid Object must have existed in Database
/// Can break Line | Arc | Circle | Ellipse | Polyline | Xline | Ray
/// </summary>
/// <param name="p1">第一个打断点 </param>
/// <param name="p2">第二个打断点</param>
/// <param name="curveid">要打断曲线的ObjectId</param>
/// <returns></returns>
public static bool BreakCurve(Point3d p1, Point3d p2, ObjectId curveid)
{
//pcm.WriteLine("BreakCurve start", 0);
try
{
Database cdb = curveid.Database;
using (Transaction ctrans = cdb.TransactionManager.StartTransaction())
{
Curve cur = (Curve)ctrans.GetObject(curveid, OpenMode.ForWrite);
Point3d p11 = cur.GetClosestPointTo(p1, false);
Point3d p21 = cur.GetClosestPointTo(p2, false);
#region Break Line
if (cur is Line)
{
//pcm.WriteLine("Break Line start ", 1);
Line l1 = (Line)cur;
Line l2 = (Line)l1.Clone();
if (l1.GetDistAtPoint(p11) < l1.GetDistAtPoint(p21))
{
l2.StartPoint = p21;
l1.EndPoint = p11;
}
else
{
l2.StartPoint = p11;
l1.EndPoint = p21;
}
DrawEntity(l2);
}
#endregion Break Line
#region Break Arc
if (cur is Arc)
{//pcm.WriteLine("Break Arc start ", 1);
Arc arc1 = (Arc)cur;
Arc arc2 = (Arc)arc1.Clone();
Vector3d v11 = arc1.StartPoint.GetVectorTo(arc1.Center);
Vector3d v12 = arc1.EndPoint.GetVectorTo(arc1.Center);
Vector3d v21 = p11.GetVectorTo(arc1.Center);
Vector3d v22 = p21.GetVectorTo(arc1.Center);
if (v11.GetAngleTo(v21, Vector3d.ZAxis) < v11.GetAngleTo(v22, Vector3d.ZAxis))
{
arc2.EndAngle = arc1.StartAngle + v11.GetAngleTo(v21, Vector3d.ZAxis);
arc1.StartAngle += v11.GetAngleTo(v22, Vector3d.ZAxis);
}
else
{
arc2.EndAngle = arc1.StartAngle + v11.GetAngleTo(v22, Vector3d.ZAxis);
arc1.StartAngle += v11.GetAngleTo(v21, Vector3d.ZAxis);
}
DrawEntity(arc2);
}
#endregion Break Arc
#region Break Circle
if (cur is Circle)
{//pcm.WriteLine("Break Circle start ", 1);
Circle c1 = (Circle)cur;
Vector3d v1 = p11.GetVectorTo(c1.Center);
Vector3d v2 = p21.GetVectorTo(c1.Center);
Arc arc1 = new Arc();
arc1.Center = c1.Center;
arc1.SetPropertiesFrom(c1);
arc1.Radius = c1.Radius;
arc1.StartAngle = Vector3d.XAxis.GetAngleTo(v2, Vector3d.ZAxis);
arc1.EndAngle = arc1.StartAngle + v2.GetAngleTo(v1, Vector3d.ZAxis);
c1.Erase();
DrawEntity(arc1);
}
#endregion Break Circle
#region Break Ellipse
if (cur is Ellipse)
{
//pcm.WriteLine("Break Ellipse start ", 1);
Ellipse ell1 = (Ellipse)cur;
if (ell1.Closed)
{
// pcm.WriteLine("Ellipse closed ", 1);
Vector3d v1 = p11.GetVectorTo(ell1.Center);
Vector3d v2 = p21.GetVectorTo(ell1.Center);
ell1.StartAngle = ell1.MajorAxis.GetAngleTo(v2, Vector3d.ZAxis);
ell1.EndAngle = ell1.StartAngle + v2.GetAngleTo(v1, Vector3d.ZAxis);
}
else
{
//pcm.WriteLine("Ellipse opened ", 1);
Ellipse ell2 = (Ellipse)ell1.Clone();
Vector3d v11 = ell1.StartPoint.GetVectorTo(ell1.Center);
Vector3d v12 = ell1.EndPoint.GetVectorTo(ell1.Center);
Vector3d v21 = p11.GetVectorTo(ell1.Center);
Vector3d v22 = p21.GetVectorTo(ell1.Center);
if (v11.GetAngleTo(v21, Vector3d.ZAxis) < v11.GetAngleTo(v22, Vector3d.ZAxis))
{
ell2.EndAngle = ell1.StartAngle + v11.GetAngleTo(v21, Vector3d.ZAxis);
ell1.StartAngle += v11.GetAngleTo(v22, Vector3d.ZAxis);
}
else
{
ell2.EndAngle = ell1.StartAngle + v11.GetAngleTo(v22, Vector3d.ZAxis);
ell1.StartAngle += v11.GetAngleTo(v21, Vector3d.ZAxis);
}
DrawEntity(ell2);
}
}
#endregion Break Ellipse
#region Break Polyline
if (cur is Polyline)
{
//pcm.WriteLine("Break PolyLine start ", 1);
Polyline pl1 = (Polyline)cur;
double param11 = pl1.GetParameterAtPoint(p11);
double param12 = pl1.GetParameterAtPoint(p21);
double param21 = Math.Min(param11, param12);
double param22 = Math.Max(param11, param12);
if (pl1.Closed)
{
#region Polyline closed
pcm.WriteLine("PolyLine closed ", 1);
Polyline pl2 = new Polyline();
pl2.SetPropertiesFrom(pl1);
double len11 = pl1.GetDistanceAtParameter(param21) + pl1.GetDistanceAtParameter(pl1.EndParam) - pl1.GetDistanceAtParameter(param22);
double len12 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
int param31 = (int)Math.Floor(param21);
int param32 = (int)Math.Floor(param22) + 1;
Point3d p31;
if (len11 > len12)
{
if ((double)param32 != param22)
{
double bul12 = pl1.GetBulgeAt(param32 - 1);
double bul22 = 0;
if (bul12 != 0.0)
{
double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);
double len32 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param22);
bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);
}
p31 = pl1.GetPointAtParameter(param22);
pl2.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul22, 0, 0);
}
for (int i = param32; i < pl1.EndParam; i++)
{
p31 = pl1.GetPointAtParameter(i);
pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
}
for (int i = 0; i <= param31; i++)
{
p31 = pl1.GetPointAtParameter(i);
pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
}
if ((double)param31 != param21)
{
p31 = pl1.GetPointAtParameter(param21);
pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);
double bul11 = pl1.GetBulgeAt(param31);
if (bul11 != 0.0)
{
double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);
double len31 = pl1.GetDistanceAtParameter(param21) - pl1.GetDistanceAtParameter(param31);
if (pl2.NumberOfVertices == 2)
len31 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
double bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);
pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul21);
}
}
}
else
{
if ((double)param31 != param21)
{
double bul11 = pl1.GetBulgeAt(param31);
double bul21 = 0;
if (bul11 != 0.0)
{
double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);
double len31 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param21);
bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);
}
p31 = pl1.GetPointAtParameter(param21);
pl2.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul21, 0, 0);
}
for (int i = param31 + 1; i <= param32 - 1; i++)
{
p31 = pl1.GetPointAtParameter(i);
pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
}
if ((double)param32 != param22)
{
p31 = pl1.GetPointAtParameter(param22);
pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);
double bul12 = pl1.GetBulgeAt(param32 - 1);
if (bul12 != 0.0)
{
double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);
double len32 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param32 - 1);
if (pl2.NumberOfVertices == 2)
len32 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
double bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);
pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul22);
}
}
}
#endregion Polyline closed
DrawEntity(pl2);
}
else
{
#region Polyline opened
//pcm.WriteLine("PolyLine opend ", 1);
Polyline pl2 = new Polyline();
pl2.SetPropertiesFrom(pl1);
double len11 = pl1.GetDistanceAtParameter(param21) + pl1.GetDistanceAtParameter(pl1.EndParam) - pl1.GetDistanceAtParameter(param22);
double len12 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
int param31 = (int)Math.Floor(param21);
int param32 = (int)Math.Floor(param22) + 1;
Point3d p31;
for (int i = 0; i < param21; i++)
{
p31 = pl1.GetPointAtParameter(i);
pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
}
if ((double)param31 != param21)
{
p31 = pl1.GetPointAtParameter(param21);
pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);
double bul11 = pl1.GetBulgeAt(param31);
if (bul11 != 0.0)
{
double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);
double len31 = pl1.GetDistanceAtParameter(param21) - pl1.GetDistanceAtParameter(param31);
if (pl2.NumberOfVertices == 2)
len31 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
double bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);
pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul21);
}
}
Polyline pl3 = new Polyline();
pl3.SetPropertiesFrom(pl1);
if ((double)param32 != param22)
{
double bul12 = pl1.GetBulgeAt(param32 - 1);
double bul22 = 0;
if (bul12 != 0.0)
{
double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);
double len32 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param22);
bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);
}