GeometryHelper.ArrangeAlgorithms 4.0.0

Suggested Alternatives

GeometryHelper

Additional Details

merge project

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package GeometryHelper.ArrangeAlgorithms --version 4.0.0
                    
NuGet\Install-Package GeometryHelper.ArrangeAlgorithms -Version 4.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GeometryHelper.ArrangeAlgorithms" Version="4.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GeometryHelper.ArrangeAlgorithms" Version="4.0.0" />
                    
Directory.Packages.props
<PackageReference Include="GeometryHelper.ArrangeAlgorithms" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GeometryHelper.ArrangeAlgorithms --version 4.0.0
                    
#r "nuget: GeometryHelper.ArrangeAlgorithms, 4.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GeometryHelper.ArrangeAlgorithms@4.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GeometryHelper.ArrangeAlgorithms&version=4.0.0
                    
Install as a Cake Addin
#tool nuget:?package=GeometryHelper.ArrangeAlgorithms&version=4.0.0
                    
Install as a Cake Tool

GeometryHelper.ArrangeAlgorithms

NuGet Version NuGet Downloads License: MIT

2D label placement for engineering drawings: given a set of labels, each associated with a guide segment and surrounding blocked regions, the library calculates translation vectors that keep labels from overlapping each other and from encroaching on the blocked regions.

It depends on AutoCAD and Tekla for nothing. The geometry it works in comes from GeometryHelper.PlaneGeometry, which comes with this package as a dependency.

Installation

dotnet add package GeometryHelper.ArrangeAlgorithms

GeometryHelper.PlaneGeometry and GeometryHelper.CommonGeometry come with it as dependencies.

Visual Examples

AutoCAD Integration

Here are some examples of labels arranged inside AutoCAD to avoid overlaps and blocked regions:

Greedy Force Directed
Greedy Force Directed

Tekla Structures Integration

Here is an example of reinforcement marks before and after arrangement:

Before Arrangement After Arrangement
Before Arrangement After Arrangement
Arranged Marks Avoiding Dimension Obstacles
Tekla Result Detail

Quick Start

var leader = new GeoLine2(0.0, 0.0, 2000.0, 0.0);

var arranges = new List<Arrange>
{
    new Arrange
    {
        // Label bounding box: center, width, height, rotation angle (radians, counter-clockwise)
        GeoRectangle2 = new GeoRectangle2(new GeoPoint2(1000.0, 0.0), 2000.0, 1000.0),
        // Guide segment: its midpoint is the origin for candidate positions expansion
        GeoLine2      = leader,
        // Minimum perpendicular offset between label edge and guide segment, specific to this label (default 50)
        MarkOffsetFromLine = 50.0,
        // Blocked regions the label must not overlap
        BlockPolygons = new List<GeoPolygon2>(),
        BlockLines    = new List<GeoLine2>()
    }
};

// Returns translation vector for each label, in the exact input order.
// Each Arrange object is also automatically updated: arranges[i].TranslationVector contains the same vector.
List<GeoVector2> moves = Arrange.Run(arranges);

for (int i = 0; i < arranges.Count; i++)
{
    // You can use the returned 'moves[i]' or read the property directly:
    GeoVector2 move = arranges[i].TranslationVector; 
    
    GeoPoint2 newPosition = arranges[i].GeoRectangle2.Center + move;
    bool isPlaced = arranges[i].Placed; // false = forced to fallback, still has overlap
}

To change the algorithm or fine-tune parameters, pass ArrangeOptions:

var options = new ArrangeOptions
{
    Algorithm           = ArrangeAlgorithmType.BoundedBacktracking,
    RowGap              = 20.0,
    PerpendicularLevels = 3
};

List<GeoVector2> moves = Arrange.Run(arranges, options);

ArrangeOptions is the shared configuration for the entire list. MarkOffsetFromLine is set per Arrange because each label may require a different offset:

var smallTextLabel = new Arrange
{
    GeoRectangle2 = new GeoRectangle2(new GeoPoint2(1000.0, 0.0), 2000.0, 1000.0),
    GeoLine2      = leader,
    MarkOffsetFromLine = 50.0   // small text, closely sticks to guide segment
};

var largeTextLabel = new Arrange
{
    GeoRectangle2 = new GeoRectangle2(new GeoPoint2(1000.0, 0.0), 4000.0, 2000.0),
    GeoLine2      = leader,
    MarkOffsetFromLine = 200.0  // large text, must move further away
};

List<GeoVector2> moves = Arrange.Run(new List<Arrange> { smallTextLabel, largeTextLabel }, options);

Candidate Positions Generation

All 5 algorithms share the same set of discrete candidate positions, expanding from the midpoint of the guide segment:

  • Perpendicular Translation — each level in PerpendicularLevels creates a row of labels, symmetric on both sides of the guide segment. The first level is placed at half the label height plus the label's own MarkOffsetFromLine. Each subsequent level adds the label height plus RowGap.
  • Longitudinal Sliding — in each row, the label slides parallel to the guide segment in both directions, up to a maximum of half the guide segment length plus LongitudinalOvershootRatio times the label width.

The algorithms only differ in how they select from this candidate set.

Five Algorithms

ArrangeAlgorithmType Selection Strategy Trade-off
Greedy (default) Sequentially places labels, prioritizing the most constrained ones; selects the most open spot in the first group of free candidates Fastest, reproducible results, but prone to local optima
BoundedBacktracking Same as Greedy, but backtracks when subsequent labels are stuck, bounded by MaxBacktrackSteps Higher clean placement rate, slower on crowded drawings
SimulatedAnnealing Global optimization based on a collision-penalty energy function, gradually cooling down Best for extremely crowded drawings, CPU-heavy
ForceDirected Simulates spring and repulsive forces, then maps to the nearest discrete candidate Distributes labels evenly and naturally
ConstraintSatisfaction CSP with MRV heuristic and forward checking Most rigorous, potential combinatorial explosion with large number of labels

BoundedBacktracking and ConstraintSatisfaction automatically fallback to Greedy if no collision-free solution is found, ensuring every label always has a display position.

SimulatedAnnealing uses a fixed seed, so its results are reproducible between runs.

Parameters for each Arrange

Parameter Default Meaning
GeoRectangle2 — Label bounding box, the geometry that will be translated
GeoLine2 — Guide segment; its midpoint is the origin for candidate positions expansion
MarkOffsetFromLine 50.0 Minimum perpendicular offset between label edge and guide segment
BlockPolygons — Blocked polygons that the label must not overlap
BlockLines — Blocked line segments that the label must not overlap

Main Parameters of ArrangeOptions

Parameter Default Meaning
Algorithm Greedy Algorithm to use
RowGap 20.0 Clearance between two consecutive rows of labels
PerpendicularLevels 3 Number of perpendicular fallback levels to test on each side
LongitudinalOvershootRatio 0.75 Ratio of label width allowed to overshoot beyond the two endpoints of the guide segment
MinimumBoxSize 10.0 Labels smaller than this size are ignored
MinimumMoveDistance 0.1 Translations smaller than this threshold are rounded to zero
NeighbourMargin 50.0 Expanded margin when filtering nearby obstacles
PlaceMostConstrainedFirst true Place labels with fewer options first
PlaceFromInsideOut true Prioritize labels close to the area centroid
LookAheadCandidates 3 Number of free positions considered before selection
MaxBacktrackSteps 1000 Cap on the number of backtracking steps
AnnealingInitialTemperature 100.0 Initial temperature for the Simulated Annealing algorithm
AnnealingCoolingRate 0.95 Cooling rate for the Simulated Annealing algorithm
ForceIterations 100 Number of force simulation iterations for the Force-Directed algorithm
Tolerance Tolerance.Global Tolerance for geometric comparisons

Default values are in millimeters, matching conventional structural drawings.

Running inside AutoCAD

GeometryHelper.ArrangeAlgorithms.CadTest builds a DLL file to be loaded into AutoCAD:

dotnet build Samples/GeometryHelper.ArrangeAlgorithms.CadTest/GeometryHelper.ArrangeAlgorithms.CadTest.csproj

The output is located at Samples/GeometryHelper.ArrangeAlgorithms.CadTest/bin/Debug/net48/GeometryHelper.ArrangeAlgorithms.CadTest.dll. Load this file into AutoCAD using the NETLOAD command, then run one of the following commands: T1_Greedy, T1_BoundedBacktracking, T1_SimulatedAnnealing, T1_ForceDirected, T1_ConstraintSatisfaction. Select LINE or LWPOLYLINE objects, and the plugin will draw the label box before and after arrangement, along with statistics.

The project compiles against three AutoCAD assemblies — accoremgd, acdbmgd, acmgd — committed under Libraries/GeometryHelper.CadConvert/Lib and referenced from there by relative path, so no AutoCAD installation is needed to build. Loading the result still needs AutoCAD, which supplies those assemblies at run time.

Running inside Tekla Structures

GeometryHelper.ArrangeAlgorithms.TeklaTest is a console application that connects to the active Tekla Structures model and drawing to arrange reinforcement marks.

To build and run:

  1. Open Tekla Structures and open a drawing with some reinforcement marks and dimensions selected.
  2. Build the project:
    dotnet build Samples/GeometryHelper.ArrangeAlgorithms.TeklaTest/GeometryHelper.ArrangeAlgorithms.TeklaTest.csproj
    
  3. Run the compiled executable:
    Samples/GeometryHelper.ArrangeAlgorithms.TeklaTest/bin/Debug/net48/GeometryHelper.ArrangeAlgorithms.TeklaTest.exe
    

Licence

MIT.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

2D label placement for engineering drawings. Given labels that each carry a guide segment and a
     set of blocked regions, the library returns the translation vectors that keep the labels off each
     other and off the blocked regions.

     - Five algorithms behind one entry point, chosen through ArrangeOptions.Algorithm: Greedy,
       Bounded Backtracking, Simulated Annealing, Force-Directed and Constraint Satisfaction.
     - Arrange.Run fills in a translation for every label; a label that cannot be improved keeps a
       zero vector rather than being dropped from the result.
     - Blocked regions accept both polygons and lines, so dimensions and the rebar centrelines a mark
       must not cross are expressed the same way.
     - Offsets, spacing, iteration counts and the tolerance are all set through ArrangeOptions, whose
       defaults are in millimetres to match conventional structural drawings.
     - It depends on AutoCAD and Tekla for nothing. The geometry comes from
       GeometryHelper.PlaneGeometry, which arrives as a dependency along with
       GeometryHelper.CommonGeometry.