TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
shape.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// Exact integer geometry for clearance checks (design doc 03 §1).
4//
5// Every copper shape is a "rounded core": a point, an open polyline or a closed polygon, inflated by a
6// radius r. Tracks are 2-point polylines with r = width/2, round pads are points, ovals are segments,
7// round-rect pads are rectangles shrunk by the corner radius and inflated back. Gap tests compare squared
8// distances in 128-bit integers, so "closer than" decisions are exact.
9#include <cstdint>
10#include <vector>
11
12#include "geom/point.hpp"
13
14namespace tmk::geom {
15
16__extension__ using i128 = __int128; // GCC extension; exact products of nm coordinates
17
18struct Shape {
19 std::vector<Point> pts; // 1 point, open polyline (>= 2), or closed polygon (>= 3)
20 Coord r = 0; // inflation radius
21 bool closed = false; // polygon interior is part of the shape
22 Box box; // bounding box including r
23
24 static Shape point(Point p, Coord r);
25 static Shape segment(Point a, Point b, Coord r);
26 static Shape polyline(std::vector<Point> pts, Coord r);
27 static Shape polygon(std::vector<Point> pts, Coord r = 0);
28 void update_box();
29 // Reset to a disk, reusing point storage for scratch legality checks.
31};
32
33// Orientation of c relative to a→b: >0 left (counter-clockwise in y-up math terms), <0 right, 0 collinear.
34inline i128 orient(Point a, Point b, Point c) {
35 return static_cast<i128>(b.x - a.x) * (c.y - a.y) - static_cast<i128>(b.y - a.y) * (c.x - a.x);
36}
37
38// True if closed segments ab and cd share at least one point.
40
41// True if the distance from p to segment ab is strictly less than t (t >= 0).
43
44// True if the distance between segments ab and cd is strictly less than t (t >= 0).
46
47// Distances in nm (not squared), for reporting (long double).
48long double point_seg_dist(Point p, Point a, Point b);
49long double seg_seg_dist(Point a, Point b, Point c, Point d);
50
51// Point in closed polygon (boundary counts as inside).
52bool point_in_polygon(Point p, const std::vector<Point>& poly);
53
54// True if the gap between the two shapes (distance between their surfaces, negative when they overlap) is
55// strictly less than `clearance`. clearance may be 0 (then: do they overlap or touch? no — strictly overlap).
56bool closer_than(const Shape& a, const Shape& b, Coord clearance);
57// Equivalent to closer_than(a, Shape::point(c, r), clearance), without allocating.
58bool closer_than_disk(const Shape& a, Point c, Coord r, Coord clearance);
59
60// Gap between two shapes in nm (negative = overlap depth bound; 0 when cores touch with r = 0).
61double gap(const Shape& a, const Shape& b);
62
63// Flattens a circular arc through start/mid/end into points with sagitta error <= max_error.
64std::vector<Point> arc_points(Point start, Point mid, Point end, Coord max_error = 5'000);
65// Circle outline as a closed polyline (first point repeated at the end).
66std::vector<Point> circle_points(Point centre, Coord radius, Coord max_error = 5'000);
67// Convex hull, counter-clockwise in a y-up frame, no repeated point (Andrew's monotone chain, 1979; exact
68// integer orientation tests). Fewer than three distinct points are returned sorted.
69std::vector<Point> convex_hull(std::vector<Point> pts);
70
71} // namespace tmk::geom
bool segments_intersect(Point a, Point b, Point c, Point d)
True if closed segments ab and cd share at least one point.
__int128 i128
GCC extension; exact products of nm coordinates.
Definition shape.hpp:16
bool seg_seg_closer(Point a, Point b, Point c, Point d, Coord t)
True if the distance between segments ab and cd is strictly less than t (t >= 0).
std::vector< Point > circle_points(Point centre, Coord radius, Coord max_error=5 '000)
Circle outline as a closed polyline (first point repeated at the end).
long double point_seg_dist(Point p, Point a, Point b)
Distances in nm (not squared), for reporting (long double).
double gap(const Shape &a, const Shape &b)
Gap between two shapes in nm (negative = overlap depth bound; 0 when cores touch with r = 0).
std::vector< Point > arc_points(Point start, Point mid, Point end, Coord max_error=5 '000)
Flattens a circular arc through start/mid/end into points with sagitta error <= max_error.
i128 orient(Point a, Point b, Point c)
Orientation of c relative to a→b: >0 left (counter-clockwise in y-up math terms), <0 right,...
Definition shape.hpp:34
bool closer_than_disk(const Shape &a, Point c, Coord r, Coord clearance)
Equivalent to closer_than(a, Shape::point(c, r), clearance), without allocating.
bool point_seg_closer(Point p, Point a, Point b, Coord t)
True if the distance from p to segment ab is strictly less than t (t >= 0).
bool point_in_polygon(Point p, const std::vector< Point > &poly)
Point in closed polygon (boundary counts as inside).
bool closer_than(const Shape &a, const Shape &b, Coord clearance)
True if the gap between the two shapes (distance between their surfaces, negative when they overlap) ...
long double seg_seg_dist(Point a, Point b, Point c, Point d)
std::vector< Point > convex_hull(std::vector< Point > pts)
Convex hull, counter-clockwise in a y-up frame, no repeated point (Andrew's monotone chain,...
std::int64_t Coord
Engine coordinate: signed 64-bit nanometres.
Definition units.hpp:12
Integer-nanometre points and KiCad-compatible rotation.
static Shape polyline(std::vector< Point > pts, Coord r)
static Shape polygon(std::vector< Point > pts, Coord r=0)
Box box
bounding box including r
Definition shape.hpp:22
void set_point(Point p, Coord r)
Reset to a disk, reusing point storage for scratch legality checks.
Coord r
inflation radius
Definition shape.hpp:20
std::vector< Point > pts
1 point, open polyline (>= 2), or closed polygon (>= 3)
Definition shape.hpp:19
bool closed
polygon interior is part of the shape
Definition shape.hpp:21
static Shape point(Point p, Coord r)
static Shape segment(Point a, Point b, Coord r)