Commit b89f516e by Starbeamrainbowlabs

Ok, sot his isn't going to work. Let's try another algorithm instead :P

parent cb01b972
 # Ramer Douglas Peucker Implementations > My implementations of the ramer-douglas-peucker line simplification algorithm in JS and C#♯. # Visvalingam’s Algorithm Implementations > My implementations of the Visvalingam’s line simplification algorithm in JS and C#♯. ## Links - https://bost.ocks.org/mike/simplify/ - http://karthaus.nl/rdp/ - https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
 ... ... @@ -10,7 +10,7 @@
• Points:
• Epsilon:
• Epsilon:
... ...
 ... ... @@ -199,13 +199,21 @@ class Vector { this.x / length, this.y / length); } /** * The length of this vector squared. * @return {number} The length of this vector squared. */ get lengthSquared() { return (this.x*this.x) + (this.y*this.y); } /** * Get the length of the current vector. * @return {number} The length of the current vector. */ get length() { return Math.sqrt((this.x * this.x) + (this.y * this.y)); return Math.sqrt(this.lengthSquared); } /** ... ...
 ... ... @@ -8,76 +8,42 @@ import Vector from './lib/Vector.js'; * @param {number} epsilon The amount of simplification to perform. * @return {Vector[]} The simplfied line. */ function simplify_line(points, epsilon) function simplify_line(points, min_area) { points = collapse_points(points); let first_point = points[0], last_point = points[points.length - 1]; let farthest_index = 0, farthest_distance = 0; for (let i = 1; i < points.length - 1; i++) { let next_distance = distance_from_line(first_point, last_point, points[i]); if(next_distance > farthest_distance) { farthest_index = i; farthest_distance = next_distance; let smallest_area = Number.MAX_SAFE_INTEGER, smallest_area_i = 1; while(smallest_area > min_area) { for(let i = 1; i < points.length - 1; i++) { let next_area = triangle_area(points[i - 1], points[i], points[i + 1]); if(next_area < smallest_area) { smallest_area = next_area; smallest_area_i = i; } } } // This point is far enough away that it's meaningful - recurse! if(farthest_distance > epsilon) { let left_side = simplify_line(points.slice(0, farthest_index + 1), epsilon), right_side = simplify_line(points.slice(farthest_index), epsilon); return [ ...left_side, ...right_side.slice(1) ]; } return [ points[0], points[points.length - 1] ]; } /** * Collapses sequences of points that are identical. * @param {[Vector]} points The list of points to collapse. * @return {[Vector]} The list of collapsed points. */ function collapse_points(points) { let result = []; for(let i = 0; i < points.length; i++) { if(result.length > 0 && result[result.length - 1].equalTo(points[i])) continue; result.push(points[i]); // Remove the central point of the smallest triangle points.splice(smallest_area_i, 1); } return result; } /** * Calculates the squared shortest distance between a point and the specified line. * @param {Vector} line_start The point at which the line starts. * @param {Vector} line_end The point at which the line ends. * @param {Vector} point The point to calculate the distance for. * @return {number} The shortest distance between the specified point * and the specified line. * Calculates the area of a triangle with the vertices a, b, and c * @param {Vector} a The first vertex of the triangle. * @param {Vector} b The second vertex of the triangle. * @param {Vector} c The third and final vertex of the triangle. * @return {number} The area of the triangle. */ function distance_from_line(line_start, line_end, point) function triangle_area(a, b, c) { let main_line = line_end.clone().subtract(line_start); let main_line_length = main_line.length; if(main_line_length === 0) return line_end.clone().subtract(point).length; let projectionFactor = Math.max(0, Math.min(1, point.clone().subtract(line_start).dotProduct(main_line) / main_line_length )); let projection = main_line.clone().multiply(projectionFactor).add(line_start); return projection.clone().subtract(point).length; return Math.abs( ( a.x * (b.x - c.x) + b.x * (c.y - a.y) + c.x * (a.y - b.y) ) / 2 ); } export { simplify_line };
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!