.NET - Find COG of linear elem
Here is a prototype C# routine to create a point at the center of gravity of a selection set of lines and/or polylines (without bulges).This example code is in response to the query made in this thread:
http://www.cadtutor.net/forum/showthread.php?t=48143
Limited testing.Use sensible precaution!
To run:
unzip lcog.zip
In AutoCAD:
Command: netload
(navigate to, and load file LCOG.dll)
Command: LCOG
Select linear elements:
// Written by Sean Tessier June 25 2010// Rev1 - Bug fix June 27 2010using System;using System.Collections.Generic;using Autodesk.AutoCAD.Runtime;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.EditorInput;using Autodesk.AutoCAD.Geometry;namespace LinesCOG{ public class CTCommands { public CTCommands() { } static public void LCOGinit() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; Database db = HostApplicationServices.WorkingDatabase; ObjectIdCollection oidColl = new ObjectIdCollection(); WeightedMidCollection wmc = new WeightedMidCollection(); PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\nSelect linear elements: "; pso.SinglePickInSpace = true; pso.SingleOnly = true; Vector3d v3d = new Vector3d(0.0, 0.0, 1.0); //Only process lines and polylines with an elevation of 0 TypedValue[] filter = { new TypedValue(-4, "") }; SelectionFilter selFilter = new SelectionFilter(filter); bool Canceled = false; using (Transaction trans = db.TransactionManager.StartTransaction()) { do { PromptSelectionResult result = ed.GetSelection(pso, selFilter); if (result.Status == PromptStatus.OK) { ObjectId[] oids = result.Value.GetObjectIds(); foreach (ObjectId oid in oids) { if (!oidColl.Contains(oid)) { oidColl.Add(oid); Line ln = trans.GetObject(oid, OpenMode.ForRead) as Line; if (ln != null) { Point3d stpt = ln.StartPoint; Point3d ndpt = ln.EndPoint; if (stpt.Z == 0.0 && ndpt.Z == 0.0)//only process lines on the WCS XY { ln.Highlight(); WeightedMid wm = new WeightedMid(new Point2d(ln.StartPoint.X, ln.StartPoint.Y), new Point2d(ln.EndPoint.X, ln.EndPoint.Y)); wmc.Add(wm); } } else { Polyline pln = trans.GetObject(oid, OpenMode.ForRead) as Polyline; if (pln != null && !pln.HasBulges)//exclude polylines with bulges { for (int i = 0; i < pln.NumberOfVertices - 1; i++) { WeightedMid wm = new WeightedMid(pln.GetPoint2dAt(i), pln.GetPoint2dAt(i + 1)); wmc.Add(wm); } pln.Highlight(); if (!oidColl.Contains(oid)) oidColl.Add(oid); } } } } ed.WriteMessage("\nPocessing " + oidColl.Count.ToString() + " linear elements"); } else Canceled = true; } while (!Canceled); if (oidColl.Count == 0) return; wmc.ProccessMids(); if (wmc.IsValid) { try { DBPoint COGpt = new DBPoint(wmc.COG); BlockTableRecord btr = (BlockTableRecord)(trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)); btr.AppendEntity(COGpt); trans.AddNewlyCreatedDBObject(COGpt, true); } catch { ed.WriteMessage("\nExecution Error:Operation cancelled!"); } finally { foreach (ObjectId oid in oidColl)//remove highlighting { Entity ent = trans.GetObject(oid, OpenMode.ForRead) as Entity; ent.Unhighlight(); } } } else ed.WriteMessage("\nOperation aborted!"); trans.Commit(); } } } struct WeightedMid //Process individual lines { //fields public double X; public double Y; public double MomentX; public double MomentY; public double length; //Constructor public WeightedMid(Point2d StartPoint, Point2d EndPoint) { X = (StartPoint.X + EndPoint.X) / 2.0; Y = (StartPoint.Y + EndPoint.Y) / 2.0; length = StartPoint.GetDistanceTo(EndPoint); MomentX = length * X; MomentY = length * Y; } } class WeightedMidCollection : List //Process lines as a collection { //Fields private double m_totLength; private Point3d m_cog; private double m_combinedXMoments; private double m_combinedYMoments; private bool m_isValid = false; //Constructor public WeightedMidCollection() { } //Properties public Point3d COG { get { return m_cog; } } public bool IsValid { get { return m_isValid; } } //Methods public void ProccessMids() { foreach (WeightedMid wm in this) { m_totLength += wm.length; m_combinedXMoments += wm.MomentX; m_combinedYMoments += wm.MomentY; } try { m_cog = new Point3d(m_combinedXMoments / m_totLength, m_combinedYMoments / m_totLength, 0.0); m_isValid = true; } catch { m_isValid = false; } } }}
LCOG_rev2.zip SEANT, i get a fatal error when I try and use LCOG, got any ideas why? That’s not good.AutoCAD 2009 is the platform with which I debugged and compiled.Conceivably, though, it should work with anything 2007+
Are you using the 64bit version?Is there any additional information you can give me? As far as i know its just normal full version 2009, the only difference is its a floating version so the license is on our server as we also run 2006LT.
Later on today I will see if it works on a different computer. I’m not sure what the ramifications are with regard to floating licenses.I’ll look into that asap.
The LCOG.dll should be run from a local drive (i.e., not from a server).Is that the case? that could be the problem I will more it to a local drive and give it a go that was the problem, needed to be on a local drive Cool.I've got to remember to make that known up front.
Thanks. Now its working I have noticed if i select the polylines using LCOG I get a point, then if I do it again I get another point, but its in a slightly different location. Could you put that geometry in a separate file and upload it here?
页:
[1]
2