git.haldean.org symrep / 6e2ae0d
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). Raw diff Collapse all Expand all
22 /*.dot
33 /*.png
44 /*.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 *
11 from . import audio
2 from . import solids
0 import functools
01 import operator
12
23
56
67 def sum(*nodes):
78 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),
911 {n: "value" for n in nodes})
1012
1113 def product(*nodes):
1214 return Node(
1315 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),
1517 {n: "value" for n in nodes})
1618
1719 def piecewise(pre, post, split, name=None):
4749
4850 def collect_nodes(root):
4951 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()))
5154
5255 def collect_edges(root):
5356 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()]
5558 for dep in root.deps.keys():
5659 edges.extend(collect_edges(dep))
5760 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])))
00 import symrep
11 import symrep.audio
22 import unittest
3
4 try:
5 import numpy as np
6 except ImportError:
7 import numpypy as np
38
49
510 class SymrepTest(unittest.TestCase):
8287 with open("test.dot", "w") as f:
8388 symrep.to_dot(n, f, name="test_dot")
8489
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
85108 if __name__ == "__main__":
86109 unittest.main()