Skip to content

Commit

Permalink
Added cylinder
Browse files Browse the repository at this point in the history
  • Loading branch information
matiasvlevi committed Sep 9, 2024
1 parent 23619c4 commit fcf7fbf
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 72 deletions.
27 changes: 21 additions & 6 deletions examples/3D.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,37 @@ end
function draw()
background(0);


orbitControl();

fill(0, 255, 0);
text('Drag the mouse around', 40, 40);

push();
noFill();
stroke(0, 255, 0);
sphere(100);
translate(-90, 0, 0);
sphere(30);
pop();

push();
rotateX(90);
noFill();
stroke(0, 255, 0)
plane(400, 400)
pop();
stroke(0, 255, 0);
translate(0, 0, 0);
cylinder(30, 60);
pop(0);

push();
noFill();
stroke(0, 255, 0);
translate(90, 0, 0);
box(50, 60);
pop(0);

push();
translate(0, 32, 0);
rotateX(90);
fill(51)
plane(400, 400);
pop();

end
89 changes: 38 additions & 51 deletions src/bindings/shapes3D.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,54 +109,41 @@ int sphere(lua_State *L)
return 0;
}

// int cylinder(lua_State *L)
// {
// lua_Number radius = lu5_assert_number(L, 1, "cylinder");
// lua_Number height = lu5_assert_number(L, 2, "cylinder");

// lua_Number detail_x = 24;
// if (lua_isboolean(L, 3)) {
// detail_x = lua_toboolean(L, 3);
// }

// lua_Number detail_y = 24;
// if (lua_isboolean(L, 4)) {
// detail_y = lua_toboolean(L, 4);
// }

// bool top_cap = false;
// if (lua_isboolean(L, 5)) {
// top_cap = lua_toboolean(L, 5);
// }

// bool bottom_cap = false;
// if (lua_isboolean(L, 6)) {
// bottom_cap = lua_toboolean(L, 6);
// }

// if (lu5_has_fill())
// {
// lu5_apply_color(lu5_style(&lu5)->fill);
// lu5_render_cylinder_faces(radius, height,
// top_cap,
// bottom_cap);
// }

// if (lu5_has_stroke())
// {
// // Draw sphere edges
// lu5_apply_color(lu5_style(&lu5)->stroke);
// glLineWidth(lu5_style(&lu5)->strokeWeight);

// // Draw stroke with a larger radius
// lu5_render_cylinder_edges(
// radius + 1.0f,
// height,
// detail_x, detail_y
// top_cap,
// bottom_cap
// );
// }

// return 0;
// }
int cylinder(lua_State *L)
{
lua_Number radius = lua_isnumber(L, 1) ? lua_tonumber(L, 1) : 50.0;
lua_Number height = lua_isnumber(L, 2) ? lua_tonumber(L, 2) : radius;

lua_Number detail_x = lua_isnumber(L, 3) ? lua_tonumber(L, 3) : 24;
lua_Number detail_y = lua_isnumber(L, 4) ? lua_tonumber(L, 4) : 1;

bool bottom_cap = lua_isboolean(L, 5) ? lua_toboolean(L, 5) : true;
bool top_cap = lua_isboolean(L, 6) ? lua_toboolean(L, 6) : true;

if (lu5_has_fill())
{
lu5_apply_color(lu5_style(&lu5)->fill);
lu5_render_cylinder_faces(radius, height,
detail_x, detail_y,
top_cap,
bottom_cap);
}

if (lu5_has_stroke())
{
// Draw sphere edges
lu5_apply_color(lu5_style(&lu5)->stroke);
glLineWidth(lu5_style(&lu5)->strokeWeight);

// Draw stroke with a larger radius
lu5_render_cylinder_edges(
radius + 0.5f,
height + 0.5f,
detail_x, detail_y,
top_cap,
bottom_cap
);
}

return 0;
}
24 changes: 24 additions & 0 deletions src/bindings/shapes3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,29 @@ int box(lua_State *L);
*/
int sphere(lua_State *L);

/**
* Draw a 3D Cylinder.
*
* @param radius radius of the cylinder. Defaults to 50.
* @param height height of the cylinder. Defaults to the value of radius.
* @param detailX number of horizontal edges. Defaults to 24.
* @param detailY number of subdivisions along the y-axis. Defaults to 1.
* @param bottomCap whether to draw the cylinder's bottom. Defaults to true.
* @param topCap whether to draw the cylinder's top. Defaults to true.
*
* @example
* function setup()
* createWindow(800, 800, GL3D);
* end
*
* function draw()
* background(51);
*
* cylinder(30, 50);
* end
* @example
*/
int cylinder(lua_State *L);


#endif /* _LU5_SHAPES3D_H_ */
76 changes: 62 additions & 14 deletions src/geometry/3D/lu5_cylinder.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ void lu5_render_cylinder_faces(
}

void lu5_render_cylinder_edges(
lua_Number radius, lua_Number height,
lua_Integer detail_x, lua_Integer detail_y,
bool bottom_cap,
bool top_cap)
lua_Number radius, lua_Number height,
lua_Integer detail_x, lua_Integer detail_y,
bool bottom_cap,
bool top_cap)
{
lua_Number half_height = height / 2.0;

// Draw vertical lines
for (lua_Integer j = 0; j <= detail_x; j++) {
lua_Number theta = 2 * M_PI * j / (lua_Number)detail_x;
lua_Number cos_theta = cosf(theta);
Expand All @@ -87,6 +88,7 @@ void lu5_render_cylinder_edges(
glEnd();
}

// Draw horizontal lines
for (lua_Integer i = 0; i <= detail_y; i++) {
lua_Number y = -half_height + (height * i / (lua_Number)detail_y);

Expand All @@ -104,34 +106,80 @@ void lu5_render_cylinder_edges(
glEnd();
}

// Draw diagonal edges
for (lua_Integer j = 0; j < detail_x; j++) {
lua_Number theta = 2 * M_PI * j / (lua_Number)detail_x;
lua_Number next_theta = 2 * M_PI * (j + 1) / (lua_Number)detail_x;
lua_Number cos_theta = cosf(theta);
lua_Number sin_theta = sinf(theta);
lua_Number cos_next_theta = cosf(next_theta);
lua_Number sin_next_theta = sinf(next_theta);

lua_Number x1 = cos_theta * radius;
lua_Number z1 = sin_theta * radius;
lua_Number x2 = cos_next_theta * radius;
lua_Number z2 = sin_next_theta * radius;

glBegin(GL_LINES);
for (lua_Integer i = 0; i < detail_y; i++) {
lua_Number y = -half_height + (height * i / (lua_Number)detail_y);
lua_Number next_y = -half_height + (height * (i + 1) / (lua_Number)detail_y);
lu5_glVertex3(x2, y, z2);
lu5_glVertex3(x1, next_y, z1);
}
glEnd();
}

// Draw bottom cap
if (bottom_cap)
{
lua_Number y = -half_height;

glBegin(GL_LINE_LOOP);
for (lua_Integer j = 0; j < detail_x; j++) {
lua_Number theta = 2 * M_PI * j / (lua_Number)detail_x;
lua_Number next_theta = 2 * M_PI * ((j + 1) % detail_x) / (lua_Number)detail_x;
lua_Number cos_theta = cosf(theta);
lua_Number sin_theta = sinf(theta);

lua_Number x = cos_theta * radius;
lua_Number z = sin_theta * radius;

lu5_glVertex3(x, -half_height, z);
lua_Number cos_next_theta = cosf(next_theta);
lua_Number sin_next_theta = sinf(next_theta);

lua_Number x1 = cos_theta * radius;
lua_Number z1 = sin_theta * radius;
lua_Number x2 = cos_next_theta * radius;
lua_Number z2 = sin_next_theta * radius;

// Draw the triangle fan lines
lu5_glVertex3(0, y, 0); // center
lu5_glVertex3(x1, y, z1); // current vertex on the circle
lu5_glVertex3(x2, y, z2); // next vertex on the circle
}
glEnd();
}

// Draw top cap
if (top_cap)
{
lua_Number y = half_height;

glBegin(GL_LINE_LOOP);
for (lua_Integer j = 0; j < detail_x; j++) {
lua_Number theta = 2 * M_PI * j / (lua_Number)detail_x;
lua_Number next_theta = 2 * M_PI * ((j + 1) % detail_x) / (lua_Number)detail_x;
lua_Number cos_theta = cosf(theta);
lua_Number sin_theta = sinf(theta);

lua_Number x = cos_theta * radius;
lua_Number z = sin_theta * radius;

lu5_glVertex3(x, half_height, z);
lua_Number cos_next_theta = cosf(next_theta);
lua_Number sin_next_theta = sinf(next_theta);

lua_Number x1 = cos_theta * radius;
lua_Number z1 = sin_theta * radius;
lua_Number x2 = cos_next_theta * radius;
lua_Number z2 = sin_next_theta * radius;

// Draw the triangle fan lines
lu5_glVertex3(0, y, 0); // center
lu5_glVertex3(x1, y, z1); // current vertex on the circle
lu5_glVertex3(x2, y, z2); // next vertex on the circle
}
glEnd();
}
Expand Down
2 changes: 1 addition & 1 deletion src/lu5_bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void lu5_register_symbols(lua_State *L)

// Shapes 3D
LUA_ADD_FUNCTION(L, box);
// LUA_ADD_FUNCTION(L, cylinder);
LUA_ADD_FUNCTION(L, cylinder);
LUA_ADD_FUNCTION(L, sphere);
LUA_ADD_FUNCTION(L, plane);

Expand Down

0 comments on commit fcf7fbf

Please sign in to comment.