git.haldean.org
more solids stuff, better float division Will Haldean Brown 6 years ago
4 changed file(s) with 66 addition(s) and 13 deletion(s).
 2 2 from symrep.solids import * 3 3 4 4 n = union( 5 sphere(const(1)), 5 difference( 6 intersection( 7 translate( 8 sphere(const(1.0)), 9 vec(-1, 0., 0.), 10 ), 11 translate( 12 box(size(2., 2., 1.75)), 13 vec(-1., 0., 0.25), 14 ), 15 ), 16 translate( 17 cylinder( 18 const(0.35), 19 const(2.0), 20 ), 21 vec(-1., 0., 0.), 22 ), 23 ), 6 24 intersection( 7 sphere(const(3)), 25 sphere(const(3.)), 8 26 translate( 9 sphere(const(2)), 27 sphere(const(2.)), 10 28 vec(3., 0., 0.), 11 29 ), 12 30 ), 13 31 translate( 14 32 difference( 15 sphere(const(2)), 33 sphere(const(2.)), 16 34 sphere(const(1.5)), 17 35 translate( 18 sphere(const(2)), 36 sphere(const(2.)), 19 37 vec(1., 0., 0.), 20 38 ), 21 39 ), 27 45 to_dot(n, f) 28 46 29 47 points = sample_solid( 30 n, (-2, -2, -2), (5, 5, 2), 20000, is_inside) 31 with open("test.xyz", "w") as f: 48 n, (-2, -2, -2), (5, 5, 2), is_on_surface(0.05), max_sec=30) 49 with open("sphere.xyz", "w") as f: 32 50 solids.write_point_cloud(points, f)
 0 from __future__ import division 1 0 2 import array 1 3 import datetime 2 4 import math
 0 from __future__ import division 1 0 2 import functools 1 3 import numpy as np 2 4 import operator
 0 from __future__ import division 1 0 2 import numpy as np 1 3 import random 2 4 import symrep.base 5 import time 3 6 4 7 5 8 def vec(*v): 15 18 fill[:3] = p 16 19 p = fill 17 20 return symrep.base.const(p) 21 22 def size(*s): 23 return symrep.base.const(np.array(s)) 18 24 19 25 def transform(n, T, name=None, nodetype="transform"): 20 26 return symrep.base.Node( 44 50 name, "sphere", 45 51 lambda t: np.linalg.norm(t[:3]) - radius(t), {radius: "radius"}) 46 52 47 def sample_solid(root, lo, hi, num_points, eval_pt): 53 def cylinder(radius, height, name=None): 54 def eval_t(t): 55 circle_dist = np.linalg.norm(t[:2]) 56 axial_dist = abs(t[2]) 57 return max(circle_dist - radius(t), axial_dist - height(t) / 2.) 58 return symrep.base.Node( 59 name, "cylinder", eval_t, {radius: "radius", height: "height"}) 60 61 def box(size, name=None): 62 return symrep.base.Node( 63 name, "box", lambda t: max(abs(t[:3]) - size(t) / 2.), 64 {size: "size"}) 65 66 def sample_solid(root, lo, hi, eval_pt, max_points=None, max_sec=None): 67 if max_points is None and max_sec is None: 68 raise ValueError( 69 "either a deadline or a number of points must be given") 70 48 71 found = 0 49 72 tried = 0 50 73 t = np.ones(4) 51 while found < num_points: 74 start = time.time() 75 while max_points is None or found < max_points: 52 76 t[0] = random.uniform(lo[0], hi[0]) 53 77 t[1] = random.uniform(lo[1], hi[1]) 54 78 t[2] = random.uniform(lo[2], hi[2]) 56 80 yield t 57 81 found += 1 58 82 tried += 1 59 print("tried {} points to find {}".format(tried, num_points)) 83 if tried % 1000 == 0: 84 elapsed = time.time() - start 85 if elapsed > max_sec: 86 break 87 print("tried {} points to find {}".format(tried, found)) 88 print("estimated scene density: {}".format(found / tried)) 60 89 61 90 def is_inside(root, t): 62 91 return root(t) <= 0 63 92 64 def is_on_surface(root, t, accuracy): 65 val = root(t) 66 return val <= 0 and abs(val) <= accuracy 93 def is_on_surface(accuracy): 94 def eval_t(root, t): 95 val = root(t) 96 return val <= 0 and abs(val) <= accuracy 97 return eval_t 67 98 68 99 def write_point_cloud(points, f): 69 100 for point in points: