简体   繁体   English

如何围绕焦点旋转d3.js节点?

[英]How to rotate d3.js nodes around a foci?

I've been using force layout as a sort of physic's engine for board game i'm making, and it's been working pretty well. 我一直在使用力布局作为我制作的棋盘游戏的一种物理引擎,并且效果很好。 However, I've been trying to figure out if it is possible to rotate nodes around a specific foci. 但是,我一直在尝试找出是否可以围绕特定焦点旋转节点。 Consider this codepen . 考虑一下这个codepen I would like to make the 3 green nodes in the codepen rotate around the foci in a uniform fashion. 我想使Codepen中的3个绿色节点以一致的方式围绕焦点旋转。 In the tick() function I do the following: 在tick()函数中,执行以下操作:

var k = .1 * e.alpha;

// Push nodes toward their designated focus.
nodes.forEach(function(o, i) {
  o.y += (foci[o.id].y - o.y) * k;
  o.x += (foci[o.id].x - o.x) * k;
});

In the same way that I push nodes toward a foci, I'd like to make all nodes designated to a foci rotate around said foci. 就像我将节点推向焦点一样,我想使所有指定给焦点的节点都围绕所述焦点旋转。 Is there any way to accomplish this by manipulating the oy and ox variables within the tick() function? 是否有任何方法可以通过处理tick()函数中的oyox变量来实现此目的? I've tried to manually set the x and y values using this formula however I think possibly the charge and gravity of the force layout are messing it up. 我试图使用此公式手动设置x和y值,但是我认为可能是力分布的电荷和重力使它混乱了。 Any ideas? 有任何想法吗?

I know i'm using force layout for something it's not quite intended to do, but any help would be appreciated. 我知道我正在将力设计用于某项并非很想做的事情,但会有所帮助。

I have messed around with your code to get a basic movement around a point. 我已经弄乱了您的代码,以获得围绕一点的基本运动。

I changed the foci var to an object which is just two points : 我将焦点变量更改为仅两点的对象:

 foci = {
    x: 300,
    y: 100
  };

Ive added to the data you have to give each node a start point : 我已经添加了数据,您必须给每个节点一个起点:

nodes.push({
  id: 0,
  x:20,
  y:30
});
nodes.push({
  id: 0,
  x:40,
  y:60
});
nodes.push({
  id: 0,
  x:80,
  y:10
});

I have added an angle to each node so you can use these independently later: 我为每个节点添加了一个角度,以便以后可以独立使用它们:

 .attr("cx", function(d) {
            d.angle = 0; //added
      return d.x;
    })

And changed the tick so each node moves around the focal point. 并更改刻度,使每个节点都围绕焦点移动。 As said before I added an angle as these points will move around different circles with different sized radius as they will be different distances from the foci point. 如前所述,我添加了一个角度,因为这些点到焦点的距离将不同,因此它们将绕不同半径的大小的圆移动。 If you use one angle then all the nodes will move ontop of each other which is pointless : 如果您使用一个角度,那么所有节点都将彼此重叠,这是毫无意义的:

Formula for point on a circle : 圆上的点的公式:

//c = centre point, r = radius, a = angle
x = cx + r * cos(a)
y = cy + r * sin(a)

Use this in tick : 在刻度中使用此命令:

var radius = 100; //made up radius

  node
    .attr("cx", function(d) {
       if(d.angle>(2*Math.PI)){ restart at full circle
         d.angle=0;
       }
    d.x = foci.x + radius *Math.cos(d.angle) //move x

      return d.x;
    })
    .attr("cy", function(d) {
    d.y = foci.y + radius *Math.sin(d.angle) //move y
      return d.y;
    });

Updated fiddle : https://jsfiddle.net/reko91/yg0rs4xc/7/ 更新的小提琴: https : //jsfiddle.net/reko91/yg0rs4xc/7/

This should be simple to implement to change from circle movement to elliptical :)) 从圆运动变为椭圆:))应该很容易实现

Looking at this again, this only moves around half way. 再看一次,这只移动了一半。 This is due to the tick function only lasting a couple of seconds. 这是由于滴答功能仅持续了几秒钟。 If you click one of the nodes, it will continue around the circle. 如果您单击其中一个节点,它将在圆周围继续。 If you want this to happen continuously, you'll have to set up a timer function so it runs around the circle non stop, but that should be easily implemented. 如果您希望这种情况连续发生,则必须设置一个计时器功能,使其绕圈不停地运行,但这应该很容易实现。

Instead of tick function just make another function with the timer inside, call it on load and it will run continuously :) 除了滴答功能,还可以在计时器内部创建另一个功能,在加载时调用它,它将连续运行:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM