You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
3.0 KiB
93 lines
3.0 KiB
import {addBoundingSquareTo, Angle, Graph, GraphBoundary, Point, rad2deg, rad2degp, Segment, Triangle} from "./pslg";
|
|
|
|
export function addTriangle(graph: Graph, boundary: GraphBoundary, segment: Segment) {
|
|
let p1 = segment.from
|
|
let p2 = segment.to
|
|
|
|
// Want to order p1 and p2 such that p2 is the right neighbor of p1
|
|
if ( !boundary.rightNeighbor(p1).is(p2) ) {
|
|
let temp = p1
|
|
p1 = p2
|
|
p2 = temp
|
|
}
|
|
|
|
// Get a segment with the ordered from/to
|
|
// So, looking from p1 to p2, points on the "left side" of the line
|
|
// are within the boundary
|
|
const orderedSegment = new Segment(p1, p2)
|
|
|
|
// Collect all points that could form valid triangles
|
|
const possiblePoints: {angle: number, point: Point}[] = []
|
|
|
|
// Find some p3 such that p1p2p3 is Delaunay (<p1p3p2 is the largest angle)
|
|
for ( const point of graph.points ) {
|
|
if ( point.is(p1) || point.is(p2) ) continue
|
|
|
|
// Check if the point is within boundary -- excluding boundary points themselves
|
|
if ( !boundary.containsPointWithin(point) ) continue
|
|
|
|
// TODO Check if the point is within the search region
|
|
|
|
// Check if the point is on the left-side of segment
|
|
if ( !orderedSegment.pointIsLeftOf(point) ) continue
|
|
|
|
possiblePoints.push({
|
|
angle: Triangle.getAngleFrom(p1, point, p2),
|
|
point,
|
|
})
|
|
}
|
|
|
|
// Sort the possible points to find the one with the largest angle
|
|
const sortedPossiblePoints = possiblePoints.sort((a, b) => {
|
|
const aDeg = rad2degp(a.angle)
|
|
const bDeg = rad2degp(b.angle)
|
|
return bDeg - aDeg
|
|
})
|
|
|
|
// Go through the sorted points and find one that forms a valid triangle
|
|
for ( const {point} of sortedPossiblePoints ) {
|
|
const seg13 = new Segment(p1, point)
|
|
const seg23 = new Segment(p2, point)
|
|
|
|
// Make sure the legs that would form from this triangle wouldn't intersect
|
|
// with the boundary segment except at p1 and p2
|
|
if ( segment.getIntersectionWithin(seg13) || segment.getIntersectionWithin(seg23) ) {
|
|
continue
|
|
}
|
|
|
|
// We found a valid 3rd point for this triangle!
|
|
const graphSeg13 = graph.findExistingSegmentOrAdd(seg13)
|
|
const graphSeg23 = graph.findExistingSegmentOrAdd(seg23)
|
|
const graphSeg12 = graph.findExistingSegmentOrAdd(segment)
|
|
|
|
graph.findExistingTriangleOrAdd(new Triangle([graphSeg13, graphSeg23, graphSeg12]))
|
|
break
|
|
}
|
|
}
|
|
|
|
export function delaunay(originalGraph: Graph): Graph {
|
|
const graph = originalGraph.clone()
|
|
const boundary = addBoundingSquareTo(graph)
|
|
|
|
// for ( const segment of boundary.segments ) {
|
|
// addTriangle(graph, boundary, segment)
|
|
// break
|
|
// }
|
|
// const segment = boundary.segments[0]
|
|
// addDelaunayTriangle(graph, boundary, segment)
|
|
|
|
for ( const point of graph.points ) {
|
|
|
|
}
|
|
|
|
return graph
|
|
}
|
|
|
|
export function delaunayRefine(originalGraph: Graph, minAngle: Angle): Graph {
|
|
const graph = originalGraph.clone()
|
|
|
|
addBoundingSquareTo(graph)
|
|
|
|
return graph
|
|
}
|