예제 #1
0
argp = argparse.ArgumentParser(description='''Navigate around a hypercube or a
mesh from a file. By default, a 3-dimensional cube will be displayed. To
display a hypercube, use --dimension to specify the dimensionality.
Alternatively, an arbitrary 3D mesh can be specified with --file, which should
specify the path to a wavefront obj file. When using a file, only the polygon
data will displayed. Lines and curves will be ignored.''')
argp.add_argument('-d','--dimension',default=3,type=int,metavar='N',help='the dimensionality of the hypercube and the navigable space.')
argp.add_argument('-f','--file',metavar='PATH',help='a wavefront obj file to load and display')
argp.add_argument('--debug',action='store_true',help="don't catch exceptions from errors")
args = argp.parse_args()

if args.debug:
    sys.excepthook = sys.__excepthook__

ntracer = NTracer(args.dimension)

if args.file:
    if ntracer.dimension != 3:
        sys.exit('a file can only be displayed with a dimensionality of 3')

    try:
        triangles = wavefront_obj.load_obj(args.file)
    except Exception as e:
        if args.debug:
            raise
        sys.exit('could not load file: ' + str(e))
        
    scene = ntracer.build_composite_scene(triangles)
else:
    scene = ntracer.BoxScene()
예제 #2
0
    def star_tesselation(self):
        t = getattr(self,'_star_tesselation',None)
        if t is None:
            co_nt = NTracer(self.dimension)
            lines = []
            planes = [Plane(co_nt,co_nt.Vector(islice(part.position,co_nt.dimension))) for part in self.parts]
            las = self.line_apothem_square()
            for pgroup in combinations(planes,co_nt.dimension-1):
                try:
                    line = plane_line_intersection(co_nt,pgroup)
                except ValueError:
                    pass
                else:
                    if line:
                        for lineb in lines:
                            if almost_equal(line.p0,lineb.p0) and almost_equal(line.v,lineb.v):
                                lineb.planes |= line.planes
                                break
                        else:
                            outer_dist = line.dist_square(co_nt.Vector()) - las
                            if outer_dist < 0.1:
                                line.outer = outer_dist > -0.1
                                lines.append(line)

            pmap = {}
            for line in lines:
                pmap[line] = {}

            graph = FuzzyGraph()
            maxr = self.circumradius_square() + 0.1
            for l1,l2 in combinations(lines,2):
                inter = line_intersection(co_nt,l1,l2)
                if inter and inter[0].square() < maxr:
                    n = graph.add(inter[0],l1.planes | l2.planes,l1.outer or l2.outer)
                    pmap[l1][n] = inter[1]
                    pmap[l2][n] = inter[2]

            for line,poss in list(pmap.items()):
                if len(poss) == 0: continue
                if len(poss) == 1:
                    graph.remove(poss[0])
                    continue
                
                poss = sorted(list(poss.items()),key=(lambda x: x[1]))
                
                if line.outer:
                    for i in range(len(poss)-1):
                        join(poss[i][0],poss[i+1][0])
                elif len(poss) == 2:
                    join(poss[0][0],poss[1][0])
                elif len(poss) > 3:
                    for i in range(2,len(poss)-2):
                        graph.remove(poss[i][0])

                    join(poss[0][0],poss[1][0])
                    join(poss[-1][0],poss[-2][0])
            
            t = []
            self._star_tesselation = t
            for n in islice(graph.nodes,0,len(graph.nodes)-co_nt.dimension):
                for cycle in n.find_cycles(co_nt.dimension):
                    t.append([nt.Vector(tuple(x.pos) + (0,) * (nt.dimension-co_nt.dimension)) for x in cycle] + [nt.Vector()])
                n.detach()

        return t
예제 #3
0
argp = argparse.ArgumentParser(description='''Navigate around a hypercube or a
mesh from a file. By default, a 3-dimensional cube will be displayed. To
display a hypercube, use --dimension to specify the dimensionality.
Alternatively, an arbitrary 3D mesh can be specified with --file, which should
specify the path to a wavefront obj file. When using a file, only the polygon
data will displayed. Lines and curves will be ignored.''')
argp.add_argument('-d','--dimension',default=3,type=int,metavar='N',help='the dimensionality of the hypercube and the navigable space.')
argp.add_argument('-f','--file',metavar='PATH',help='a wavefront obj file to load and display')
argp.add_argument('--debug',action='store_true',help="don't catch exceptions from errors")
args = argp.parse_args()

if args.debug:
    sys.excepthook = sys.__excepthook__

ntracer = NTracer(args.dimension)

if args.file:
    if ntracer.dimension != 3:
        sys.exit('a file can only be displayed with a dimensionality of 3')

    try:
        triangles = wavefront_obj.load_obj(args.file)
    except Exception as e:
        if args.debug:
            raise
        sys.exit('could not load file: ' + str(e))
        
    scene = ntracer.build_composite_scene(triangles)
else:
    scene = ntracer.BoxScene()
예제 #4
0
parser.add_argument('-t','--type',metavar='TYPE',default='h264',
    help='Specifies output type when --output is used. If TYPE is "png", the '+
        'output is a series of PNG images. For any other value, it is used '+
        'as the video codec for ffmpeg.')
parser.add_argument('-f','--frames',metavar='F',type=positive_int,default=160,help='when creating an animation or benchmarking, the number of frames to render')
parser.add_argument('-s','--screen',metavar='WIDTHxHEIGHT',type=screen_size,default=(800,600),help='screen size')
parser.add_argument('-a','--fov',metavar='FOV',type=fov_type,default=0.8,help='field of vision in degrees')
parser.add_argument('-d','--cam-dist',metavar='DIST',type=float,default=4,
    help='How far the view-port is from the center of the polytope. The '+
        'value is a multiple of the outer raidius of the polytope.')
parser.add_argument('--benchmark',action='store_true',help='measure the speed of rendering the scene')
args = parser.parse_args()


material = Material((1,0.5,0.5))
nt = NTracer(max(len(args.schlafli)+1,3))


def higher_dihedral_supplement(schlafli,ds):
    a = math.pi*schlafli.denominator/schlafli.numerator
    return 2*math.asin(math.sin(math.acos(1/(math.tan(ds/2)*math.tan(a))))*math.sin(a))

def almost_equal(a,b,threshold=0.1):
    return (a-b).absolute() < threshold

def radial_vector(angle):
    return nt.Vector.axis(0,math.sin(angle)) + nt.Vector.axis(1,math.cos(angle))


class Instance:
    def __init__(self,shape,position,orientation=nt.Matrix.identity()):
예제 #5
0
파일: polytope.py 프로젝트: Rouslan/NTracer
parser.add_argument("-a", "--fov", metavar="FOV", type=fov_type, default=0.8, help="field of vision in degrees")
parser.add_argument(
    "-d",
    "--cam-dist",
    metavar="DIST",
    type=float,
    default=4,
    help="How far the view-port is from the center of the polytope. The "
    + "value is a multiple of the outer raidius of the polytope.",
)
parser.add_argument("--benchmark", action="store_true", help="measure the speed of rendering the scene")
args = parser.parse_args()


material = Material((1, 0.5, 0.5))
nt = NTracer(max(len(args.schlafli) + 1, 3))


def higher_dihedral_supplement(schlafli, ds):
    a = math.pi * schlafli.denominator / schlafli.numerator
    return 2 * math.asin(math.sin(math.acos(1 / (math.tan(ds / 2) * math.tan(a)))) * math.sin(a))


def almost_equal(a, b, threshold=0.1):
    return (a - b).absolute() < threshold


def radial_vector(angle):
    return nt.Vector.axis(0, math.sin(angle)) + nt.Vector.axis(1, math.cos(angle))