optiwindnet.geometric¶
Module Contents¶
- optiwindnet.geometric.triangle_AR(base1C: CoordPair, base2C: CoordPair, topC: CoordPair) float[source]¶
Calculate the ratio: dist(base1, base2)/dist(base, top).
Numerator is the length of the base of the triagle (base1C, base2C).
Denominator is the distance from point topC to the base line.
- Parameters:
uC – triangle vertices coordinates as (2,) numpy arrays
vC – triangle vertices coordinates as (2,) numpy arrays
tC – triangle vertices coordinates as (2,) numpy arrays
- Returns:
Aspect ratio of the triangle defined by the three 2D points.
- optiwindnet.geometric.point_d2line(pC: CoordPair, uC: CoordPair, vC: CoordPair) numpy.float64[source]¶
Calculate the distance from point pC to the uC-vC line.
- optiwindnet.geometric.is_same_side(uC: CoordPair, vC: CoordPair, sC: CoordPair, tC: CoordPair, touch_is_cross: bool = True) bool[source]¶
Check if points sC an tC are on the same side of the line defined by points uC and vC.
Note: often used to check crossings with feeder links, where the feeder link sC-tC is already known to be on a line that crosses the edge uC–vC (using the angle rank).
- optiwindnet.geometric.any_pairs_opposite_edge(nodesC: CoordPairs, uC: CoordPair, vC: CoordPair, margin: float = 0.0) bool[source]¶
Compare relative position of vertices wrt line segment.
- Parameters:
nodesC – (N, 2) array of test coordinates
uC – (2,) array of coordinates of edge ends
vC – (2,) array of coordinates of edge ends
- Returns:
True if any two of nodesC are on opposite sides of the edge.
- optiwindnet.geometric.rotate(coords: CoordPairs, angle: float) CoordPairs[source]¶
Rotates coords (numpy array T×2) by angle (degrees)
- optiwindnet.geometric.angle_numpy(aC: CoordPairs, pivotC: CoordPairs, bC: CoordPairs) numpy.ndarray[tuple[int], numpy.dtype[numpy.float64]][source]¶
Calculate the angle a-pivot-b.
can operate on multiple point triplets
angle is within ±π (shortest arc from a to b around pivot)
positive direction is counter-clockwise
- Parameters:
aC – (N, 2) numpy arrays of coordinate pairs
pivotC – (N, 2) numpy arrays of coordinate pairs
bC – (N, 2) numpy arrays of coordinate pairs
- Returns:
Angles a-pivot-b (radians)
- optiwindnet.geometric.angle(aC, pivotC, bC)[source]¶
Calculate the angle aC-pivotC-bC.
angle is within ±π (shortest arc from a to b around pivot)
positive direction is counter-clockwise
- Parameters:
aC – (2,) numpy arrays of coordinate pairs
pivotC – (2,) numpy arrays of coordinate pairs
bC – (2,) numpy arrays of coordinate pairs
- Returns:
Angle aC-pivotC-bC (radians)
- optiwindnet.geometric.angle_helpers(L: networkx.Graph, include_borders: bool = True) tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.int_], list[dict[int, int]]][source]¶
Create auxiliary arrays of node attributes based on polar coordinates.
The ranks of the angles and calculated per root and start from 0. The duplicates mapping is a list of dicts and is indexed first by the root.
- Parameters:
L – location (also works with A or G)
- Returns:
Tuple of (angle__, angle_rank__, dups_from_root_rank__)
- optiwindnet.geometric.angle_oracles_factory(angle__: numpy.typing.NDArray[numpy.float64], angle_rank__: numpy.typing.NDArray[numpy.int_]) tuple[Callable[[int, int, int, int, int, int, int], tuple[int, int]], Callable[[int, int, int], float]][source]¶
Make functions to answer queries about relative angles.
Inputs are the outputs of angle_helpers().
- Parameters:
angle – (T, R)-array of angles wrt root (+-pi)
angle_rank – (T, R)-array of the relative placement of angles
- Returns:
union_limits() and angle_ccw()
- optiwindnet.geometric.find_edges_bbox_overlaps(VertexC: CoordPairs, u: int, v: int, edges: IndexPairs) numpy.typing.NDArray[numpy.int_][source]¶
Find which edges have a bounding box overlap with ⟨u, v⟩.
This is a preliminary filter for crossing checks. Enables avoiding the more costly geometric crossing calculations for segments that are clearly disjoint.
- Parameters:
VertexC – (N×2) point coordinates
u – indices of probed edge
v – indices of probed edge
edges – list of index pairs representing edges to check against
- Returns:
numpy array with the indices of overlaps in edges
- optiwindnet.geometric.is_crossing_numpy(u, v, s, t)[source]¶
Checks if (u, v) crosses (s, t).
- Returns:
True in case of crossing.
- optiwindnet.geometric.is_crossing_no_bbox(uC: CoordPair, vC: CoordPair, sC: CoordPair, tC: CoordPair) bool[source]¶
Checks if (uC, vC) crosses (sC, tC).
Does not check for bounding-box overlap. Use find_edges_bbox_overlap() first to filter out edges with disjoint bounding boxes (cheaper than the calculations here).
- Returns:
True in case of crossing.
- optiwindnet.geometric.is_crossing(uC: CoordPair, vC: CoordPair, sC: CoordPair, tC: CoordPair, touch_is_cross: bool = True) bool[source]¶
Checks if (uC, vC) crosses (sC, tC).
- Parameters:
uC – (2,) numpy array coordinates of edge ends
vC – (2,) numpy array coordinates of edge ends
sC – (2,) numpy array coordinates of edge ends
tC – (2,) numpy array coordinates of edge ends
touch_is_cross – whether to consider any common point as a crossing
- Returns:
True in case of crossing.
- optiwindnet.geometric.is_bunch_split_by_corner(bunch, a, o, b, margin=0.001)[source]¶
Check if a cone splits a bunch of points in two sets.
- Parameters:
bunch – numpy array of points (T×2)
a – points that define the cone’s angle
o – points that define the cone’s angle
b – points that define the cone’s angle
- Returns:
True if points in bunch are both inside and outside cone a-o-b
- optiwindnet.geometric.is_triangle_pair_a_convex_quadrilateral(uC: CoordPair, vC: CoordPair, sC: CoordPair, tC: CoordPair) bool[source]¶
Check convexity of quadrilateral.
⟨u, v⟩ is the common side; ⟨s, t⟩ are the opposing vertices; only works if ⟨s, t⟩ crosses the line defined by ⟨u, v⟩
- Returns:
True if the quadrilateral is convex and is not a triangle
- optiwindnet.geometric.perimeter(VertexC, vertices_ordered)[source]¶
Calculate the perimeter of the polygon defined by vertices_ordered.
- Parameters:
vertices_ordered – indices of VertexC in clockwise or counter-clockwise orientation.
- Returns:
The perimeter length.
- optiwindnet.geometric.assign_root(A: networkx.Graph) None[source]¶
Add node attribute ‘root’ with the root closest to each node.
Changes A in-place.
- Parameters:
A – available-edges graph
- optiwindnet.geometric.complete_graph(G_base: networkx.Graph, *, include_roots: bool = False, prune: bool = True, map_crossings: bool = False) networkx.Graph[source]¶
Create a complete graph based on G_base.
Produces a networkx Graph connecting all non-root nodes to every other non-root node. Edges with an arc > pi/2 around root are discarded The length of each edge is the euclidean distance between its vertices.
- optiwindnet.geometric.minimum_spanning_forest(A: networkx.Graph) networkx.Graph[source]¶
Create the minimum spanning forest from the Delaunay edges of A.
There is one tree for each root and exactly one root per tree. If the graph has more than one root, the minimum spanning tree of the entire graph is split on its longest links between each root pair.
- Returns:
Topology S containing the forest.
- optiwindnet.geometric.rotation_checkers_factory(VertexC: CoordPairs) tuple[Callable[[int, int, int], bool], Callable[[int, int, int], bool]][source]¶
- optiwindnet.geometric.rotating_calipers(convex_hull: numpy.typing.NDArray, metric: str = 'height') tuple[numpy.typing.NDArray[numpy.int_], float, float, CoordPairs][source]¶
Find the shortest width of a polygon.
Reference: Toussaint, Godfried T. “Solving geometric problems with the rotating calipers.” Proc. IEEE Melecon. Vol. 83. 1983.
- Parameters:
convex_hull – (H, 2) array of coordinates of the convex hull in counter-clockwise order
metric – what should be minimized, one of {‘height’, ‘area’}
- Returns:
best_calipers, best_caliper_angle, best_metric, bbox
- optiwindnet.geometric.area_from_polygon_vertices(X: numpy.ndarray, Y: numpy.ndarray) float[source]¶
Calculate the area enclosed by the polygon with the vertices (x, y).
Vertices must be in sequence around the perimeter (either clockwise or counter-clockwise).
- Parameters:
X – array of X coordinates
Y – array of Y coordinates
- Returns:
area
- optiwindnet.geometric.add_link_blockmap(A: networkx.Graph)[source]¶
Experimental. Add attributes ‘blocked__’ to edges and nodes.
Edges’ ‘blocked__’ are R-long list of T-long bitarray maps. A 1-bit in position t on the bitarray for root r means the edge crosses the line-of-sight t-r.
Changes A in place. A should have no feeder edges.
- optiwindnet.geometric.add_link_cosines(A: networkx.Graph)[source]¶
Add cosine of the angle wrt each root to all links of A as attribute ‘_cos’.
Changes A in-place. The cosine is of the acute angle between the link line and the line that contains the mid-point of the link and the root (for each root).