新增基于摄像机网格投影的黑白笔画原型
沿用彩色块的网格与可见性投影,便于评估透视适配的笔画。已通过几何单元测试及 250/500 像素光流探针。
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
"""Convex camera-cell stroke shapes and perspective-preserving clipping."""
|
||||
|
||||
import math
|
||||
import random
|
||||
|
||||
from patch_geometry import clip_halfspace, interpolate_uv
|
||||
|
||||
|
||||
def capsule_in_cell(i, j, nx, ny, seed, width_ratio=0.42, length_ratio=0.84):
|
||||
"""Return a round-ended stroke wholly inside one normalized camera cell."""
|
||||
if not 0 < width_ratio <= length_ratio < 1:
|
||||
raise ValueError("require 0 < width_ratio <= length_ratio < 1")
|
||||
rng = random.Random((seed * 1000003 + i * 9176 + j * 6113) & 0xFFFFFFFF)
|
||||
angle = rng.uniform(0, math.pi)
|
||||
radius = width_ratio / 2
|
||||
half_body = (length_ratio - width_ratio) / 2
|
||||
outline = []
|
||||
for centre, start in ((half_body, -math.pi / 2), (-half_body, math.pi / 2)):
|
||||
for step in range(9):
|
||||
theta = start + math.pi * step / 8
|
||||
x = centre + radius * math.cos(theta)
|
||||
y = radius * math.sin(theta)
|
||||
xr = x * math.cos(angle) - y * math.sin(angle)
|
||||
yr = x * math.sin(angle) + y * math.cos(angle)
|
||||
outline.append(((i + 0.5 + xr) / nx, (j + 0.5 + yr) / ny))
|
||||
return outline
|
||||
|
||||
|
||||
def clip_to_stroke(fragment, outline):
|
||||
"""Clip a projected triangle while retaining its perspective attributes."""
|
||||
points = fragment
|
||||
for a, b in zip(outline, outline[1:] + outline[:1]):
|
||||
dx, dy = b[0] - a[0], b[1] - a[1]
|
||||
points = clip_halfspace(
|
||||
points,
|
||||
lambda p, a=a, dx=dx, dy=dy: dx * (p[1] - a[1]) - dy * (p[0] - a[0]),
|
||||
)
|
||||
if len(points) < 3:
|
||||
return []
|
||||
return points
|
||||
|
||||
|
||||
def projected_stroke_uv(fragment, loop_uvs, outline):
|
||||
"""Resolve a clipped camera stroke through the same UV interpolation as patches."""
|
||||
return [interpolate_uv(point, loop_uvs)
|
||||
for point in clip_to_stroke(fragment, outline)]
|
||||
Reference in New Issue
Block a user