javascript – 如何在D3力模拟中实现圆盘形状?

我试图通过Nadieh Bremer和Shirely Wu从 Bussed out重新创建令人敬畏的“点流”可视化.

original bubbles

我特别感兴趣的是“气泡”的圆形形状以及点到达气泡点(黑色箭头)的流体动力学压缩.

我的想法是通过.fx和.fy(黑点)创建(三个)固定节点,并将所有其他节点链接到相应的固定节点.结果看起来非常凌乱,并且当我降低力时,气泡甚至不会在它们的中心节点周围形成,因此动画运行速度稍慢.

const simulation = d3.forceSimulation(nodes)
    .force("collide",d3.forceCollide((n,i) => i < 3 ? 0 : 7))
    .force("links",d3.forceLink(links).strength(.06))

关于力量设置的任何想法会产生更美观的结果吗?

我确实理解我将不得不随着时间的推移动画小组作业以获得’涓流’效果(否则所有的点都会聚集到他们的目的地),但我想从一个良好的圆形稳定状态开始模拟.

编辑

我确实检查了源代码,它只是重放预先录制的模拟数据,我想是出于性能原因.

my result

解决方法

建立Gerardo的开始,

我认为避免过度熵的关键点之一是指定速度衰减 – 这将有助于避免超出所需位置.太慢,你不会在流量停止,速度过快的情况下增加密度,并且你的节点要么过于混乱,要么超出目的地,在太远和太短之间振荡.

许多体力在这里是有用的 – 它可以保持节点间隔(而不是碰撞力),节点之间的排斥力被每个簇的定位力抵消.下面我使用了两个居中点和一个节点属性来确定使用哪一个.这些力量必须相当弱 – 强大的力量很容易导致过度修正.

我使用simulation.find()函数而不是使用计时器,每个tick都从一个集群中选择一个节点并切换它被吸引到哪个中心.在1000个滴答之后,下面的模拟将停止:

var canvas = d3.select("canvas");
var width = +canvas.attr("width");
var height = +canvas.attr("height");
var context = canvas.node().getContext('2d');

// Key variables:
var nodes = [];
var strength = -0.25;         // default repulsion
var centeringStrength = 0.01; // power of centering force for two clusters
var velocityDecay = 0.15;     // velocity decay: higher value,less overshooting
var outerRadius = 250;        // new nodes within this radius
var innerRadius = 100;        // new nodes outside this radius,initial nodes within.
var startCenter = [250,250];  // new nodes/initial nodes center point
var endCenter = [710,250];	  // destination center
var n = 200;		          // number of initial nodes
var cycles = 1000;	          // number of ticks before stopping.



// Create a random node:
var random = function() {
	var angle = Math.random() * Math.PI * 2;
	var distance = Math.random() * (outerRadius - innerRadius) + innerRadius;
	var x = Math.cos(angle) * distance + startCenter[0];
	var y = Math.sin(angle) * distance + startCenter[1];

	return { 
	   x: x,y: y,strength: strength,migrated: false
	   }
}

// Initial nodes:
for(var i = 0; i < n; i++) {
	nodes.push(random());
}
	
var simulation = d3.forceSimulation()
    .force("charge",d3.forceManyBody().strength(function(d) { return d.strength; } ))
	.force("x1",d3.forceX().x(function(d) { return d.migrated ? endCenter[0] : startCenter[0] }).strength(centeringStrength))
	.force("y1",d3.forceY().y(function(d) { return d.migrated ? endCenter[1] : startCenter[1] }).strength(centeringStrength))
	.alphaDecay(0)
	.velocityDecay(velocityDecay)
    .nodes(nodes)
    .on("tick",ticked);

var tick = 0;
	
function ticked() {
	tick++;
	
	if(tick > cycles) this.stop();
	
	nodes.push(random()); // create a node
	this.nodes(nodes);    // update the nodes.

  var migrating = this.find((Math.random() - 0.5) * 50 + startCenter[0],(Math.random() - 0.5) * 50 + startCenter[1],10);
  if(migrating) migrating.migrated = true;
  
	
	context.clearRect(0,width,height);
	
	nodes.forEach(function(d) {
		context.beginPath();
		context.fillStyle = d.migrated ? "steelblue" : "orange";
		context.arc(d.x,d.y,3,Math.PI*2);
		context.fill();
	})
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<canvas width="960" height="500"></canvas>

这是一个block view(片段是更好的整页,参数是它的意思).初始节点与后来的节点形成在同一个环中(因此在get get中有一些争用,但这很容易解决).在每个tick上,创建一个节点,并尝试将中间点附近的节点迁移到另一侧 – 这样就创建了一个流(与任何随机节点相对).

对于流体,未链接的节点可能是最好的(我一直用它来进行风力模拟) – 链接节点非常适合结构材料,如网或布.而且,和Gerardo一样,我也是Nadieh工作的粉丝,但是未来也必须关注Shirley的工作.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)