Skip to content

Instantly share code, notes, and snippets.

@shvydky
Created January 10, 2024 05:48
Show Gist options
  • Save shvydky/4abf008dd4934aa44d2988c2769cc690 to your computer and use it in GitHub Desktop.
Save shvydky/4abf008dd4934aa44d2988c2769cc690 to your computer and use it in GitHub Desktop.
DouglasPeuckerEpsilon: 0.03 # epsilon for Douglas-Peucker algorithm
// DouglasPeucker simplifies a path using the Douglas-Peucker algorithm.
func DouglasPeucker(points []TenantPosition, epsilon float64) []TenantPosition {
if len(points) <= 2 {
return points
}
dMax := 0.0
index := 0
// Calculate the point farthest from the line segment formed by the first and last points.
for i := 1; i < len(points)-1; i++ {
d := perpendicularDistance(points[i], points[0], points[len(points)-1])
if d > dMax {
index = i
dMax = d
}
}
if dMax > epsilon {
// Recursively simplify the two subpaths formed by the farthest point.
firstPart := DouglasPeucker(points[:index+1], epsilon)
secondPart := DouglasPeucker(points[index:], epsilon)
return append(firstPart[:len(firstPart)-1], secondPart...)
}
return []TenantPosition{points[0], points[len(points)-1]}
}
// perpendicularDistance calculates the perpendicular distance from a point to a line segment.
func perpendicularDistance(point, start, end TenantPosition) float64 {
if start == end {
return math.Sqrt(math.Pow(point.XY.X-start.XY.X, 2) + math.Pow(point.XY.Y-start.XY.Y, 2))
}
return math.Abs((point.XY.X-start.XY.X)*(end.XY.Y-start.XY.Y)-(point.XY.Y-start.XY.Y)*(end.XY.X-start.XY.X)) /
math.Sqrt(math.Pow(end.XY.X-start.XY.X, 2)+math.Pow(end.XY.Y-start.XY.Y, 2))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment