#! /usr/bin/python3 # Last edited on 2024-06-06 17:39:20 by stolfi from math import sin, cos, pi import sys prec = 4 # Decimal digits eps = 0.1**prec # Coordinate quantum. Ne = int(sys.argv[1]) # Total number of edges. assert (Ne % 3) == 0, "{Ne} ust be a multiple of 3" N = Ne//3 - 1 # Number points on circular arc. def reven(C): # Rounds {C} to even multiple of {eps}. return eps*2*int(C/eps/2) sys.stderr.write("N = %d\n" % N) R = 10000 # Radius of circular arc. h = R/20 # Prism thickness. ang_min = pi/6 # Min arg of circular arc (radians). ang_max = pi/2 - ang_min # Max arg of circular arc (radians). L = R*(sin(ang_max) - sin(ang_min)) # Height of circular arc. Yc = 2*eps + R*cos(ang_min) # Y of arc center. Zc = 2*eps + L + R*sin(ang_max) # Z of arc center. elen = reven(R*(ang_max - ang_min)/N) # Approx edge length. assert elen > 5*eps sys.stderr.write("elen = %.*f\n" % (prec, elen)) # The {(Y,Z)} coordinates of the vertices: # Vertices 1 to {N+1} are one base, {N+2} to {2*N+2} are the other base. v = [ None ] for f in range(2): X = reven(2*eps if f == 0 else h - 2*eps) v.append((X, 2*eps, 2*eps)) for k in range(N): ang = ang_min + (ang_max - ang_min)*k/(N-1) c = cos(ang); s = sin(ang) Y = reven(Yc - R*c) Z = reven(Zc - R*s) v.append((X, Y, Z)) Nv = len(v) - 1 assert Nv == 2*(N+1), "bug len(v), Nv" def P(st): sys.stdout.write(st) # Write the vertex coordinates: for f in range(2): for k in range(N+1): vkf = v[1 + k + f*(N+1)] P("v") for j in range(3): P(" %.*f" % (prec, vkf[j])) P("\n") P("\n") P("\n") # Write the base faces in CCW order from outside. # Note that OBJ indices start at 1: P("f ") P(" %d" % 1) for k in range(N): P(" %d" % (N+1-k)) P("\n") P("\n") P("f ") P(" %d" % (N+2)) for k in range(N): P(" %d" % (N+3+k)) P("\n") P("\n") # Write the square faces on the wall, in CCW order from outside: for k00 in range(N+1): k01 = ((k00 + 1) % (N+1)) k10 = k00 + N+1 k11 = k01 + N+1 P("f %d %d %d %d\n" % (k00+1, k01+1, k11+1, k10+1)) # Nesta ordem!