フォローする

.NET - 曲線オブジェクト上の近接点を見つける

更新 : 2017-12-26 05:17:47 UTC

GetPoint メソッドや GetEntity メソッドを使用してユーザ入力を行った時に、
図形の上で入力を行っても、実際の位置は図形上の座標ではない場合があるので、
GetClosestPointTo メソッドを使用して、図形上の座標に変換する必要があります。

オブジェクトスナップが有効の場合は、スナップされているオブジェクトの位置が取得できますが、
スナップがオフの状態や GetEntity メソッドでは、図形上の点では無いと考えられます。

下の例では、GetClosestPointTo メソッドで入力した点を図形上の座標に変換した後に、
GetSplitCurves メソッドを使用して曲線を点で分割しています。

GetSplitCurves メソッドについては、曲線を分割する の記事で紹介しています。

VB.NET

<CommandMethod("BREAKSAMPLE")>
Public Sub BreakSample()
	Dim db = Application.DocumentManager.MdiActiveDocument.Database
	Dim ed = Application.DocumentManager.MdiActiveDocument.Editor
	Dim res1 = ed.GetEntity(vbLf + "点で分割する曲線を選択")
	If res1.Status <> PromptStatus.OK Then Return
	Using trans = db.TransactionManager.StartTransaction()
		Using ent As Entity = trans.GetObject(res1.ObjectId, OpenMode.ForRead)
			If TypeOf ent Is Curve Then
				Dim crv As Curve = ent
				If TypeOf crv Is Circle Or TypeOf crv Is Ellipse Then
					ed.WriteMessage(vbLf + "円、楕円は点で分割できません")
					Return
				End If
				Dim res2 = ed.GetPoint(vbLf + "分割点を指定")
				If res2.Status <> PromptStatus.OK Then Return
				Dim breakPt = crv.GetClosestPointTo(res2.Value, False)
				Dim crvs = crv.GetSplitCurves(New Point3dCollection(New Point3d() {breakPt}))
				If crvs.Count = 0 Then Return
				Dim curSpace As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
				For Each obj As Curve In crvs
					curSpace.AppendEntity(obj)
					trans.AddNewlyCreatedDBObject(obj, True)
				Next
				crv.UpgradeOpen()
				crv.Erase()
			Else
				ed.WriteMessage(vbLf + "選択されたオブジェクトは曲線ではありません")
				Return
			End If
		End Using
		trans.Commit()
	End Using
End Sub
C#
[CommandMethod("BREAKSAMPLE")]
public void BreakSample()
{
	var db = Application.DocumentManager.MdiActiveDocument.Database;
	var ed = Application.DocumentManager.MdiActiveDocument.Editor;
	var res1 = ed.GetEntity("\n点で分割する曲線を選択");
	if (res1.Status != PromptStatus.OK) return;
	using (var trans = db.TransactionManager.StartTransaction())
	{
		using (var ent = trans.GetObject(res1.ObjectId, OpenMode.ForRead) as Entity)
		{
			if(ent is Curve)
			{
				var crv = ent as Curve;						
				if (crv is Circle || crv is Ellipse)
				{
					ed.WriteMessage("\n円、楕円は点で分割できません");
					return;
				}
				var res2 = ed.GetPoint("\n分割点を指定");
				if (res2.Status != PromptStatus.OK) return;
				var breakPt = crv.GetClosestPointTo(res2.Value, false);
				var crvs = crv.GetSplitCurves(new Point3dCollection(new Point3d[] { breakPt }));
				if (crvs.Count == 0) return;
				var curSpace = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
				foreach (Curve obj in crvs)
				{
					curSpace.AppendEntity(obj);
					trans.AddNewlyCreatedDBObject(obj, true);
				}
				crv.UpgradeOpen();
				crv.Erase();
			}
			else
			{
				ed.WriteMessage("\n選択されたオブジェクトは曲線ではありません");
				return;
			}
		}					
		trans.Commit();
	}
}

 

GetClosestPointTo メソッドの extend の値を False ではなく True にすることで、
近接点を求める際に元の曲線オブジェクトを、延長させた結果で計算させることができますが、
Polyline3d オブジェクトなど一部の曲線では、近接点の計算に支障がでるので注意が必要です。

この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています
他にご質問がございましたら、リクエストを送信してください

コメント