d3碰撞源码分析
技术
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的子节点标记为未访问(需要继续对其子节点进行调整)。
d3碰撞源码分析的更多相关文章
- d3 bubble源码分析
		
技术 d3.d3.pack.d3.hierarchy 展示 https://bl.ocks.org/xunhanliu/e0688dc2ae9167c4c7fc264c0aedcdd1 关于怎么使用, ...
 - JDK1.8 HashMap 源码分析
		
一.概述 以键值对的形式存储,是基于Map接口的实现,可以接收null的键值,不保证有序(比如插入顺序),存储着Entry(hash, key, value, next)对象. 二.示例 public ...
 - Java并发包源码分析
		
并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善.现代的PC都有多个CPU或一个CPU中有多个 ...
 - .net源码分析 – Dictionary<TKey, TValue>
		
接上篇:.net源码分析 – List<T> Dictionary<TKey, TValue>源码地址:https://github.com/dotnet/corefx/blo ...
 - HashMap实现原理及源码分析
		
哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...
 - Java集合源码分析(七)HashMap<K, V>
		
一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了不同步和允许使用 null 之外,HashMap ...
 - OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
		
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
 - HTTP严格安全传输(HTTP Strict Transport Security, HSTS)chromuim实现源码分析(一)
		
// HTTP strict transport security (HSTS) is defined in// http://tools.ietf.org/html/ietf-websec-stri ...
 - Java中HashMap源码分析
		
一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...
 
随机推荐
- C语言学习小记
			
2013年1月31日 今天试着编程为报文去头去尾. #include #include #define MAX_LENTH 1024 int main() { char *path = &quo ...
 - TabPage判断重复添加Page
			
..... ........ ...........代码如下: bool isPag = true; foreach (TabPage page in tbpDynamicMenu.TabPages) ...
 - Android自定义TabBar
			
转载请说明出处:http://www.sunhome.org.cn 我发现现在的移动开发界面都被iOS主导了,UI动不动设计出来的东西都是ios的风格,对于一个做Android的程序员来说甚是苦恼啊, ...
 - Codeforces 986B. Petr and Permutations(没想到这道2250分的题这么简单,早知道就先做了)
			
这题真的只能靠直觉了,我没法给出详细证明. 解题思路: 1.交换3n次或者7n+1次,一定会出现一个为奇数,另一个为偶数. 2.用最朴素的方法,将n个数字归位,计算交换次数. 3.判断交换次数是否与3 ...
 - 【原创】rman 全库备份脚本
			
rman 全库备份脚本 run { allocate channel d1 type disk; allocate channel d2 type disk; backup full database ...
 - springmvc两种非注解的处理器适配器
			
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...
 - STM8S103之独立看门狗和窗口看门狗
			
独立看门狗时钟来源为LSI:窗口看门狗时钟来源为CPU: 窗口看门狗窗口的含义是:喂狗必须在一定的窗口期内完成,不能过早也不能过晚. 总结:防止程序复位,用独立看门狗. 独立看门狗使用的流程:参见库函 ...
 - nginx的location 匹配的规则问题
			
正则解释: ~ #匹配一个正则匹配,区分大小写~* #匹配一个正则,不区分大小写^~ #普通字符匹配,如果该选择匹配不匹配别的选项,一般用来匹配目录= #精确匹配 匹配案例:location = / ...
 - LA3231 Fair Share 二分_网络流
			
Code: #include<cstdio> #include<vector> #include<queue> #include<cstring> #i ...
 - BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)
			
题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...