Skip to content

Instantly share code, notes, and snippets.

@ggirou
Created March 21, 2014 13:41
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ggirou/9686524 to your computer and use it in GitHub Desktop.
Save ggirou/9686524 to your computer and use it in GitHub Desktop.
Center mass of SVG path elements
import 'dart:convert';
import 'dart:html';
import 'dart:math';
import 'dart:svg' as svg;
main() {
HttpRequest.getString('svg-datas.json').then(JSON.decode).then(calculateGravity);
}
calculateGravity(Map<String, Map> paths) {
paths.forEach((country, data) {
var path = data['path'];
var el = new svg.PathElement()..setAttribute('d', path);
List<Point> points = el.pathSegList
.where((ps) => !(ps is svg.PathSegClosePath))
.map((p) => new Point(p.x, p.y)).toList();
var g = gravity(points);
print(""" "$country": {
"path": "$path",
"center": {
"x": ${g.x},
"y": ${g.y}
}
},""");
});
}
Point gravity(List<Point> points) {
num sumArea = 0, sumX = 0, sumY = 0;
for (int i = 0; i < points.length; i++) {
var i_p = (i + 1) % points.length;
var g = points[i].x * points[i_p].y - points[i_p].x * points[i].y;
sumArea += g;
sumX += (points[i].x + points[i_p].x) * g;
sumY += (points[i].y + points[i_p].y) * g;
}
sumArea = 3 * sumArea;
return new Point((sumX / sumArea).round(), (sumY / sumArea).round());
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>center</title>
</head>
<body>
<p id="text"></p>
<script type="application/dart" src="center.dart"></script>
<!-- for this next line to work, your pubspec.yaml file must have a dependency on 'browser' -->
<script src="packages/browser/dart.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment