马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 csharp 于 2014-7-2 18:19 编辑
在Help中
[return: MarshalAs(UnmanagedType.U1)]
public virtual bool OnSegmentAt(
int index,
Point2d pt2d,
double value
);
int index
| Input index (0 based) of the vertex
| Point2d pt2d
| Input point (in polyline OCS coords) to check at vertex index
| double value
| Output parameter of at vertex index
|
这个 value 说明是 output parameter ,在 ARX Help 也是这样的,
virtual Adesk::Boolean onSegAt(
unsigned int index,
const AcGePoint2d& pt2d,
double& param) const;
Parameters
| Description
| unsigned int index
| Input index (0 based) of the vertex
| const AcGePoint2d& pt2d
| Input point (in polyline OCS coords) to check at vertex index
| double& param
| Output parameter of at vertex index
|
这是http://adndevblog.typepad.com/autocad/2012/06/use-getclosestpointto-and-onsegat-to-locate-a-polyline-vertex-near-a-point.html
一个例子
static void TEST_PointOnPoly(void)
{
ads_name ename; ads_point pt, ptWcs; AcDbObjectId Id;
if(acedEntSel(_T("Select Pline: "), ename,pt)!=RTNORM) return;
// Convert to WCS incase selection was made // while in a UCS. acdbUcs2Wcs(pt, ptWcs, Adesk::kFalse); acdbGetObjectId(Id,ename); AcDbEntity* pEnt; acdbOpenObject(pEnt,Id,AcDb::kForRead,false);
AcDbPolyline* pLine=NULL; pLine=AcDbPolyline::cast(pEnt);
if(!pLine) { acutPrintf(_T ("Selected Entity not a Polyline")); pEnt->close(); return; }
AcGePoint3d clickpt; // This will convert the pick point to a // point on the polyline pLine->getClosestPointTo(asPnt3d(ptWcs), clickpt); // Convert to 2d point, needed below... AcGePoint2d clickpt2d(clickpt.x, clickpt.y);
for(unsigned int c=0; pLine->numVerts() > c ; c++) { double segParam; // This is the test filter here...it uses the // nifty API onSegAt if(pLine->onSegAt(c, clickpt2d, segParam)) { acutPrintf(_T("Selected Segment: %d \n"),c+1); break; } } pLine->close(); }
在 Net 中测试这个 OnSegmentAt 怎么都没有 output , 自己就写了一个, 可以用来测试自交点所在的实际参数(xdrx_polyline_onsegat)
- // based on article by Wayne Brill
- // http://adndevblog.typepad.com/autocad/2012/06/use-getclosestpointto-and-onsegat-to-locate-a-polyline-vertex-near-a-point.html
- [CommandMethod("oseg")]
- public static void TEST_PointOnPoly()
- {
- Database db = Application.DocumentManager.MdiActiveDocument.Database;
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
- CoordinateSystem3d cs = ed.CurrentUserCoordinateSystem.CoordinateSystem3d;
- Plane plan = new Plane(Point3d.Origin, cs.Zaxis);
- Application.SetSystemVariable("osmode", 512);
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- try
- {
- Entity ename;
- Point3d pt;
- Point3d ptWcs;
- PromptEntityOptions peo = new PromptEntityOptions("\nSelect Pline: ");
- peo.SetRejectMessage("\nYou have to select LWPOLYLINE!");
- peo.AddAllowedClass(typeof(Polyline), false);
- PromptEntityResult res = ed.GetEntity(peo);
- if (res.Status != PromptStatus.OK) return;
- ObjectId id = res.ObjectId;
- // Convert to WCS incase selection was made
- // while in a UCS.
- pt = res.PickedPoint;
- // Transform from UCS to WCS
- Matrix3d mat =
- Matrix3d.AlignCoordinateSystem(
- Point3d.Origin,
- Vector3d.XAxis,
- Vector3d.YAxis,
- Vector3d.ZAxis,
- cs.Origin,
- cs.Xaxis,
- cs.Yaxis,
- cs.Zaxis
- );
- ptWcs = pt.TransformBy(mat);
- ename = tr.GetObject(id, OpenMode.ForRead) as Entity;
- Polyline pline = ename as Polyline;
- if (pline == null)
- {
- ed.WriteMessage("\nSelected Entity is not a Polyline");
- return;
- }
- Point3d clickpt = pline.GetClosestPointTo(ptWcs, false);
- for (int c = 0; c < pline.NumberOfVertices; c++)
- {
- //double segParam = new double();
- double segParam;
- // This is the test filter here...it uses the
- // nifty API OnSegmentAt
- if (MyOnSegmentAt((Curve)ename,c, clickpt, out segParam))
- {
- ed.WriteMessage("\nSelected Segment: {0} \n", c + 1);
- ed.WriteMessage("\nSelected Param: {0} \n", segParam.ToString());
- break;
- }
- }
- }
- catch (System.Exception ex)
- {
- ed.WriteMessage("\n" + ex.Message + "\n" + ex.StackTrace);
- }
- }
- }
- private static bool MyOnSegmentAt(Curve cv, int index, Point3d pt, out double pams )
- {
- Polyline pl = cv as Polyline;
- int numVerts = pl.NumberOfVertices;
- Point2d npt = new Point2d(pt.X, pt.Y);
- for (int i = 0; i < numVerts -1; i++)
- {
- if (pl.OnSegmentAt(i, npt, 0.0))
- {
- SegmentType pType = pl.GetSegmentType(i);
- double iDist = cv.GetDistanceAtParameter((double) i);
- if (pType == SegmentType .Line)
- {
- Point3d p1 = cv.GetPointAtParameter((double)i);
-
- double pDist = p1.DistanceTo( pt);
- pams = cv.GetParameterAtDistance(pDist + iDist);
- return true;
- }
- else if (pType == SegmentType.Arc )
- {
- Point3d sPnt = cv.GetPointAtParameter( (double )i);
- Point3d ePnt = cv.GetPointAtParameter((double) i + 1.0);
- CircularArc3d arc = new CircularArc3d( sPnt ,pt,ePnt );
- Point3d pCen = arc.Center;
- double radius = arc.Radius;
- Vector3d vStart = pCen.GetVectorTo(sPnt);
- Vector3d vPnt = pCen.GetVectorTo(pt);
- double jiajiao = vStart.GetAngleTo(vPnt, vStart);
- double dis = jiajiao * radius;
- pams = cv.GetParameterAtDistance(dis + iDist );
- return true;
- }
- else
- {
- pams = -1;
- return false;
- }
- }
- }
- pams = -1;
- return false;
- }
|