Using Math to generate Cylinders?

Maybe he wants a cylinder that is procedurally generated.

Cylinder is not an Instance type. Your code will error.
image

However, it is a PartType.

local Cylinder = Instance.new("Part")

Cylinder.Shape = Enum.PartType.Cylinder
2 Likes

I noticed you have made a couple of posts about shapes, so I feel the need to ask, what is your use case for this? Do you need to just render the surfaces of a cylinder? Or do you have to be able to compute every possible point inside the cylinder? If so then you would have to integrate through the length and radius as @SwagMasterAndrew pointed out.

1 Like

No, No, No I want a hollow cylinder generated by many many parts like the sphere code I want that only a cylinder shape

I need it for a infinite game im making using -perlin noise and custom structurs.,

1 Like

This is sorta off topic but I am trying to get into generating different shapes as well so I have some questions:

local Radius = 1
local Circle = math.pi * 2
local Amt = 10000
local Height = 10

for Y = 0, Height do
	for Number = 1, Amt do
		local Angle = Circle / Amt * Number
		local X = math.sin(Angle) * Radius
		local Z = math.cos(Angle) * Radius

		local Position = Vector3.new(X, Y, Z)
	end
end

How does multiplying pi by 2 make a circle (in your circle variable)?

Why do you use sin and cos, how does it work?

Also what is it mean if something is procedurally generated?

Thanks!

math.pi * 2 makes sure th circle is a full circle so math.pi * 1 would be a semi - circle etc

But pi is just a number, 3,14… How can that be a semi-circle?

because we are diving math.pi by Amt

You already have a function to generate a sphere. To generate cylinder with this method, all you have to do is to achieve a constant radius. Remove cosine factors from the coordinates calculations.

Cylinder Generation:

local function spiral_cylinder(num_points)
	local vectors = {}
	local gr = (math.sqrt(5) + 1) / 2
	local ga = (2 - gr) * (2 * math.pi)
	
	for i = 1, num_points do
		local lat = math.asin(-1 + 2 * i / (num_points + 1))
		local lon = ga * i
		
		local x = math.cos(lon) --remove * math.cos(lat)
		local y = math.sin(lon) --remove * math.cos(lat)
		local z = math.sin(lat)
		
		table.insert(vectors, Vector3.new(x, y, z))
	end
	
	return vectors
end

Hope this helps!

This does not make a Cylinder?

local function spiral_cylinder(num_points)
	local vectors = {}
	local gr = (math.sqrt(5) + 1) / 2
	local ga = (2 - gr) * (2 * math.pi)
	
	for i = 1, num_points do
		local lat = math.asin(-1 + 2 * i / (num_points + 1))
		local lon = ga * i
		
		local x = math.cos(lon) --remove * math.cos(lat)
		local y = math.sin(lon) --remove * math.cos(lat)
		local z = math.sin(lat)
		
		table.insert(vectors, Vector3.new(x, y, z))
	end
	
	return vectors
end

local Radius = 100

for Number, Vector3 in pairs(spiral_cylinder(1000)) do
	local Part = Instance.new("Part")
	Part.Anchored = true
	Part.CFrame = CFrame.new(Vector3.Unit * Radius)
	Part.Parent = workspace
end

I am not sure what Vector3.Unit is supposed to do, it sure behaves strange. However this works:

for Number, v in pairs(spiral_cylinder(1000)) do
	local Part = Instance.new("Part")
	Part.Anchored = true
	Part.CFrame = CFrame.new(v * Radius)
	Part.Parent = workspace
end

How would I change the length?

You will need to add another parameter for length. Due to way this function works, it will be still dependent on both this and radius though.

local function spiral_cylinder(num_points,length)
	local vectors = {}
	local gr = (math.sqrt(5) + 1) / 2
	local ga = (2 - gr) * (2 * math.pi)
	
	for i = 1, num_points do
		local lat = math.asin(-1 + 2 * i / (num_points + 1))
		local lon = ga * i
		
		local x = math.cos(lon) 
		local y = math.sin(lon) 
		local z = math.sin(lat) * length
		
		table.insert(vectors, Vector3.new(x, y, z))
	end
	
	return vectors
end

Usage:

for Number, v in pairs(spiral_cylinder(1000,10)) do
	local Part = Instance.new("Part")
	Part.Anchored = true
	Part.CFrame = CFrame.new(v * Radius)
	Part.Parent = workspace
end

Do you know how to generate a cuboid?

Here’s a sample I just typed up:

(I used the size and position of a brick named “Box” for the parameters)

local function hollow_cuboid(length, width, height, centerPosition, resolution)
	-- 'centerPosition' can be either a Vector3 or a CFrame
	-- (orientation will default to {0, 0, 0} if a Vector3 is used)
	local pos = (typeof(centerPosition) == "CFrame") and centerPosition
		or (typeof(centerPosition) == "Vector3") and CFrame.new(centerPosition)
		or CFrame.new()
	local vectors = {}
	local hl = length / 2
	local hw = width / 2
	local hh = height / 2
	local rr = 1 / resolution -- 'resolution' is points per stud, 'rr' is number of studs between points
	
	-- bottom + top (length * width)
	-- left + right (length * height)
	for i = -hl, hl, rr do
		for j = -hw, hw, rr do
			table.insert(vectors, (pos * CFrame.new(j, -hh, i)).Position)
			table.insert(vectors, (pos * CFrame.new(j, hh, i)).Position)
		end
		for j = -hh, hh, rr do
			table.insert(vectors, (pos * CFrame.new(-hw, j, i)).Position)
			table.insert(vectors, (pos * CFrame.new(hw, j, i)).Position)
		end
	end
	-- front + back (width * height)
	for i = -hw, hw, rr do
		for j = -hh, hh, rr do
			table.insert(vectors, (pos * CFrame.new(i, j, -hl)).Position)
			table.insert(vectors, (pos * CFrame.new(i, j, hl)).Position)
		end
	end
	return vectors
end

local box = workspace.Box.Size
local vs = hollow_cuboid(box.Z, box.X, box.Y, workspace.Box.CFrame, 1)

for _, v in ipairs(vs) do
	local p = Instance.new("Part")
	p.Size = Vector3.new(0.2, 0.2, 0.2)
	p.Anchored = true
	p.CFrame = CFrame.new(v)
	p.Parent = workspace
	--wait()
end

Result:

WOW! Thanks so much. This will help in my game a lot! btw, In my other thread didn’t you say you had a triangle generator?

It didn’t make triangle prisms like the rectangle script, it just draws a triangle between three vector3 vertices. I originally made it to render the surface of the sphere I mentioned in the last thread.

local function make_triangle(a, b, c, thickness)
	-- sanitize input
	a = (typeof(a) == "Vector3") and a or Vector3.new(0, 0, 0)
	b = (typeof(b) == "Vector3") and b or Vector3.new(1, 0, 0)
	c = (typeof(c) == "Vector3") and c or Vector3.new(0, 1, 0)
	thickness = math.max((tonumber(thickness) or 1), 0.05)

	-- re-order vertices so that AB is the longest side
	local a0, b0, c0 = a, b, c
	local ab = (a - b).Magnitude
	local bc = (b - c).Magnitude
	local ca = (a - c).Magnitude
	if (bc > ab) then
		-- ab not the longest side
		if (ca > bc) then
			-- ca longest
			a = c0
			b = a0
			c = b0
		else
			-- bc longest
			a = b0
			b = c0
			c = a0
		end
	else
		-- ab longer than bc
		if (ca > ab) then
			-- ca longest
			a = c0
			b = a0
			c = b0
		else
			-- ab longest
		end
	end
	ab = (a - b).Magnitude
	bc = (b - c).Magnitude
	ca = (a - c).Magnitude

	local area = (b - a):Cross(c - a).Magnitude / 2
	local h = 2 * area / ab
	local hx = math.sqrt((ca ^ 2) - (h ^ 2))

	-- cframe stuff
	local f = (b - a).Unit
	local u = (c - a).Unit
	local r = f:Cross(u).Unit
	local u2 = r:Cross(f).Unit
	local cf = CFrame.fromMatrix(a, r, u2)

	-- parts
	local p1 = Instance.new("WedgePart")
	p1.Anchored = true
	p1.Size = Vector3.new(thickness, h, hx)
	p1.CFrame = cf * CFrame.new(0, h / 2, -(hx / 2)) * CFrame.Angles(0, math.pi, 0)
	p1.Parent = workspace
	local p2 = Instance.new("WedgePart")
	p2.Anchored = true
	p2.Size = Vector3.new(thickness, h, ab - hx)
	p2.CFrame = cf * CFrame.new(0, h / 2, -(ab + hx) / 2)
	p2.Parent = workspace

	return p1, p2 -- so the user can do more stuff with it
end

So do you know how to make a 3D five-sided triangle made out of parts then?

Yes, though it’s just a solid triangle made from two wedge parts.

I mean lots of parts like the cuboid sphere and cylinder?