Question: I need help to create a torus out of a circle by revolving it about x=2r, r is the radius of the circle. I am open to either JULIA code or Python code. Whichever that can solve my problem the most efficient. I have Julia code to plot circle and the x=2r as the axis of revolution. using Plots, LaTeXStrings, Plots.PlotMeasures gr() θ = 0:0.1:2.1π x = 0 .+ 2cos.(θ) y = 0 .+ 2sin.(θ) plot(x, y, label=L"x^{2} + y^{2} = a^{2}", framestyle=:zerolines, legend=:outertop) plot!([4], seriestype="vline", color=:green, label="x=2a")   I want to create a torus out of it, but unable, meanwhile I have solid of revolution Python code like this: # Calculate the surface area of y = sqrt(r^2 - x^2) # revolved about the x-axis import matplotlib.pyplot as plt import numpy as np import sympy as sy x = sy.Symbol("x", nonnegative=True) r = sy.Symbol("r", nonnegative=True) def f(x): return sy.sqrt(r**2 - x**2) def fd(x): return sy.simplify(sy.diff(f(x), x)) def f2(x): return sy.sqrt((1 + (fd(x)**2))) def vx(x): return 2*sy.pi*(f(x)*sy.sqrt(1 + (fd(x) ** 2))) vxi = sy.Integral(vx(x), (x, -r, r)) vxf = vxi.simplify().doit() vxn = vxf.evalf() n = 100 fig = plt.figure(figsize=(14, 7)) ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222, projection='3d') ax3 = fig.add_subplot(223) ax4 = fig.add_subplot(224, projection='3d') # 1 is the starting point. The first 3 is the end point. # The last 200 is the number of discretization points. # help(np.linspace) to read its documentation. x = np.linspace(1, 3, 200) # Plot the circle y = np.sqrt(2 ** 2 - x ** 2) t = np.linspace(0, np.pi * 2, n) xn = np.outer(x, np.cos(t)) yn = np.outer(x, np.sin(t)) zn = np.zeros_like(xn) for i in range(len(x)): zn[i:i + 1, :] = np.full_like(zn[0, :], y[i]) ax1.plot(x, y) ax1.set_title("$f(x)$") ax2.plot_surface(xn, yn, zn) ax2.set_title("$f(x)$: Revolution around $y$") # find the inverse of the function y_inverse = x x_inverse = np.power(2 ** 2 - y_inverse ** 2, 1 / 2) xn_inverse = np.outer(x_inverse, np.cos(t)) yn_inverse = np.outer(x_inverse, np.sin(t)) zn_inverse = np.zeros_like(xn_inverse) for i in range(len(x_inverse)): zn_inverse[i:i + 1, :] = np.full_like(zn_inverse[0, :], y_inverse[i]) ax3.plot(x_inverse, y_inverse) ax3.set_title("Inverse of $f(x)$") ax4.plot_surface(xn_inverse, yn_inverse, zn_inverse) ax4.set_title("$f(x)$: Revolution around $x$ \n Surface Area = {}".format(vxn)) plt.tight_layout() plt.show()  

Answer: My take with Makie: using GLMakie Base.@kwdef mutable struct Torus R::Float64 = 2 r::Float64 = 1 end function generate_torus(torus::Torus, resolution=100; upto=1.0) u = range(0, stop=2π*upto, length=resolution) v = range(0, stop=2π*upto, length=resolution) x = [ ( torus.R + torus.r*cos(vᵢ) ) * cos(uᵢ) for vᵢ in v, uᵢ in u ] y = [ ( torus.R + torus.r*cos(vᵢ) ) * sin(uᵢ) for vᵢ in v, uᵢ in u ] z = [ torus.r * sin(vᵢ) for vᵢ in v, _ in u ] return x, y, z end function animate_torus(torus::Torus, filename="torus.gif") fig = Figure(resolution = (500, 500)) ax = fig[1, 1] = LScene(fig) cam3d!(ax.scene) # Initialize surface plot with full torus x, y, z = generate_torus(torus) p = surface!(ax, x, y, z, colormap=:viridis, shading = false) # Set the limits xlims!(ax.scene, (-4, 4)) ylims!(ax.scene, (-4, 4)) zlims!(ax.scene, (-1, 1)) record(fig, filename, range(0, stop=1, length=100)) do i # Update data of surface plot x, y, z = generate_torus(torus, upto=i) p[1] = x p[2] = y p[3] = z end end   And with Plots using Plots Base.@kwdef mutable struct Torus x::Float64 = cos(0) + cos(0)*cos(0) y::Float64 = sin(0) + cos(0)*sin(0) z::Float64 = sin(0) end function step!(torus::Torus, t, u; r=1) torus.x = r*cos(t) + cos(u)*cos(t) torus.y = r*sin(t) + cos(u)*sin(t) torus.z = sin(u) return torus end torus = Torus() plt = plot([0], [0], [0], aspect_ratio=:equal, xlims=(-3, 3), ylims=(-3, 3), zlims=(-3, 3)) @gif for t in range(0, stop=2π, length=100) for u in range(0, stop=2π, length=100) step!(torus, t, u, r=2) push!(plt, torus.x, torus.y, torus.z) end end every 2