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 2010 using 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;[assembly: CommandClass(typeof(LinesCOG.CTCommands))]namespace LinesCOG{ public class CTCommands { public CTCommands() { } [CommandMethod("LCOG")] 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