技术

d3、 d3.force、d3.geom.quadtree。

d3.geom.quadtree

四叉树的应用:图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,游戏编程。

上图中的数据就是普通的点,点与点之间没有关系。此函数在构建四叉树的时候(原数据要么是树型的数据要么是包含位置信息的点,此例子是包含位置信息的普通的点),整个rect是一个根节点,当这个节点内部的有大于一个数据点的时候,会对这个节点进行四等分,持续下去直到每个叶子节点至多包含一个数据点。引用: https://www.sypopo.com/post/dJQbeP8Zoj/

四叉树碰撞应用(圆)

d3官方example:

 <!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script> var width = 960,
height = 500; var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }),
root = nodes[0],
color = d3.scale.category10(); root.radius = 0;
root.fixed = true; var force = d3.layout.force()
.gravity(0.05)
.charge(function(d, i) { return i ? 0 : -2000; })
.nodes(nodes)
.size([width, height]); force.start(); var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height); svg.selectAll("circle")
.data(nodes.slice(1))
.enter().append("circle")
.attr("r", function(d) { return d.radius; })
.style("fill", function(d, i) { return color(i % 3); }); force.on("tick", function(e) {
var q = d3.geom.quadtree(nodes),
i = 0,
n = nodes.length; while (++i < n) q.visit(collide(nodes[i])); //n^2的复杂度 svg.selectAll("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}); svg.on("mousemove", function() {
var p1 = d3.mouse(this);
root.px = p1[0];
root.py = p1[1];
force.resume();
}); function collide(node) {
var r = node.radius + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {//是叶子节点且不是当前节点
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
} </script>

核心代码在 : L60-L71行。解释如下:

另平移因子S=(r-l)/(2l) ;利用勾股证明得:

因此,程序中偏移实际上是偏大了一点!不过绘制的结果还是挺好的。

经试验,对L36-L44行进行单独迭代,把上述代码中的力去掉。迭代大约30次左右,才能避免碰撞现象。其中迭代step,可以对L67行中的"l"进行适当缩放。注意避免震荡情况(l较大的时候)。

collide函数的分析

测试下面的函数:

 <script>
function a(x){
return x(1,2);
}
function b(x,y){
console.log(x+":b:"+y);
}
function c(x) {
return function(a,b){
console.log(x+":"+a+":c:"+b);
}
} </script>

结果:

可见,b 、c两种写法都是ok的,c更骚一点。

quadtree().visit()

前序遍历,关于回调函数返回值:

If the callback returns true for a given node, then the children of that node are not visited; otherwise, all child nodes are visited.

返回值: return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;

意思就是内部的node超出了quad的话,对当前quad的子节点标记为未访问(需要继续对其子节点进行调整)。

最新文章

  1. Linux常用命令学习7---(磁盘管理df du、磁盘的分区和格式化fdisk parted)
  2. 自定义Spring Security权限控制管理(实战篇)
  3. 配置云服务器 FTP 服务
  4. hdu 1279 验证角谷猜想
  5. python数据结构与算法——栈
  6. nodejs express 框架解密1-总体结构
  7. php页面打开响应时间
  8. JDBC第三次学习
  9. React 万能的函数表达式
  10. .NET中的Newtonsoft.Json.JsonConvert.SerializeObject(string a)
  11. Axure RP 各个版本中文版 汉化包 破解版 下载地址及注册码
  12. C/C++ Linux 程序员必须了解的 10 个工具
  13. 移动web前端的一些硬技能(二)动手前必须掌握的基本常识
  14. 任何时候都适用的20个C++技巧
  15. python 函数之walk
  16. C语言获取文件SHA1哈希
  17. 全球互联网技术大会GITC 2016 最炫酷技术盛宴
  18. Can I use MyBatis to generate Dynamic SQL without executing it?
  19. 解决ODBC连接Oracle数据库报Unable to connect SQLState=08004问题
  20. Vue/Egg大型项目开发(二)数据库设计

热门文章

  1. POJ 1945 暴搜+打表 (Or 暴搜+判重)
  2. http请求常出现的状态码
  3. jQuery学习(五)——使用JQ完成复选框的全选和全不选
  4. 转:IE 无法使用 js trim() 的解决方法
  5. 【原创】Unable to read TLD &quot;META-INF/c.tld&quot; from JAR file 解决方法
  6. hdu1010 - dfs,奇偶剪枝
  7. 树上倍增求LCA
  8. mysql中如何查看某个数据库或表占用的磁盘空间
  9. 小程序QQ版表情解析组件
  10. Oralce 视图 view