widgetti / ipyvolume

3d plotting for Python in the Jupyter notebook based on IPython widgets using WebGL
MIT License
1.94k stars 234 forks source link

Attaching camera to animated data point #212

Open fberlinger opened 5 years ago

fberlinger commented 5 years ago

Thanks for ipyvolume, Maarten, which is allowing me to create insightful visualizations quickly. I am a roboticist and I study collective behaviors of multi-agent systems. I'd like to attach the camera to one of the robots in a moving swarm, such that I get an inside rather than an observer's perspective on the swarm behavior. However, not matter what I do, the camera is always directed toward the center of the cube within the robots move (which makes sense for the observer's perspective).

Here is what I tried:

Both, the moviemaker and pylab.view updated the camera position correctly but ignored the orientation and always set it such that the camera looks toward the center of the cube.

Is there any way you could disable the automatic orientation of the camera and allow a user specified orientation? Ideal case, a moviemaker or pylab.view that takes (x, y, z, vx, vy, vz) as an input and sets the camera accordingly? This way, the camera matrix would basically be set equal to one of the quiver points (x, y, z, vx, vy, vz).

Thank you so much! Florian

maartenbreddels commented 5 years ago

Hi Florian,

thanks for the kind words, and always interesting to hear how people use ipyvolume! Figure.camera_center controls the center, could that be the solution for you?

cheers,

Maarten

maartenbreddels commented 5 years ago

What you could try is to have a special case of camera_center being None. If you want to try that out, I'm happy to accept a PR.

fberlinger commented 5 years ago

Thanks Maarten! Please have a quick look at my two videos in camera_man.zip such that we definitely talk about the same problem. It is very similar to your demo but the camera is attached to and travelling with one of the animated cones. This feature would be a very nice addition to ipyvolume, allowing researchers to experience the view point of a particle, or even of a fish swimming in a school (given that we have tracking data of several fish swimming together).

I have several objects with positions (x, y, z) and velocities (vx, vy, vz). I am already able to set the camera to a desired position (x, y, z). However, at this position, I am unable to make it look in a desired direction (vx, vy, vz).

What I want to achieve is a local view of a global behavior. I attached two video examples. First, a global view of aggregation in 3d space. Second, a local view from the perspective of the red cone. The camera travels with the red cone (x, y, z). However, instead of looking at the direction in which the red cone is moving (vx, vy, vz), it is always looking at the center of the cube. Doesn't look too bad in pure aggregation. However, in dispersion starting from the center moving outwards, the camera would always look backward.

The way I produced those videos was with a quiver plot plus the moviemaker: ipv.quiver(x, y, z, vx, vy, vz) mm = MovieMaker(stream=fig, camera=fig.camera, positions=positions, quaternions=quaternions, times=times) positions are (x, y, z). quaternions are corresponding to (vx, vy, vz) and are ignored.

I was not able to change the camera orientation in a given position with any of those: fig.camera.rotation, fig.camera_center, fig.camera.position.

My best guess is that we should be able to change it in figure.js, l534. Any ideas how to change it dynamically and still getting a smooth animation?

Thanks you so much! Florian

camera_man.zip

maartenbreddels commented 5 years ago

Nice animation.

Take a look at this: https://github.com/maartenbreddels/ipyvolume/blob/master/js/src/figure.js#L823 I think what you can try, is to allow camera_center to be None on a Python side (which is null on the JS side). If this is the case, the lookAt should be skipped.

fberlinger commented 5 years ago

I think we are close. Skipping the lookAt might do the trick.

Starting with: fig = ipv.figure() setting camera_center to be None raises an error (see below), fig.camera_center = None passing an empty list does not work neither because nothing is shown after calling ipv.show() fig.camera_center = []

Any alternatives to skip the lookAt and look in the direction of the quaternion specified in the movie maker, or simpler just looking along the (vx, vy, vz) vector of the quiver element in position (x, y, z)? Or maybe passing (vx, vy, vz) to the lookAt while still allowing a synchronized animation of data point and camera?

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/traitlets/traitlets.pyc in error(self, obj, value) 1522 % (self.name, self.info(), msg) 1523 -> 1524 raise TraitError(e) 1525 1526 TraitError: The 'camera_center' trait of a Figure instance must be a list, but a value of type 'NoneType' (i.e. None) was specified.

maartenbreddels commented 5 years ago

Sounds good.

Indeed, see my comment above:

  • add allow_none to widgest.py:Figure.camera_center

See https://traitlets.readthedocs.io/en/stable/trait_types.html?highlight=allow_none#traitlets.TraitType.__init__ for the docs (or see the same file for examples)

Hope that helps!