ManimCommunity / manim

A community-maintained Python framework for creating mathematical animations.
https://www.manim.community
MIT License
19.95k stars 1.48k forks source link

distance attribute is ignored by camera in a three d scene #899

Closed lrfinotti closed 2 years ago

lrfinotti commented 3 years ago

Description of bug / unexpected behavior

The distance parameter is ignored in set_camera_orientation and move_camera. Setting different values has no effect. (See also: https://github.com/3b1b/manim/issues/999)

How to reproduce the issue

Code for reproducing the problem ```py from manim import * class Axes(ThreeDScene): def construct(self): axis_config = { 'x_min': -8, 'x_max': 8, 'y_min': -8, 'y_max': 8, 'z_min': -8, 'z_max': 8, } axes = ThreeDAxes(**axis_config) self.set_camera_orientation(phi=0*DEGREES, theta=-90*DEGREES, distance=15) self.play(ShowCreation(axes)) self.move_camera(phi=15*DEGREES, theta=-45*DEGREES, distance=20) self.wait(5) https://user-images.githubusercontent.com/22774569/103466714-4b6cb700-4d15-11eb-9f2b-4204de9133e8.mp4 ```

Additional media files

Video https://user-images.githubusercontent.com/22774569/103466723-5de6f080-4d15-11eb-8999-682722f8bc90.mp4

Logs

Terminal output ``` [01/02/21 16:14:36] DEBUG Hashing ... hashing.py:239 [01/02/21 16:14:37] DEBUG Hashing done in 0.986282 s. hashing.py:254 DEBUG Hash generated : 3587823_3987436653_2748229870 hashing.py:258 DEBUG List of the first few animation hashes of the scene: ['3587823_3987436653_2748229870'] caching.py:48 [01/02/21 16:14:41] INFO Animation 0 : Partial movie file written in scene_file_writer.py:391 {'/home/finotti/GD/InSync/code/manim/examples/media/videos/axes/480p15/partial_movie_files/Axes/3587823_3987436653_2748229870.mp4'} DEBUG Hashing ... hashing.py:239 [01/02/21 16:14:42] DEBUG Hashing done in 0.937759 s. hashing.py:254 DEBUG Hash generated : 748612456_2237676021_4179218321 hashing.py:258 DEBUG List of the first few animation hashes of the scene: ['3587823_3987436653_2748229870', '748612456_2237676021_4179218321'] caching.py:48 [01/02/21 16:14:45] INFO Animation 1 : Partial movie file written in scene_file_writer.py:391 {'/home/finotti/GD/InSync/code/manim/examples/media/videos/axes/480p15/partial_movie_files/Axes/748612456_2237676021_4179218321.mp4'} DEBUG Hashing ... hashing.py:239 [01/02/21 16:14:46] DEBUG Hashing done in 0.932262 s. hashing.py:254 DEBUG Hash generated : 4128474730_2874490763_3594327885 hashing.py:258 DEBUG List of the first few animation hashes of the scene: ['3587823_3987436653_2748229870', '748612456_2237676021_4179218321', '4128474730_2874490763_3594327885'] caching.py:48 INFO Animation 2 : Partial movie file written in scene_file_writer.py:391 {'/home/finotti/GD/InSync/code/manim/examples/media/videos/axes/480p15/partial_movie_files/Axes/4128474730_2874490763_3594327885.mp4'} DEBUG Partial movie files to combine (3 files): scene_file_writer.py:440 ['/home/finotti/GD/InSync/code/manim/examples/media/videos/axes/480p15/partial_movie_files/Axes/3587823_3987436653_2748229870.mp4', '/home/finotti/GD/InSync/code/manim/examples/media/videos/axes/480p15/partial_movie_files/Axes/748612456_2237676021_4179218321.mp4', '/home/finotti/GD/InSync/code/manim/examples/media/videos/axes/480p15/partial_movie_files/Axes/4128474730_2874490763_3594327885.mp4'] INFO scene_file_writer.py:562 File ready at /home/finotti/GD/InSync/code/manim/examples/media/videos/axes/480p15/Axes.mp4 INFO Rendered Axes scene.py:95 Played 3 animations ```

System specifications

System Details - OS: Debian Linux Sid/Unstable - RAM: 32GB - Python version: 3.9.1 - Installed modules (provide output from `pip list`): ``` Package Version ---------------------- ------------ alabaster 0.7.12 appdirs 1.4.4 apsw 3.32.2.post1 argon2-cffi 20.1.0 asn1crypto 1.4.0 astroid 2.4.2 async-generator 1.10 atomicwrites 1.4.0 attrs 20.3.0 autopep8 1.5.4 Babel 2.9.0 backcall 0.2.0 beautifulsoup4 4.9.3 bleach 3.2.1 blessings 1.7 bpython 0.20.1 cairocffi 1.2.0 certifi 2020.11.8 cffi 1.14.4 chardet 4.0.0 click 7.1.2 cloudpickle 1.6.0 colorama 0.4.4 colour 0.1.5 commonmark 0.9.1 cryptography 3.2.1 cson 0.8 css-parser 1.0.6 cssselect 1.1.0 cssutils 1.0.2 cupshelpers 1.0 curtsies 0.3.4 cycler 0.10.0 dbus-python 1.2.16 decorator 4.4.2 defusedxml 0.6.0 deprecation 2.1.0 distlib 0.3.1 distro 1.5.0 dnspython 2.0.0 docutils 0.16 entrypoints 0.3 eyeD3 0.9.5 feedparser 6.0.2 filelock 3.0.12 filetype 1.0.7 flake8 3.8.4 flake8-polyfill 1.0.2 future 0.18.2 Glances 3.1.5 greenlet 0.4.17 grpcio 1.33.2 grpcio-tools 1.33.2 html2text 2020.1.16 html5-parser 0.4.9 html5lib 1.1 httplib2 0.18.1 idna 2.10 ifaddr 0.1.7 imagesize 1.2.0 importlib-metadata 3.1.0 iniconfig 1.1.1 iotop 0.6 ipykernel 5.4.2 ipython 7.19.0 ipython-genutils 0.2.0 isodate 0.6.0 isort 5.6.4 jedi 0.17.2 jeepney 0.6.0 Jinja2 2.11.2 json5 0.9.5 jsonschema 3.2.0 jupyter-client 6.1.7 jupyter-core 4.7.0 jupyterlab 2.2.9 jupyterlab-pygments 0.1.2 jupyterlab-server 1.2.0 keyring 21.8.0 kiwisolver 1.3.1 lazy-object-proxy 1.5.2 libvirt-python 6.1.0 logilab-common 1.8.0 lxml 4.6.2 manimce 0.1.1 Markdown 3.3.3 markdown2 2.3.10 MarkupSafe 1.1.1 matplotlib 3.3.3 mccabe 0.6.1 mechanize 0.4.5 mistune 0.8.4 mock 4.0.2 mod 0.99.8 more-itertools 8.6.0 msgpack 1.0.0 mutagen 1.45.1 mypy-extensions 0.4.3 nbclient 0.5.1 nbconvert 6.0.7 nbformat 5.0.8 nest-asyncio 1.4.3 netifaces 0.10.9 notebook 6.1.5 notify2 0.3.1 numexpr 2.7.1 numpy 1.19.4 numpydoc 1.1.0 odfpy 1.4.1 olefile 0.46 packaging 20.7 pandas 1.1.5 pandocfilters 1.4.3 pangocairocffi 0.4.0 pangocffi 0.8.0 parso 0.8.0 pathtools 0.1.2 pbr 5.5.1 pep8 1.7.1 pep8-naming 0.11.1 pexpect 4.8.0 pickleshare 0.7.5 Pillow 8.0.1 pip 20.1.1 pip-review 1.1.0 pipenv 2020.11.15 playitslowly 1.5.0 pluggy 0.13.1 progressbar 2.5 prometheus-client 0.9.0 prompt-toolkit 3.0.8 protobuf 3.14.0 psutil 5.7.3 ptyprocess 0.6.0 py 1.9.0 pycairo 1.20.0 pychm 0.8.6 pycodestyle 2.6.0 pycparser 2.20 pycrypto 2.6.1 pycups 2.0.1 pycurl 7.43.0.6 pydub 0.24.1 pyflakes 2.2.0 Pygments 2.7.2 PyGObject 3.38.0 pyliblo 0.10.0 pylint 2.6.0 pyOpenSSL 20.0.0 pyparsing 2.4.7 PyQt5 5.15.2 PyQt5-sip 12.8.1 PyQtWebEngine 5.15.2 pyrsistent 0.17.3 pyserial 3.5 PySimpleSOAP 1.16.2 pystache 0.5.4 pytest 6.1.2 python-apt 2.1.7 python-dateutil 2.8.1 python-debian 0.1.39 python-debianbts 3.1.0 python-distutils-extra 2.39 python-libdiscid 1.1 python-magic 0.4.18 pytz 2020.5 pyxdg 0.27 pyzmq 20.0.0 QtAwesome 1.0.1 qtconsole 5.0.1 QtPy 1.9.0 ranger-fm 1.9.3 rdflib 5.0.0 recollchm 0.8.4.1+git regex 2020.11.13 reportbug 7.9.0 reportlab 3.5.57 repoze.lru 0.7 requests 2.25.0 rgain3 1.1.0 rich 6.2.0 roman 3.3 rope 0.18.0 Routes 2.5.1 scipy 1.5.4 SecretStorage 3.3.0 Send2Trash 1.5.0 setuptools 50.3.2 sgmllib3k 1.0.0 simplegeneric 0.8.1 sip 5.5.0 six 1.15.0 snowballstemmer 2.0.0 soupsieve 2.1 speedtest-cli 2.1.2 speg 0.3 Sphinx 3.4.1 spyder 3.3.6 spyder-kernels 0.5.2 tables 3.6.1 terminado 0.9.1 testpath 0.4.4 toml 0.10.2 tornado 6.1 tqdm 4.54.0 traitlets 5.0.5 trimage 1.0.6 typing-extensions 3.7.4.3 urllib3 1.26.2 urwid 2.1.2 virtualenv 20.2.1+ds virtualenv-clone 0.5.4 watchdog 0.10.4 wcwidth 0.2.5 webencodings 0.5.1 wheel 0.36.0 wrapt 1.12.1 youtube-dl 2020.11.29 zeroconf 0.28.6 zipp 3.4.0 ```
LaTeX details + LaTeX distribution: TeX Live
FFMPEG Output of `ffmpeg -version`: ``` ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers built with gcc 10 (Debian 10.2.1-1) configuration: --disable-decoder=amrnb --disable-decoder=libopenjpeg --disable-gnutls --disable-libopencv --disable-podpages --disable-sndio --disable-stripping --enable-avfilter --enable-avresample --enable-gcrypt --enable-gpl --enable-ladspa --enable-libaom --enable-libaribb24 --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libfdk-aac --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libjack --enable-libkvazaar --enable-liblensfun --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-nonfree --enable-openal --enable-opencl --enable-opengl --enable-openssl --enable-postproc --enable-pthreads --enable-shared --enable-version3 --enable-vulkan --incdir=/usr/include/x86_64-linux-gnu --libdir=/usr/lib/x86_64-linux-gnu --prefix=/usr --toolchain=hardened --enable-frei0r --enable-chromaprint --enable-libx264 --enable-libiec61883 --enable-libdc1394 --enable-vaapi --enable-libmfx --enable-libvmaf --disable-altivec --shlibdir=/usr/lib/x86_64-linux-gnu libavutil 56. 51.100 / 56. 51.100 libavcodec 58. 91.100 / 58. 91.100 libavformat 58. 45.100 / 58. 45.100 libavdevice 58. 10.100 / 58. 10.100 libavfilter 7. 85.100 / 7. 85.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 7.100 / 5. 7.100 libswresample 3. 7.100 / 3. 7.100 libpostproc 55. 7.100 / 55. 7.100 ```

Additional comments

See also this bug report: https://github.com/3b1b/manim/issues/999

huguesdevimeux commented 3 years ago

That's an important bug. Thanks for reporting, and sorry for not reponding sooner.

huguesdevimeux commented 3 years ago

For future reference: This issue comes from here https://github.com/ManimCommunity/manim/blob/79eb1985638309e15d352a7fa4aeb1b25dd3e906/manim/camera/three_d_camera.py#L258-L294

The factor variable is too close to 1, for some reason. Either the formula is wrong or the variable zs is not what it is supposed to be.

andryandrew commented 3 years ago

It doesn't seem that the distance attribute is ignored, rather it might be a semantic issue: as the code below shows, it appears to actually control the amount of perspective distortion:

class DebugCamera(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(phi=PI/3, theta=PI/4, distance=15)
        self.renderer.camera.exponential_projection=True

        axes = ThreeDAxes()
        cube = Cube()
        self.add(axes, cube)

        self.play(
            self.renderer.camera.distance_tracker.animate.set_value(3),
            rate_func=there_and_back,
            run_time=6
        )
Click for Video https://user-images.githubusercontent.com/29781022/108546841-f9deb280-72e9-11eb-935b-c6dd9f6d59d3.mp4

Of course it might just be a bug, but the code in project_points() doesn't suggest that it should do anything else.

suhailsherif commented 2 years ago

The camera implicitly defines a frame rectangle by its frame_center and the frame width and height.

To understand distance, imagine this experiment. Think of the frame rectangle as a window. Stand "distance" many units away from the center of this window and take a photo of it. Now crop the picture so that the window fills the whole picture. That cropped window is what should be rendered.

So any stickers stuck on the window itself will never change position regardless of the distance. However, distance does affect things. If the distance is small, when you look at the window you will actually see things that are behind and to to the side of the window, because the field of view of the window is a large angle. If the distance is really large you will only see things directly behind the window and not things behind and to the side. Similarly it will also affect objects in front of the window.

I hope this was helpful.

Viicos commented 2 years ago

Using the zoom parameter should produce better results.

lrfinotti commented 2 years ago

(OP here...) It is still not clear to me how to zoom out in a 3D Scene. As you can see in the original video, the shot does not cover the whole axes. I thought that the distance parameter would do it, but it seems I misinterpreted the meaning.

As Viicos suggested, I tried looking at the zoom parameter. But it does not seem to work either. In fact, although the documentation indicates that set_camera_orientation has a zoom parameter, I get an error (in manim 0.4.0) when trying to set it.

Traceback (most recent call last):
  File "/home/finotti/.local/lib/python3.9/site-packages/manim/__main__.py", line 95, in main
    scene.render()
  File "/home/finotti/.local/lib/python3.9/site-packages/manim/scene/scene.py", line 169, in render
    self.construct()
  File "/home/finotti/tmp/manim-test/manim-test.py", line 15, in construct
    self.set_camera_orientation(phi=0*DEGREES, theta=-90*DEGREES, zoom=0.1)
TypeError: set_camera_orientation() got an unexpected keyword argument 'zoom'

Is there a way to not have the 3D Axes so close?

Viicos commented 2 years ago

The zoom parameter is new since 0.10.0 and was implemented in #1929. I strongly advise you using it. In fact the distance parameter has been renamed to focal_distance. Here's a preview of the zoom effect:

Video https://user-images.githubusercontent.com/65306057/141365635-bfba160e-3f25-4d18-95ca-5bc5714db9fb.mp4
Code ```py class Sample(ThreeDScene): def construct(self): axes = ThreeDAxes() cube = Cube() self.set_camera_orientation( phi=15 * DEGREES, theta=-45 * DEGREES ) self.add(axes, cube) self.move_camera( zoom=0.5, run_time=3, rate_func=there_and_back ) self.wait() ```
lrfinotti commented 2 years ago

@Viicos: thanks for the reply! That is exactly what I was looking for! (I thought I had the latest version installed...)

I suppose this bug can be closed, unless someone has any objections.

Thanks all for the great support!

icedcoffeeee commented 2 years ago

Fixed via #1929