git.haldean.org
add basic geometry f-rep for spheres Will Haldean Brown 6 years ago
6 changed file(s) with 99 addition(s) and 5 deletion(s).
 2 2 /*.dot 3 3 /*.png 4 4 /*.wav 5 /*.xyz
 0 import numpy as np 1 from symrep import * 2 3 n = solids.union( 4 solids.sphere(const(1)), 5 solids.intersection( 6 solids.sphere(const(3)), 7 solids.translate( 8 solids.sphere(const(2)), 9 const(np.array((3., 0., 0.))), 10 ), 11 ), 12 ) 13 14 with open("test.xyz", "w") as f: 15 solids.write_pointcloud( 16 n, (-1, -2, -2), (5, 2, 2), 100000, f)
 0 from base import * 0 from .base import * 1 1 from . import audio 2 from . import solids
 0 import functools 0 1 import operator 1 2 2 3 5 6 6 7 def sum(*nodes): 7 8 return Node( 8 None, "sum", lambda t: reduce(operator.add, (n(t) for n in nodes), 0), 9 None, "sum", 10 lambda t: functools.reduce(operator.add, (n(t) for n in nodes), 0), 9 11 {n: "value" for n in nodes}) 10 12 11 13 def product(*nodes): 12 14 return Node( 13 15 None, "product", 14 lambda t: reduce(operator.mul, (n(t) for n in nodes), 1), 16 lambda t: functools.reduce(operator.mul, (n(t) for n in nodes), 1), 15 17 {n: "value" for n in nodes}) 16 18 17 19 def piecewise(pre, post, split, name=None): 47 49 48 50 def collect_nodes(root): 49 51 return set([root]).union( 50 reduce(set.union, map(collect_nodes, root.deps.keys()), set())) 52 functools.reduce( 53 set.union, map(collect_nodes, root.deps.keys()), set())) 51 54 52 55 def collect_edges(root): 53 56 edges = [(root.id, dep.id, dep_type) 54 for dep, dep_type in root.deps.iteritems()] 57 for dep, dep_type in root.deps.items()] 55 58 for dep in root.deps.keys(): 56 59 edges.extend(collect_edges(dep)) 57 60 return edges
 0 import numpy as np 1 import random 2 import symrep.base 3 4 5 def transform(n, T, name=None, nodetype="transform"): 6 return symrep.base.Node( 7 name, nodetype, lambda t: n(T(t).dot(t)), {n: "value", T: "transform"}) 8 9 def translate(n, trans, name=None): 10 def getT(t): 11 T = np.eye(4) 12 T[:3, 3] = -trans(t) 13 return T 14 return transform(n, getT, name=name, nodetype="translate") 15 16 def sphere(radius, name=None): 17 return symrep.base.Node( 18 name, "sphere", 19 lambda t: np.linalg.norm(t[:3]) - radius(t), {radius: "radius"}) 20 21 def union(*nodes): 22 return symrep.base.Node( 23 None, "union", lambda t: min(map(lambda n: n(t), nodes)), 24 {n: "value" for n in nodes}) 25 26 def intersection(*nodes): 27 return symrep.base.Node( 28 None, "intersection", lambda t: max(map(lambda n: n(t), nodes)), 29 {n: "value" for n in nodes}) 30 31 def to_pointcloud(root, hi, lo, num_points): 32 found = 0 33 tried = 0 34 t = np.ones(4) 35 while found < num_points: 36 t[0] = random.uniform(lo[0], hi[0]) 37 t[1] = random.uniform(lo[1], hi[1]) 38 t[2] = random.uniform(lo[2], hi[2]) 39 if root(t) < 0: 40 yield t 41 found += 1 42 tried += 1 43 print("tried {} points to find {}".format(tried, num_points)) 44 45 def write_pointcloud(root, hi, lo, num_points, f): 46 num_written = 0 47 for point in to_pointcloud(root, hi, lo, num_points): 48 f.write("{} {} {}\n".format(*(point[:3])))
 0 0 import symrep 1 1 import symrep.audio 2 2 import unittest 3 4 try: 5 import numpy as np 6 except ImportError: 7 import numpypy as np 3 8 4 9 5 10 class SymrepTest(unittest.TestCase): 82 87 with open("test.dot", "w") as f: 83 88 symrep.to_dot(n, f, name="test_dot") 84 89 90 def test_sphere(self): 91 n = symrep.solids.sphere(symrep.const(2)) 92 cloud = list(symrep.solids.to_pointcloud( 93 n, -2. * np.ones(3), 2 * np.ones(3), 500)) 94 self.assertEqual(len(cloud), 500) 95 for pt in cloud: 96 self.assertLessEqual(np.linalg.norm(pt[:3]), 2.) 97 98 def test_translate(self): 99 n = symrep.solids.translate( 100 symrep.solids.sphere(symrep.const(2)), 101 symrep.const(np.array((4., 0., 0.))), 102 ) 103 self.assertLessEqual(n((4., 0., 0., 1.)), 0) 104 self.assertLessEqual(n((4., 1.5, 0., 1.)), 0) 105 self.assertGreaterEqual(n((4., 2.5, 0., 1.)), 0) 106 self.assertGreaterEqual(n((0., 0., 0., 1.)), 0) 107 85 108 if __name__ == "__main__": 86 109 unittest.main()