EasyFillet
CAD-grade tangent arc and line extension tool for QGIS • v1.4.7
1. Overview
EasyFillet brings AutoCAD-style FILLET and EXTEND commands into QGIS for geospatial vector editing. Given two line features, the plugin computes a circular tangent arc that smooths the corner between them, trims both source lines to the tangent points, and inserts the arc as a new feature. An Extend mode lengthens a line endpoint to a cursor target with live preview. The tool operates in-place on editable line layers with full CRS awareness, a spatial-index-backed nearest-feature lookup, and persistent parameter memory.
EasyFillet is a dock-free, toolbar-activated interactive map tool. It has no processing provider or model builder integration—it works directly on the QGIS map canvas.
2. Feature Documentation
2.1 Fillet Mode
Tangent Arc Insertion
Two-click workflow: pick the first line, then the second. The plugin computes the intersection of the two lines, determines the tangent points at the specified radius, generates a circular arc, and trims both lines back to the tangent points. The arc is added as a new feature inheriting attributes from the first line.
A live red QgsRubberBand preview shows the arc as the cursor hovers over candidate second lines, using the current radius setting.
In-Place Trimming (default)
Source line geometries are updated via layer.changeGeometry() so their endpoints precisely meet the arc's tangent points. No duplicate features are created. This is the v1.4 default behaviour.
Unchecking Trim originals in place restores the legacy additive mode where original features are preserved and three new features (arc + two trimmed copies) are added—useful for scripting compatibility.
2.2 Extend Mode
Endpoint Extension
Right-click toggles between Fillet and Extend modes. In Extend mode, click near a line endpoint (within the configurable pixel tolerance), then click a target location. The line geometry is updated in-place so its endpoint moves to the target point. Snap-to-endpoint is automatically applied when hovering near another line's endpoint.
2.3 Spatial Index Lookup
Nearest-Feature Query
A per-layer QgsSpatialIndex is built lazily, queried for ~24 nearest candidates per mouse-move, and invalidated automatically on geometry changes, feature additions/deletions, and editing stop signals. Falls back to expanding bounding-box probes when the index returns empty. CRS-transforms the map point to layer CRS before querying.
3. Parameters and Controls
| Parameter | Type | Range | Default | Description |
|---|---|---|---|---|
| Radius | QDoubleSpinBox | 0.001 – 1,000,000 m | 4.0 m | Arc radius; smaller values suit tight corners |
| Endpoint tolerance | QSpinBox | 5 – 200 px | 30 px | Snap radius for Extend mode endpoint detection |
| Arc segments | QSpinBox | 4 – 200 | 24 | Polyline resolution of generated arc; more = smoother |
| Trim originals in place | QCheckBox | on / off | on | When on: replaces source geometries; off: legacy additive mode |
All parameter values are persisted across QGIS sessions via QSettings under PlanX/EasyFillet. Press Space at any time during tool use to reopen the dialog.
4. Workflow Guide
4.1 Fillet Mode
- Click the EasyFillet toolbar icon. The plugin checks the active layer is an editable line layer (offers to start editing if not). The parameter dialog opens.
- Set the desired radius and click OK.
- Click the first line feature. It highlights in blue.
- Move the mouse over a second line. A red preview arc appears at the corner.
- Click the second line. The fillet is applied and a success message reports the radius and corner angle.
- The tool remains active for further operations.
4.2 Extend Mode
- Right-click to toggle to Extend Mode (purple cursor). The status bar reads “Extend Mode.”
- Click near a line endpoint (within the tolerance). The endpoint highlights in green and the line in blue.
- Move the cursor to the target location. A red preview line and red target marker show the proposed extension.
- Click to commit. The line geometry is updated in-place.
4.3 Keyboard Shortcuts
| Key | Action |
|---|---|
| Space | Reopen parameter dialog |
| Escape | Clear current selection without exiting tool |
| Right-click | Toggle between Fillet and Extend modes |
5. Geometry Engine
The core computation in easyfillet_logic.py uses three pure functions with no QGIS dependency beyond QgsGeometry and QgsPointXY:
5.1 Fillet Arc Geometry
Given two infinite lines defined by their segment endpoints, the algorithm:
- Finds the intersection point of the two lines (parallel-line rejection when the denominator is within 1×10−12 of zero).
- Determines which endpoint of each polyline approaches the corner.
- Computes unit direction vectors from the intersection toward those endpoints.
- Derives the angle between direction vectors via dot product and
acos(). - Calculates tangent length:
tan_len = radius / tan(θ / 2). - Validates that neither tangent point falls beyond its segment's far endpoint.
- Places tangent points at distance
tan_lenfrom the intersection along each direction. - Computes the circle centre by walking along the angle bisector at distance
radius / sin(θ / 2). - Shortest-arc fix: clamps the angular difference to (−π, π] to avoid 270° counter-clockwise sweeps.
- Generates arc points as a polyline approximation.
5.2 Line Trimming
trim_line_to_point() determines whether the tangent point is closer to the start or end of the polyline and replaces that endpoint with the tangent point.
6. Technical Notes
- CRS handling: All spatial-index queries transform the canvas point to the layer's CRS via
QgsCoordinateTransform, supporting mixed-CRS projects. - Cursor design: Custom 32×32 px
QPixmapcursors drawn withQPainter—teal-green pen for Fillet mode, purple for Extend mode. - Spatial index invalidation: Four layer signals (
geometryChanged,featureAdded,featuresDeleted,editingStopped) trigger index rebuild. - Cleanup:
unload()callscanvas.unsetMapTool()before clearing the reference to prevent dangling-pointer crashes. - Geometry normalisation: Multi-part geometries use the first part. Features with fewer than 2 points are rejected.
- Feature attributes: The "fid" column is explicitly nulled on new features so QGIS auto-assigns a unique feature ID.
- QGIS compatibility: 3.0 through 4.99. Pure
qgis.core/qgis.gui/qgis.PyQtwith no external dependencies.
7. Literature
- Farin, G. (2002). Curves and Surfaces for CAGD: A Practical Guide (5th ed.). Morgan Kaufmann. DOI: 10.1016/B978-1-55860-737-8.X5000-5
- Nielson, G. M. (1993). Scattered data modeling. IEEE Computer Graphics and Applications, 13(1), 60–70. DOI: 10.1109/38.180122
- de Berg, M., Cheong, O., van Kreveld, M., & Overmars, M. (2008). Computational Geometry: Algorithms and Applications (3rd ed.). Springer. DOI: 10.1007/978-3-540-77974-2
- Guttman, A. (1984). R-trees: a dynamic index structure for spatial searching. Proceedings of the 1984 ACM SIGMOD International Conference on Management of Data, 47–57. DOI: 10.1145/602259.602266