丰富了基本图形

This commit is contained in:
bk_office
2026-04-25 16:09:47 +08:00
parent 6a68db70f5
commit c3c22e7145
4 changed files with 90 additions and 5 deletions

View File

@ -8,8 +8,11 @@ cmd_marchtoy = on_command("march")
@cmd_marchtoy.handle()
async def _(args: Message = CommandArg()):
if cmd := args.extract_plain_text():
img = await render.render(cmd, (256, 256))
buffer = io.BytesIO()
img.save(buffer, format="PNG")
buffer.seek(0)
await cmd_marchtoy.send(await UniMessage().image(raw=buffer).export())
try:
img = await render.render(cmd, (256, 256))
buffer = io.BytesIO()
img.save(buffer, format="PNG")
buffer.seek(0)
await cmd_marchtoy.send(await UniMessage().image(raw=buffer).export())
except Exception as e:
await cmd_marchtoy.send(await Message(message=f"发生了错误: {e}"))

View File

@ -113,6 +113,55 @@ class Sphere(Object):
return f"sdSphere({self.transform.p_expr()}, {self.radius})"
@make_obj("cylinder", "cyl")
class Cylinder(Object):
def __init__(self, _radius: float = 1.0, _height: float = 1.0) -> None:
super().__init__()
self.radius = _radius
self.height = _height
def parse_args(self, args: list[str]):
param = ArgParser.as_vec2(args)
self.radius = param[0]
self.height = param[1]
def sdf_block(self) -> str:
return f"sdCappedCylinder({self.transform.p_expr()}, {self.radius}, {self.height})"
@make_obj("torus")
class Torus(Object):
def __init__(self, _r1: float = 0.5, _r2: float = 1.0) -> None:
super().__init__()
self.r1 = _r1
self.r2 = _r2
def parse_args(self, args: list[str]):
param = ArgParser.as_vec2(args)
self.r1 = param[0]
self.r2 = param[1]
def sdf_block(self) -> str:
return f"sdTorus({self.transform.p_expr()}, vec2({self.r1}, {self.r2}))"
@make_obj("capsule", "pill")
class Capsule(Object):
def __init__(self, _h: float = 1.0, _r: float = 0.25) -> None:
super().__init__()
self._h = _h
self._r = _r
def parse_args(self, args: list[str]):
param = ArgParser.as_vec2(args)
self._h = param[0]
self._r = param[1]
def sdf_block(self) -> str:
return f"sdVerticalCapsule({self.transform.p_expr()}, {self._h}, {self._r})"
@make_obj("camera", "cam")
class Camera(Object):
def __init__(self, _focus: float = 1.0) -> None:

View File

@ -25,6 +25,23 @@ float sdSphere(vec3 p, float r) {
return length(p) - r;
}
float sdCappedCylinder( vec3 p, float r, float h )
{
vec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
float sdVerticalCapsule( vec3 p, float h, float r )
{
p.y -= clamp( p.y, 0.0, h );
return length( p ) - r;
}
float sdTorus( vec3 p, vec2 t )
{
vec2 q = vec2(length(p.xz)-t.x,p.y);
return length(q)-t.y;
}
sdQuery sd(vec3 p) {
sdQuery qry;
qry.value = 100000000.0;

View File

@ -36,6 +36,22 @@ class ArgParser:
raise Exception(f"cannot parse {args}")
return default
@staticmethod
def as_vec2(
args: list[str], default: np.ndarray = np.array((0.0, 0.0))
) -> np.ndarray:
try:
if len(args) == 1:
x = float(args[0])
return np.array((x, x))
elif len(args) == 2:
x = float(args[0])
y = float(args[1])
return np.array((x, y))
except:
raise Exception(f"cannot parse {args}")
return default
@staticmethod
def as_vec3(
args: list[str], default: np.ndarray = np.array((0.0, 0.0, 0.0))