Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Computational geometry with Shapely - create geometries, boolean operations, measurements, predicates
.claude/skills/shapely-compute/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 17% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 54% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 119% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 65% | 0% |
| I want to... | Command | Example | |--------------|---------|---------| | Create geometry | create | create polygon --coords "0,0 1,0 1,1 0,1" | | Intersection | op intersection | op intersection --g1 "POLYGON(...)" --g2 "POLYGON(...)" | | Check contains | pred contains | pred contains --g1 "POLYGON(...)" --g2 "POINT(0.5 0.5)" | | Calculate area | measure area | measure area --geom "POLYGON(...)" | | Distance | distance | distance --g1 "POINT(0 0)" --g2 "POINT(3 4)" | | Transform | transform translate | transform translate --geom "..." --params "1,2" | | Validate | validate | validate --geom "POLYGON(...)" |
Create geometric objects from coordinates.
bash# Point uv run python scripts/shapely_compute.py create point --coords "1,2" # Line (2+ points) uv run python scripts/shapely_compute.py create line --coords "0,0 1,1 2,0" # Polygon (3+ points, auto-closes) uv run python scripts/shapely_compute.py create polygon --coords "0,0 1,0 1,1 0,1" # Polygon with hole uv run python scripts/shapely_compute.py create polygon --coords "0,0 10,0 10,10 0,10" --holes "2,2 8,2 8,8 2,8" # MultiPoint uv run python scripts/shapely_compute.py create multipoint --coords "0,0 1,1 2,2" # MultiLineString (pipe-separated lines) uv run python scripts/shapely_compute.py create multilinestring --coords "0,0 1,1|2,2 3,3" # MultiPolygon (pipe-separated polygons) uv run python scripts/shapely_compute.py create multipolygon --coords "0,0 1,0 1,1 0,1|2,2 3,2 3,3 2,3"
Boolean geometry operations.
bash# Intersection of two polygons uv run python scripts/shapely_compute.py op intersection \ --g1 "POLYGON((0 0,2 0,2 2,0 2,0 0))" \ --g2 "POLYGON((1 1,3 1,3 3,1 3,1 1))" # Union uv run python scripts/shapely_compute.py op union --g1 "POLYGON(...)" --g2 "POLYGON(...)" # Difference (g1 - g2) uv run python scripts/shapely_compute.py op difference --g1 "POLYGON(...)" --g2 "POLYGON(...)" # Symmetric difference (XOR) uv run python scripts/shapely_compute.py op symmetric_difference --g1 "..." --g2 "..." # Buffer (expand/erode) uv run python scripts/shapely_compute.py op buffer --g1 "POINT(0 0)" --g2 "1.5" # Convex hull uv run python scripts/shapely_compute.py op convex_hull --g1 "MULTIPOINT((0 0),(1 1),(0 2),(2 0))" # Envelope (bounding box) uv run python scripts/shapely_compute.py op envelope --g1 "POLYGON(...)" # Simplify (reduce points) uv run python scripts/shapely_compute.py op simplify --g1 "LINESTRING(...)" --g2 "0.5"
Spatial relationship tests (returns boolean).
bash# Does polygon contain point? uv run python scripts/shapely_compute.py pred contains \ --g1 "POLYGON((0 0,2 0,2 2,0 2,0 0))" \ --g2 "POINT(1 1)" # Do geometries intersect? uv run python scripts/shapely_compute.py pred intersects --g1 "..." --g2 "..." # Is g1 within g2? uv run python scripts/shapely_compute.py pred within --g1 "POINT(1 1)" --g2 "POLYGON(...)" # Do geometries touch (share boundary)? uv run python scripts/shapely_compute.py pred touches --g1 "..." --g2 "..." # Do geometries cross? uv run python scripts/shapely_compute.py pred crosses --g1 "LINESTRING(...)" --g2 "LINESTRING(...)" # Are geometries disjoint (no intersection)? uv run python scripts/shapely_compute.py pred disjoint --g1 "..." --g2 "..." # Do geometries overlap? uv run python scripts/shapely_compute.py pred overlaps --g1 "..." --g2 "..." # Are geometries equal? uv run python scripts/shapely_compute.py pred equals --g1 "..." --g2 "..." # Does g1 cover g2? uv run python scripts/shapely_compute.py pred covers --g1 "..." --g2 "..." # Is g1 covered by g2? uv run python scripts/shapely_compute.py pred covered_by --g1 "..." --g2 "..."
Geometric measurements.
bash# Area (polygons) uv run python scripts/shapely_compute.py measure area --geom "POLYGON((0 0,1 0,1 1,0 1,0 0))" # Length (lines, polygon perimeter) uv run python scripts/shapely_compute.py measure length --geom "LINESTRING(0 0,3 4)" # Centroid uv run python scripts/shapely_compute.py measure centroid --geom "POLYGON((0 0,2 0,2 2,0 2,0 0))" # Bounds (minx, miny, maxx, maxy) uv run python scripts/shapely_compute.py measure bounds --geom "POLYGON(...)" # Exterior ring (polygon only) uv run python scripts/shapely_compute.py measure exterior_ring --geom "POLYGON(...)" # All measurements at once uv run python scripts/shapely_compute.py measure all --geom "POLYGON((0 0,2 0,2 2,0 2,0 0))"
Distance between geometries.
bashuv run python scripts/shapely_compute.py distance --g1 "POINT(0 0)" --g2 "POINT(3 4)" # Returns: {"distance": 5.0, "g1_type": "Point", "g2_type": "Point"}
Affine transformations.
bash# Translate (move) uv run python scripts/shapely_compute.py transform translate \ --geom "POLYGON((0 0,1 0,1 1,0 1,0 0))" --params "5,10" # params: dx,dy or dx,dy,dz # Rotate (degrees, around centroid by default) uv run python scripts/shapely_compute.py transform rotate \ --geom "POLYGON((0 0,1 0,1 1,0 1,0 0))" --params "45" # params: angle or angle,origin_x,origin_y # Scale (from centroid by default) uv run python scripts/shapely_compute.py transform scale \ --geom "POLYGON((0 0,1 0,1 1,0 1,0 0))" --params "2,2" # params: sx,sy or sx,sy,origin_x,origin_y # Skew uv run python scripts/shapely_compute.py transform skew \ --geom "POLYGON(...)" --params "15,0" # params: xs,ys (degrees)
Check and fix geometry validity.
bash# Check if valid uv run python scripts/shapely_compute.py validate --geom "POLYGON((0 0,1 0,1 1,0 1,0 0))" # Returns: {"is_valid": true, "type": "Polygon", ...} # Fix invalid geometry (self-intersecting, etc.) uv run python scripts/shapely_compute.py makevalid --geom "POLYGON((0 0,2 2,2 0,0 2,0 0))"
Extract coordinates from geometry.
bashuv run python scripts/shapely_compute.py coords --geom "POLYGON((0 0,1 0,1 1,0 1,0 0))" # Returns: {"coords": [[0,0],[1,0],[1,1],[0,1],[0,0]], "type": "Polygon"}
Parse WKT and get geometry information.
bashuv run python scripts/shapely_compute.py fromwkt "POLYGON((0 0,1 0,1 1,0 1,0 0))" # Returns: {"type": "Polygon", "bounds": [...], "area": 1.0, ...}
point - Single coordinate (x, y) or (x, y, z)line/linestring - Sequence of connected pointspolygon - Closed shape with optional holesmultipoint, multilinestring, multipolygon - Collections"0,0 1,0 1,1 0,1" (space-separated x,y pairs)"POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))"All commands return JSON with:
wkt: WKT representation of result geometrytype: Geometry type (Point, LineString, Polygon, etc.)bounds: (minx, miny, maxx, maxy)is_valid, is_empty: Validity flags| Use Case | Command | |----------|---------| | Collision detection | pred intersects | | Point-in-polygon | pred contains | | Area calculation | measure area | | Buffer zones | op buffer | | Shape combination | op union | | Shape subtraction | op difference | | Bounding box | op envelope or measure bounds | | Simplify path | op simplify |
/math-mode - Full math orchestration (SymPy, Z3)/math-plot - Visualization with matplotlib| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 4,274 | 4,001 | -6% | 1 | 1 | 0% | 959 | 3,344 | +249% | 0 | 0 | — |
case-02 | fail→fail | 19,006 | 5,937 | -69% | 1 | 1 | 0% | 4,529 | 3,065 | -32% | 0 | 0 | — |
case-03 | fail→fail | 21,312 | 6,085 | -71% | 1 | 1 | 0% | 4,577 | 3,115 | -32% | 0 | 0 | — |
case-04 | fail→pass | 13,646 | 3,790 | -72% | 1 | 1 | 0% | 2,952 | 3,442 | +17% | 0 | 0 | — |
case-17 | pass→pass | 8,127 | 2,664 | -67% | 1 | 1 | 0% | 1,436 | 3,200 | +123% | 0 | 0 | — |
case-05 | fail→pass | 12,993 | 3,366 | -74% | 1 | 1 | 0% | 2,086 | 3,357 | +61% | 0 | 0 | — |
case-06 | fail→pass | 10,309 | 3,452 | -67% | 1 | 1 | 0% | 2,138 | 3,299 | +54% | 0 | 0 | — |
case-07 | pass→pass | 9,609 | 4,838 | -50% | 1 | 1 | 0% | 1,829 | 3,623 | +98% | 0 | 0 | — |
case-08 | fail→pass | 7,811 | 2,732 | -65% | 1 | 1 | 0% | 1,454 | 3,181 | +119% | 0 | 0 | — |
case-09 | pass→pass | 6,690 | 2,612 | -61% | 1 | 1 | 0% | 996 | 3,138 | +215% | 0 | 0 | — |
case-10 | pass→pass | 9,605 | 4,240 | -56% | 1 | 1 | 0% | 1,724 | 3,496 | +103% | 0 | 0 | — |
case-11 | pass→pass | 11,824 | 4,548 | -62% | 1 | 1 | 0% | 2,065 | 3,552 | +72% | 0 | 0 | — |
case-12 | fail→pass | 11,959 | 4,032 | -66% | 1 | 1 | 0% | 1,983 | 3,272 | +65% | 0 | 0 | — |
case-13 | fail→pass | 8,243 | 3,317 | -60% | 1 | 1 | 0% | 1,527 | 3,319 | +117% | 0 | 0 | — |
case-14 | fail→pass | 6,002 | 2,358 | -61% | 1 | 1 | 0% | 1,160 | 3,096 | +167% | 0 | 0 | — |
case-15 | fail→pass | 6,296 | 2,661 | -58% | 1 | 1 | 0% | 1,054 | 3,105 | +195% | 0 | 0 | — |
case-16 | fail→pass | 7,757 | 3,159 | -59% | 1 | 1 | 0% | 1,475 | 3,304 | +124% | 0 | 0 | — |
case-18 | fail→pass | 9,578 | 4,672 | -51% | 1 | 1 | 0% | 1,890 | 3,524 | +86% | 0 | 0 | — |
case-19 | pass→pass | 10,150 | 5,287 | -48% | 1 | 1 | 0% | 1,661 | 3,656 | +120% | 0 | 0 | — |
case-20 | fail→fail | 9,892 | 11,405 | +15% | 1 | 1 | 0% | 1,892 | 4,990 | +164% | 0 | 0 | — |
case-21 | fail→fail | 8,397 | 6,167 | -27% | 1 | 1 | 0% | 1,592 | 3,763 | +136% | 0 | 0 | — |
case-22 | fail→pass | 13,005 | 8,108 | -38% | 1 | 1 | 0% | 1,892 | 4,175 | +121% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +50 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/23/2026 | +30% |
Other measured skills in the registry, with their headline benchmark lift.