← BásicoObjeto 3Dfogon/pinza
Pinza
Arrastrá para girarlo// «Pinza» · gpt-6-sol (medium)
// Pliers («Pinza»).
// Pliers lying flat, with open silver jaws and ribbed red grips.
function inside(x, y, p) {
let hit = false;
for (let i = 0, j = p.length - 1; i < p.length; j = i++) {
const a = p[i], b = p[j];
if ((a[1] > y) !== (b[1] > y) &&
x < (b[0] - a[0]) * (y - a[1]) / (b[1] - a[1]) + a[0]) hit = !hit;
}
return hit;
}
function plate(points, bottom, top) {
for (let x = 4; x <= 45; x++) for (let y = 5; y <= 43; y++) {
if (!inside(x + 0.5, y + 0.5, points)) continue;
for (let z = bottom; z <= top; z++) {
let c = z === bottom ? "#52616a"
: z < top - 2 ? "#87969c"
: z < top ? "#b8c5c7"
: rand() < 0.18 ? "#f0f3ed" : "#dce5e3";
set(x, y, z, c);
}
}
}
function grip(ax, ay, bx, by, radius) {
const dx = bx - ax, dy = by - ay, len2 = dx * dx + dy * dy;
for (let x = 18; x <= 45; x++) for (let y = 5; y <= 43; y++) {
const t = ((x - ax) * dx + (y - ay) * dy) / len2;
const q = Math.max(0, Math.min(1, t));
const dist = Math.hypot(x - ax - q * dx, y - ay - q * dy);
if (dist > radius || t < -0.08 || t > 1.09) continue;
const cap = t > 0.88;
const rib = !cap && t > 0.12 && Math.abs((t * 7.5) % 1 - 0.5) < 0.19;
const height = cap ? 6 : rib ? 8 : 7;
for (let z = 0; z <= height; z++) {
let c;
if (cap) c = z < 3 ? "#202b33" : z < 6 ? "#35434b" : "#485660";
else if (z < 2) c = "#742825";
else if (z < 5) c = rib ? "#a82d2a" : "#922a28";
else if (rib) c = z === 8 ? "#e55042" : "#c53a31";
else c = dist < radius - 1.2 ? "#cc3c33" : "#aa302c";
set(x, y, z, c);
}
}
}
// The two separated, broad gripping jaws.
plate([[6,10],[11,10],[13,12],[16,12],[19,15],[23,18],
[25,21],[23,24],[20,24],[17,21],[14,20],[10,18],[6,17]], 1, 7);
plate([[8,24],[8,29],[12,29],[15,28],[19,28],[23,27],
[26,24],[24,21],[21,21],[18,23],[14,24]], 2, 8);
// Dark inset along the facing edges; small, square-cut jaw teeth.
for (let x = 8; x <= 16; x += 2) {
for (let y = 13; y <= 17; y++) {
if (get(x, y, 7)) set(x, y, 8, "#84979e");
}
for (let y = 25; y <= 28; y++) {
if (get(x, y, 8)) set(x, y, 9, "#93a5aa");
}
}
for (let x = 9; x <= 15; x += 3) {
line(x, 11, 8, x, 15, 8, 0, "#f4f5ed");
line(x, 25, 9, x, 28, 9, 0, "#edf3ee");
}
for (let x = 15; x <= 20; x += 2)
line(x, 23, 9, x, 24, 9, 0, "#718993");
// Exposed steel tangs where the handles meet the jaws.
line(21, 25, 4, 29, 32, 4, 3, "#657780");
line(21, 21, 4, 28, 15, 4, 3, "#687b83");
line(22, 26, 7, 29, 32, 7, 1, "#c7d3d2");
line(22, 20, 7, 28, 15, 7, 1, "#c5d0d0");
// Thick rubber handles, splayed apart, with raised molded ribs and dark tips.
grip(27, 29, 41, 39, 3.3);
grip(26, 17, 38, 8, 3.2);
// A few glints along the upper edges of the red grips.
line(29, 32, 8, 37, 37, 8, 0, "#e45043");
line(28, 15, 8, 34, 11, 8, 0, "#e34b40");
// Round, layered pivot and its central pin.
cylinder(22, 23, 5, 4, 3, "#899ca2");
cylinder(22, 23, 8, 3, 1, "#d8e2df");
cylinder(22, 23, 9, 2, 1, "#f0f2ea");
set(22, 23, 10, "#82959b");
set(23, 23, 10, "#aab9ba");import { draw } from "./assets/voxel";
import { pinza } from "./assets/pinza";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, pinza, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: lo que mide en px su lado más largo
// angle: giro sobre el piso, en radianes
// t: segundos; si se mueve, se anima solo con eso# En una terminal, en la carpeta del juego
fogon assets add pinza
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["pinza"] })
# Queda en client/assets/pinza.ts
# https://fogon.page/object/pinza