How can I render a cube using a draw triangle function?

Now hear me out, but how could I do this? Let’s say that I have no camera, literally just a draw triangle function. drawTriangle(x1, y1, x2, y2, x3, y3)

I want to draw a cube. Or even a square. Something simple for now. I could possibly get the vertices, BUT mostly I want to know how I would move them. Like if I had a cube, how would I rotate the vertices?
I don’t have a camera. At all. Just triangles.

If you know anything, please help me. I don’t know where else to post this. This is the only scripting forum that I might actually get a couple responses.

1 Like

Imagine a triangle is an array of Vector2s.
To move the triangle to the left one unit:

local triangle = etc…

for x = 1, #triangle do
	triangle[x].X = vertices.X - 1
end

To move the triangle up one unit:

local triangle = etc…

for y = 1, #triangle do
	triangle[y].Y = vertices.Y + 1
end

To translate an entire triangle by a Vector2:

local function translateTriangle(triangle, vec2) --triangle is in the format {Vector2, Vector2, Vector2} and vec2 is the Vector2 that you want to translate the triangle by
	local output = {Vector2.new, Vector2.new, Vector2.new}

	for z = 1, #triangle do
		output[z].X, output[z].Y = output[z].X + vec2.X, output[z].Y + vec2.Y
	end

	return output
end

All this code is untested by the way, but I hope you see where I’m coming from in case this code isn’t in the right format. Translation (moving the triangle around) is the easiest transformation you can do. Rotation is definitely the hardest. I’ll give you the transformation code for scaling but here’s the Wikipedia article for Rotation in geometry. Your question is basically “how do I use linear algebra?” It’s taking sets of points and transforming them and using the output for whatever. Enough with the boring stuff; you probably skipped [most of] it anyway.

Okay, here’s how to scale the triangle:

local function scaleTriangle(triangle, scaleX, scaleY, c) --The center is a Vector2 that represents where all the points would converge to if the triangle were scaled to zero. If not included, it defaults to the first point of the triangle
	local output = {Vector2.new, Vector2.new, Vector2.new}
	local center = c

	if not center then
		center = triangle[1]
	end

	for j = 1, #triangle do
		output[j].X = center.X + (scaleX * (triangle[j].X - center.X)) --Linearly interpolates from the center point to the original point on the X axis
		output[j].Y = center.Y + (scaleY * (triangle[j].Y - center.Y)) --Linearly interpolates from the center point to the original point on the Y axis
	end

	return output
end

It looks pretty clean! I hope this is what you’re looking for and something other people will get something out of, too. If you don’t want to have to come up with everything yourself, just look up “transformation matrices in python” (or Lua, but Python is more popular) and study what you find. Happy coding!

Edit: I forgot that you want to make things out of your triangles. To make a square (two triangles) do this:

local triangleA = {Vector2.new(0, 0), Vector2.new(0, 1), Vector2.new(1, 0)}
local triangleB = {Vector2.new(1, 1), Vector2.new(0, 1), Vector2.new(1, 0)}
local square = {triangleA, triangleB} --You could put any triangles in here and just call it a mesh. Meshes are usually 3D but all the principles are identical.

Then, to move the square, call translateTriangles in a loop

local function translateMesh(mesh, vec2) --your square is a mesh; you would just put in an array of triangles, which is what your square is
	local output = {}

	for x = 1, #mesh do
		output[x] = translateTriangle(mesh[x], vec2)
	end

	return output
end

I hope this works for whatever you’re doing. Also, if you figure out how to render individual triangles in 3D using the RenderService, please tell me. I thought I saw that somewhere.