As promised, here’s a sample of the code that you helped fix:
using GLMakie
# Converts 3-element vectors or 3-tuples into 3 vectors for calling Makie functions
function to_components(vectors::Vector{T}) where T <: Union{
Vector{<:Integer},
Vector{<:AbstractFloat},
Tuple{<:Integer,<:Integer,<:Integer},
Tuple{<:AbstractFloat,<:AbstractFloat,<:AbstractFloat}
}
xs = Float64[]
ys = Float64[]
zs = Float64[]
for ve in vectors
push!(xs, ve[1])
push!(ys, ve[2])
push!(zs, ve[3])
end
xs, ys, zs
end
function draw_axis()
fig = Figure()
lscene = LScene(fig[1,1])
# Generate crosshairs at origin
ps = [-1,1]
origin = vcat(
[[x,0,0] for x in ps],
[[0,y,0] for y in ps],
[[0,0,z] for z in ps]
)
xs, ys, zs = to_components(origin)
# Draw and display crosshairs
linesegments!(xs, ys, zs, linewidth=5, color=:brown)
fig
end
# Helper function; draws a vector outlined by a cube with highlighted verices
function vector_box(tail::T, tip::S; clr=:black) where {
T <: Union{Vector{<:Integer},Vector{<:AbstractFloat}},
S <: Union{Vector{<:Integer},Vector{<:AbstractFloat}}
}
# Destructure the ends of the vector
x, y, z = tail
s, t, u = tip
# Use the components of the endpoints of the vector to set up permutation vectors
# so that the computer can perform the iterative process of generating the vertex
# vectors and edge vectors
trans_x = [x, s]
trans_y = [y, t]
trans_z = [z, u]
# Generate a mulit-dimensional array containing points that define the vertices
vertices = [[x, y, z] for x in trans_x, y in trans_y, z in trans_z]
# Generate a multidimensional array containing the point pairs that define the edges
edges_pre = vcat(
[[[x,y,z],[s,y,z]] for y in trans_y, z in trans_z],
[[[x,y,z],[x,t,z]] for x in trans_x, z in trans_z],
[[[x,y,z],[x,y,u]] for x in trans_x, y in trans_y]
)
# Container for the vectorized (re-shaped) edges array
edges_mid = Vector{Float64}[]
# Destructure the edge pairs so they can be further destructured for plotting
for edge in vec(edges_pre)
t1, t2 = edge
push!(edges_mid, t1)
push!(edges_mid, t2)
end
# Finally get lists of edge components for plotting
edges_x, edges_y, edges_z = to_components(edges_mid)
# Plot the vector outlined with a cube
xs, ys, zs = to_components(vec(vertices))
meshscatter!(xs, ys, zs, color=clr, markersize=0.3)
linesegments!(edges_x, edges_y, edges_z, linestyle=:dot, color=clr, linewidth=5)
arrows!([x], [y], [z], [s], [t], [u], color=clr, linewidth=0.25)
end
# Helper function
# NOTE: This function requires a Figure object!
# use draw_axis3D or another means to initialize a Figure.
# Geometrically adds an arbitrary number of 3D vectors
# Vectors to be summed must be given as a list
# e.g., add([[1,2,3], [4,5,6]]) will return [5,7,9]
function add(vectors::Vector{T}) where T <: Union{
Vector{<:Integer},
Vector{<:AbstractFloat}
}
# Draw the vectors to be summed
prev = [0,0,0]
for ve in vectors
clr = RGBf(rand(3)...)
vector_box(prev, prev .+ ve; clr)
prev = prev .+ ve
end
# Draw the summation vector labeled with the summed point
vector_box([0,0,0], prev; clr=:springgreen2)
text!("$(prev)", position = (prev[1],prev[2],prev[3]), color=:red)
end
# A convenience function that provides its own axis for ploting single operations.
# Use draw_axis3D() with separate vector functions for more complex operations.
# Geometrically adds an arbitrary number of 3D vectors
# Vectors to be summed must be given as a list
# e.g., draw_add([[1,2,3], [4,5,6]]) will return [5,7,9]
function draw_add(vectors::Vector{T}) where T <: Union{Vector{<:Integer}, Vector{<:AbstractFloat}
}
# Establish axes, plot and dispay vectors
draw_axis()
add(vectors)
current_figure()
end
For example, you could execute
draw_add([[-1,-2,-3],[-4,-5,-6],[7,8,9]])
Thanks again!