GLMakie Camera Controls vs Scene Controls

I am trying to do a very simple thing - Create a Scene in GLMakie and then control it’s camera.

using GLMakie: Scene, scatter!, Circle, display, text!

s1 = Scene()
scatter!(s1, (0, 0), marker = Circle, markersize = 200, color = :red)
# text!(s1, (0, 0), text="(0,0)", color=:black, fontsize=12, align=(:center, :center))
scatter!(s1, (1, 0), marker = Circle, markersize = 200, color = :blue)
# text!(s1, (1, 0), text="(1,0)", color=:black, fontsize=12, align=(:center, :center))
scatter!(s1, (-1, 0), marker = Circle, markersize = 200, color = :green)
# text!(s1, (-1, 0), text="(-1,0)", color=:black, fontsize=12, align=(:center, :center))

display(s1)

# Creating a standard number plane for visualization
using GLMakie: lines!, text!

# Draw a line at each  0.5 units in the x and y direction and at each point on the line intersection, write a text with the coordinate of point with respect to the origin, the default x and y range is (-10, 10) for both axes

function draw_number_plane(scene; x_range=[-10, 10], y_range=[-10, 10], step=0.5)
    for x in x_range[1]:step:x_range[2]
        lines!(scene, [x, x], y_range, color=:gray, linewidth=0.5) # vertical lines
    end
    for y in y_range[1]:step:y_range[2]
        lines!(scene, x_range, [y, y], color=:gray, linewidth=0.5) # horizontal lines
    end

    # Write the text for each intersection 
    for x in x_range[1]:step:x_range[2]
        for y in y_range[1]:step:y_range[2]
            text!(scene, (x, y), text="($x, $y)", color=:black, fontsize=8, align=(:center, :center))
        end
    end
end

draw_number_plane(s1, x_range=[-10, 10], y_range=[-10, 10], step=0.5)

This creates a very nice grid in a Makie Scene

(For some reason, Axis(s1, …) didn’t work, so this was the method I came up with)

I then try

using GLMakie: translate!
# Translate the scene by (1, 1)
translate!(s1, (1, 1))
text!(s1, (-1, -1), text="(-1,-1) in transformed scene", color=:black, fontsize=12, align=(:center, :center))
s1.transformation
#https://docs.makie.org/v0.22/reference/generic/transformations heres more on this

Amazing! That is exactly what I intended. I assume this shifts everything in the Scene by (1,1) unit in Normalized Device Coordinates (the default coordinate system in OpenGL and hence GLMakie where the screen spans -1 to 1 are the x and y direction limits)

using GLMakie: rotate!, qrotation, Vec3f

# Equivalent Approach of using Quaternions
# qr = qrotation(Vec3f(0, 0, 1), pi / 4)
# rotate!(s1, qr) # Rotate the scene by 45 degrees (π/4 radians)

rotate!(s1, pi / 4) # Alternatively, you can use radians directly (Internally uses Quaternions)

Instead of rotating everything nicely by 45 degrees, it sort of applies a weighted rotation to everything, squishing everything.

This makes me wonder that these transformations are not those of the camera but the screen space coordinates of the scene (and hence all objects rendered in it) itself.

rotate!(s1, pi / 2)

I wonder why rotation by 90 degrees doesn’t squish things (well maybe it does since the distance between each point in x is still more than that in y)


I thus tried using rotate_cam! instead, as I realized that is what would actually be used to not disturb anything within the scene, but just move the camera around within the scene.

rotate_cam!(s1, Vec3f(0,0,45))

But this gives an error

MethodError: no method matching rotate_cam!(::Scene, ::Makie.EmptyCamera, ::Tuple{Float64})

Closest candidates are:
  rotate_cam!(::Scene, !Matched::Makie.OldCamera3D, ::Union{Tuple{Vararg{T, N}}, StaticArraysCore.StaticArray{Tuple{N}, T, 1}} where {N, T}, !Matched::Bool)
   @ Makie C:\Users\DELL\.julia\packages\Makie\ux0Te\src\camera\old_camera3d.jl:308
  rotate_cam!(::Scene, !Matched::Makie.OldCamera3D, ::Union{Tuple{Vararg{T, N}}, StaticArraysCore.StaticArray{Tuple{N}, T, 1}} where {N, T})
   @ Makie C:\Users\DELL\.julia\packages\Makie\ux0Te\src\camera\old_camera3d.jl:308
  rotate_cam!(::Any, !Matched::Makie.Camera3D, ::Union{Tuple{Vararg{T, N}}, StaticArraysCore.StaticArray{Tuple{N}, T, 1}} where {N, T}, !Matched::Any)
   @ Makie C:\Users\DELL\.julia\packages\Makie\ux0Te\src\camera\camera3d.jl:526
  ...


Stacktrace:
 [1] rotate_cam!(scene::Scene, theta_v::Float64)
   @ Makie C:\Users\DELL\.julia\packages\Makie\ux0Te\src\camera\old_camera3d.jl:306
 [2] top-level scope
   @ e:\Programming\Canvas\jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_X60sZmlsZQ==.jl:10

I don’t know why it didn’t work, even though the documentation uses it in a similar way (There isn’t explicitly an example under Cameras section).

Here’s an answer I found. My usual strategy while using Scenes is that things that work on figures usually work on scenes too, but generally by passing scene as the first parameter.
It seemingly doesn’t work for this.

I tried a bunch of different variations of using the function, but it didn’t work.


How do I manipulate the camera in a Scene? Any good suggestions, notes, or examples of moving the camera around (position as well as eye position if those are any different; rotations) vs. transforming the scene around?

Also, any nice explanations of the Spaces? Space vs. Markerspace in 2D vs. 3D and what does either do?

Thanks!