mirror of
https://github.com/HackerPoet/PySpace
synced 2025-08-24 22:02:33 +02:00
270 lines
6 KiB
Python
270 lines
6 KiB
Python
import math
|
|
import numpy as np
|
|
from .util import *
|
|
|
|
class Sphere:
|
|
def __init__(self, r=1.0, c=(0,0,0), color=(1,1,1)):
|
|
self.r = set_global_float(r)
|
|
self.c = set_global_vec3(c)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
c = get_global(self.c)
|
|
r = get_global(self.r)
|
|
return (np.linalg.norm(p[:3] - c) - r) / p[3]
|
|
|
|
def NP(self, p):
|
|
c = get_global(self.c)
|
|
r = get_global(self.r)
|
|
return normalize(p[:3] - c) * r + c
|
|
|
|
def glsl(self):
|
|
return 'de_sphere(p' + cond_offset(self.c) + ', ' + float_str(self.r) + ')'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class Box:
|
|
def __init__(self, s=(1,1,1), c=(0,0,0), color=(1,1,1)):
|
|
self.s = set_global_vec3(s)
|
|
self.c = set_global_vec3(c)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
c = get_global(self.c)
|
|
s = get_global(self.s)
|
|
a = np.abs(p[:3] - c) - s;
|
|
return (min(max(a[0], a[1], a[2]), 0.0) + np.linalg.norm(np.maximum(a,0.0))) / p[3]
|
|
|
|
def NP(self, p):
|
|
c = get_global(self.c)
|
|
s = get_global(self.s)
|
|
return np.clip(p[:3] - c, -s, s) + c
|
|
|
|
def glsl(self):
|
|
return 'de_box(p' + cond_offset(self.c) + ', ' + vec3_str(self.s) + ')'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class Tetrahedron:
|
|
def __init__(self, r=1.0, c=(0,0,0), color=(1,1,1)):
|
|
self.r = set_global_float(r)
|
|
self.c = set_global_vec3(c)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
c = get_global(self.c)
|
|
r = get_global(self.r)
|
|
a = p[:3] - c
|
|
md = max(-a[0] - a[1] - a[2], a[0] + a[1] - a[2], -a[0] + a[1] + a[2], a[0] - a[1] + a[2])
|
|
return (md - r) / (p[3] * math.sqrt(3.0));
|
|
|
|
def NP(self, p):
|
|
raise Exception("Not implemented")
|
|
|
|
def glsl(self):
|
|
return 'de_tetrahedron(p' + cond_offset(self.c) + ', ' + float_str(self.r) + ')'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class InfCross:
|
|
def __init__(self, r=1.0, c=(0,0,0), color=(1,1,1)):
|
|
self.r = set_global_float(r)
|
|
self.c = set_global_vec3(c)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
r = get_global(self.r)
|
|
c = get_global(self.c)
|
|
sq = (p[:3] - c) * (p[:3] - c)
|
|
return (math.sqrt(min(min(sq[0] + sq[1], sq[0] + sq[2]), sq[1] + sq[2])) - r) / p[3]
|
|
|
|
def NP(self, p):
|
|
r = get_global(self.r)
|
|
c = get_global(self.c)
|
|
n = p[:3] - c
|
|
m_ix = np.argmax(np.abs(n))
|
|
n[m_ix] = 0.0
|
|
n = normalize(n) * r
|
|
n[m_ix] = p[m_ix] - c[m_ix]
|
|
return n + c
|
|
|
|
def glsl(self):
|
|
return 'de_inf_cross(p' + cond_offset(self.c) + ', ' + float_str(self.r) + ')'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class InfCrossXY:
|
|
def __init__(self, r=1.0, c=(0,0,0), color=(1,1,1)):
|
|
self.r = set_global_float(r)
|
|
self.c = set_global_vec3(c)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
r = get_global(self.r)
|
|
c = get_global(self.c)
|
|
sq = (p[:3] - c) * (p[:3] - c)
|
|
return (math.sqrt(min(sq[0], sq[1]) + sq[2]) - r) / p[3]
|
|
|
|
def NP(self, p):
|
|
r = get_global(self.r)
|
|
c = get_global(self.c)
|
|
n = p[:3] - c
|
|
m_ix = (0 if abs(n[0]) > abs(n[1]) else 1)
|
|
n[m_ix] = 0.0
|
|
n = normalize(n) * r
|
|
n[m_ix] = p[m_ix] - c[m_ix]
|
|
return n + c
|
|
|
|
def glsl(self):
|
|
return 'de_inf_cross_xy(p' + cond_offset(self.c) + ', ' + float_str(self.r) + ')'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class InfLine:
|
|
def __init__(self, r=1.0, n=(1,0,0), c=(0,0,0), color=(1,1,1)):
|
|
self.r = set_global_float(r)
|
|
self.n = set_global_vec3(n)
|
|
self.c = set_global_vec3(c)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
r = get_global(self.r)
|
|
n = get_global(self.n)
|
|
c = get_global(self.c)
|
|
q = p[:3] - c
|
|
return (np.linalg.norm(q - n*np.dot(n,q)) - r) / p[3]
|
|
|
|
def NP(self, p):
|
|
r = get_global(self.r)
|
|
c = get_global(self.c)
|
|
n = p[:3] - c
|
|
m_ix = (0 if abs(n[0]) > abs(n[1]) else 1)
|
|
n[m_ix] = 0.0
|
|
n = normalize(n) * r
|
|
n[m_ix] = p[m_ix] - c[m_ix]
|
|
return n + c
|
|
|
|
def glsl(self):
|
|
return 'de_inf_line(p' + cond_offset(self.c) + ', ' + vec3_str(self.n) + ', ' + float_str(self.r) + ')'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class XPlane:
|
|
def __init__(self, x=0.0, color=(1,1,1)):
|
|
self.x = set_global_float(x)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
x = get_global(self.x)
|
|
return abs(p[0] - x) / p[3]
|
|
|
|
def NP(self, p):
|
|
x = get_global(self.x)
|
|
return np.array([x, p[1], p[2]])
|
|
|
|
def glsl(self):
|
|
return 'abs(p.x' + cond_subtract(self.x) + ') / p.w'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class YPlane:
|
|
def __init__(self, x=0.0, color=(1,1,1)):
|
|
self.x = set_global_float(x)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
x = get_global(self.x)
|
|
return abs(p[1] - x) / p[3]
|
|
|
|
def NP(self, p):
|
|
x = get_global(self.x)
|
|
return np.array([p[0], x, p[2]])
|
|
|
|
def glsl(self):
|
|
return 'abs(p.y' + cond_subtract(self.x) + ') / p.w'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class ZPlane:
|
|
def __init__(self, x=0.0, color=(1,1,1)):
|
|
self.x = set_global_float(x)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
x = get_global(self.x)
|
|
return abs(p[2] - x) / p[3]
|
|
|
|
def NP(self, p):
|
|
x = get_global(self.x)
|
|
return np.array([p[0], p[1], x])
|
|
|
|
def glsl(self):
|
|
return 'abs(p.z' + cond_subtract(self.x) + ') / p.w'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class XHalfSpace:
|
|
def __init__(self, x=0.0, color=(1,1,1)):
|
|
self.x = set_global_float(x)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
x = get_global(self.x)
|
|
return (p[0] - x) / p[3]
|
|
|
|
def NP(self, p):
|
|
x = get_global(self.x)
|
|
return np.array([x, p[1], p[2]])
|
|
|
|
def glsl(self):
|
|
return '(p.x' + cond_subtract(self.x) + ') / p.w'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class YHalfSpace:
|
|
def __init__(self, x=0.0, color=(1,1,1)):
|
|
self.x = set_global_float(x)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
x = get_global(self.x)
|
|
return (p[1] - x) / p[3]
|
|
|
|
def NP(self, p):
|
|
x = get_global(self.x)
|
|
return np.array([p[0], x, p[2]])
|
|
|
|
def glsl(self):
|
|
return '(p.y' + cond_subtract(self.x) + ') / p.w'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|
|
|
|
class ZHalfSpace:
|
|
def __init__(self, x=0.0, color=(1,1,1)):
|
|
self.x = set_global_float(x)
|
|
self.color = color
|
|
|
|
def DE(self, p):
|
|
x = get_global(self.x)
|
|
return (p[2] - x) / p[3]
|
|
|
|
def NP(self, p):
|
|
x = get_global(self.x)
|
|
return np.array([p[0], p[1], x])
|
|
|
|
def glsl(self):
|
|
return '(p.z' + cond_subtract(self.x) + ') / p.w'
|
|
|
|
def glsl_col(self):
|
|
return make_color(self)
|