mirror of
https://github.com/skishore/makemeahanzi.git
synced 2025-11-02 04:37:30 +08:00
Get basic matching algorithm working
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
var MAX_BRIDGE_DISTANCE = 64;
|
||||
var MIN_CORNER_ANGLE = 0.1*Math.PI;
|
||||
var MIN_CORNER_TANGENT_DISTANCE = 4;
|
||||
|
||||
@ -21,6 +22,9 @@ var Angle = {
|
||||
}
|
||||
return result;
|
||||
},
|
||||
penalty: function(diff) {
|
||||
return diff*diff*(diff < 0 ? 4 : 1);
|
||||
},
|
||||
};
|
||||
|
||||
// Helper methods for use with "points", which are just pairs of integers.
|
||||
@ -138,19 +142,45 @@ function get_2x_area(path) {
|
||||
// Returns a list of critical segments that are arrayed around the corner.
|
||||
// Each of these segments will include a d value, an "in" bit, and an "out" bit.
|
||||
function get_segments(corners) {
|
||||
var map = {};
|
||||
var result = [[], []];
|
||||
for (var i = 0; i < corners.length; i++) {
|
||||
var corner = corners[i];
|
||||
for (var j = 0; j < 2; j++) {
|
||||
var key = Point.key(corner.indices[j]);
|
||||
if (!map.hasOwnProperty(key)) {
|
||||
map[key] = {segment: corner.segments[j]};
|
||||
}
|
||||
result[j].push({
|
||||
angle: corners[i].angles[j],
|
||||
point: corners[i].point,
|
||||
});
|
||||
}
|
||||
map[Point.key(corner.indices[0])].in = true;
|
||||
map[Point.key(corner.indices[1])].out = true;
|
||||
}
|
||||
return _.values(map);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Takes a list of segments and returns a bipartite match array between them.
|
||||
// If array[i] === j, then segments[0][i] is matched with segments[1][j].
|
||||
function match_segments(segments) {
|
||||
var matrix = [];
|
||||
for (var i = 0; i < segments[0].length; i++) {
|
||||
matrix.push([]);
|
||||
for (var j = 0; j < segments[0].length; j++) {
|
||||
matrix[i].push(score_segments(segments[0][i], segments[1][j]));
|
||||
}
|
||||
}
|
||||
return (new Hungarian(matrix)).x_match;
|
||||
}
|
||||
|
||||
// Takes two segments and returns the score that should be assigned to matching
|
||||
// the in segment to the out segment. The score will generally be negative.
|
||||
function score_segments(ins, out) {
|
||||
var diff = Point.subtract(out.point, ins.point);
|
||||
if (Point.equal(diff, [0, 0])) {
|
||||
return -Angle.penalty(Angle.subtract(out.angle, ins.angle));
|
||||
}
|
||||
var angle = Math.atan2(diff[1], diff[0]);
|
||||
var threshold = Math.pow(MAX_BRIDGE_DISTANCE, 2);
|
||||
var score = 0;
|
||||
score -= Angle.penalty(Angle.subtract(angle, ins.angle));
|
||||
score -= Angle.penalty(Angle.subtract(out.angle, angle));
|
||||
score -= Point.distance2(out.point, ins.point)/threshold;
|
||||
return score;
|
||||
}
|
||||
|
||||
function Endpoint(paths, index) {
|
||||
@ -192,9 +222,12 @@ this.get_glyph_render_data = function(glyph) {
|
||||
}
|
||||
}
|
||||
var corners = endpoints.filter(function(x) { return x.corner; });
|
||||
var segments = get_segments(corners);
|
||||
var matching = match_segments(segments);
|
||||
return {
|
||||
d: Glyphs.get_svg_path(glyph),
|
||||
endpoints: endpoints,
|
||||
segments: get_segments(corners),
|
||||
segments: segments,
|
||||
matching: matching,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user