From 3fbfc1fb1563873c5f065a971d220a8ae4458b25 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sat, 15 May 2021 02:00:40 +0100 Subject: [PATCH] torus: rework to add axes, but it's not finished yet --- worldeditadditions/lib/torus.lua | 15 ++++- .../commands/torus.lua | 67 +++++++++++++------ 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/worldeditadditions/lib/torus.lua b/worldeditadditions/lib/torus.lua index df4734f..22e23f4 100644 --- a/worldeditadditions/lib/torus.lua +++ b/worldeditadditions/lib/torus.lua @@ -1,7 +1,16 @@ --- Overlap command. Places a specified node on top of -- @module worldeditadditions.overlay -function worldeditadditions.torus(position, major_radius, minor_radius, target_node, hollow) +--- Generates a torus shape at the given position with the given parameters. +-- @param position Vector The position at which to generate the torus. +-- @param major_radius number The major radius of the torus - i.e. the distance from the middle to the ring. +-- @param minor_radius number The minor radius of the torus - i.e. the radaius fo the ring itself. +-- @param target_node string The name of the target node to generate the torus with. +-- @param axes=xz string|nil The axes upon which the torus should lay flat. +-- @param hollow=false boolean Whether the generated torus should be hollow or not. +function worldeditadditions.torus(position, major_radius, minor_radius, target_node, axes, hollow) + if type(axes) ~= "string" then axes = "xz" end + -- position = { x, y, z } local total_radius = major_radius + minor_radius local inner_minor_radius = minor_radius - 2 @@ -33,6 +42,10 @@ function worldeditadditions.torus(position, major_radius, minor_radius, target_n for x = -total_radius, total_radius do local x_sq = x*x + if axes == "xz" then + -- TODO: Figure out which 2 axes we need to fiddle here + end + -- (x^2+y^2+z^2-(a^2+b^2))^2-4 a b (b^2-z^2) -- Where: -- (x, y, z) is the point diff --git a/worldeditadditions_commands/commands/torus.lua b/worldeditadditions_commands/commands/torus.lua index 0d6d4a7..2156e32 100644 --- a/worldeditadditions_commands/commands/torus.lua +++ b/worldeditadditions_commands/commands/torus.lua @@ -4,33 +4,58 @@ -- ██ ██ ██ ██ ██ ██ ██ ██ -- ██ ██████ ██ ██ ██████ ███████ local function parse_params_torus(params_text) - local found, _, major_radius, minor_radius, replace_node = params_text:find("([0-9]+)%s+([0-9]+)%s+([a-z:_\\-]+)") + local parts = worldeditadditions.split(params_text, "%s+", false) + print("[DEBUG:torus/parts]") + for i = 1, #parts, 1 do print(parts[i]) end + -- local found, _, major_radius, minor_radius, replace_node, axes = params_text:find("([0-9]+)%s+([0-9]+)%s+([a-z:_\\-]+)%s+([xyz]+)") - if found == nil then - return nil, nil - end + if #parts < 3 then return nil, nil, nil end - major_radius = tonumber(major_radius) - minor_radius = tonumber(minor_radius) - - replace_node = worldedit.normalize_nodename(replace_node) - - if not replace_node then + if #parts < 1 then return false, "Error: Invalid replace_node." end - if not major_radius or major_radius < 1 then + if #parts < 2 then return false, "Error: Invalid major radius (expected integer greater than 0)" end - if not minor_radius or minor_radius < 1 then + if #parts < 3 then return false, "Error: Invalid minor radius (expected integer greater than 0)" end - return true, replace_node, major_radius, minor_radius + local major_radius = tonumber(parts[1]) + local minor_radius = tonumber(parts[2]) + local replace_node = worldedit.normalize_nodename(parts[3]) + local axes + if #parts > 3 then axes = parts[4] end + if not axes then axes = "xy" end + + if major_radius < 1 then + return false, "Error: The major radius must be greater than 0." + end + if minor_radius < 1 then + return false, "Error: The minor radius must be greater than 0." + end + if not replace_node then + return false, "Error: Invalid node name." + end + if axes:find("[^xyz]") then + return false, "Error: The axes may only contain the latters x, y, and z." + end + if #axes ~= 2 then + return false, "Error: Exactly 2 axes must be specified. For example, 'xy' is valid, but 'xyy' is not (both of course without quotes)." + end + + + -- Sort the axis names (this is important to ensure we can identify the direction properly) + if axes == "yx" then axes = "xy" end + if axes == "zx" then axes = "xz" end + if axes == "zy" then axes = "yz" end + + return true, replace_node, major_radius, minor_radius, axes end worldedit.register_command("torus", { - params = " ", - description = "Creates a 3D torus with a major radius of and a minor radius of at pos1, filled with .", + params = " []", + description = "Creates a 3D torus with a major radius of and a minor radius of at pos1, filled with , on axes (i.e. 2 axis names: xz, zy, etc).", privs = { worldedit = true }, require_pos = 1, parse = function(params_text) @@ -40,9 +65,9 @@ worldedit.register_command("torus", { nodes_needed = function(name, target_node, major_radius, minor_radius) return math.ceil(2 * math.pi*math.pi * major_radius * minor_radius*minor_radius) end, - func = function(name, target_node, major_radius, minor_radius) + func = function(name, target_node, major_radius, minor_radius, axes) local start_time = worldeditadditions.get_ms_time() - local replaced = worldeditadditions.torus(worldedit.pos1[name], major_radius, minor_radius, target_node, false) + local replaced = worldeditadditions.torus(worldedit.pos1[name], major_radius, minor_radius, target_node, axes, false) local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //torus at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. replaced .. " nodes in " .. time_taken .. "s") @@ -52,20 +77,20 @@ worldedit.register_command("torus", { -- TODO: This duplicates a lot of code. Perhaps we can trim it down a bit? worldedit.register_command("hollowtorus", { - params = " ", - description = "Creates a 3D hollow torus with a major radius of and a minor radius of at pos1, made out of .", + params = " []", + description = "Creates a 3D hollow torus with a major radius of and a minor radius of at pos1, made out of , on axes (i.e. 2 axis names: xz, zy, etc).", privs = { worldedit = true }, require_pos = 1, parse = function(params_text) local values = {parse_params_torus(params_text)} return unpack(values) end, - nodes_needed = function(name, target_node, major_radius, minor_radius) + nodes_needed = function(name, target_node, major_radius, minor_radius, axes) return math.ceil(2 * math.pi*math.pi * major_radius * minor_radius*minor_radius) end, func = function(name, target_node, major_radius, minor_radius) local start_time = worldeditadditions.get_ms_time() - local replaced = worldeditadditions.torus(worldedit.pos1[name], major_radius, minor_radius, target_node, true) + local replaced = worldeditadditions.torus(worldedit.pos1[name], major_radius, minor_radius, target_node, axes, true) local time_taken = worldeditadditions.get_ms_time() - start_time minetest.log("action", name .. " used //hollowtorus at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. replaced .. " nodes in " .. time_taken .. "s")