this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Increment other degrees as well.

+11 -22
+11 -22
avatar_cube.py
··· 11 11 ZOOM = 100.0 12 12 CIRCLE_R = 17 13 13 LINE_W = 6 14 - PITCH_DEG = 20 15 - YAW_DEG = 45 16 - 17 - # ─────────────────────────── math helpers ──────────────────────────────── 18 14 19 15 def rot_xyz(roll: float, pitch: float, yaw: float) -> np.ndarray: 20 16 """Build 3×3 rotation matrix for intrinsic X‑(roll), Y‑(pitch), Z‑(yaw).""" ··· 40 36 CUBE_RADIUS_PX = math.sqrt(3) * (ZOOM / 2) 41 37 HALF_FRAME = CUBE_RADIUS_PX + CIRCLE_R + 5 42 38 43 - # ─────────────────────────── rendering core ────────────────────────────── 44 - 45 - def render_frame(roll_deg: float) -> bytes: 39 + def render_frame(roll_deg: float, pitch_deg: float, yaw_deg: float) -> bytes: 46 40 """Return PNG bytes of cube at given pitch (deg).""" 47 41 # Matplotlib figure — square, no border 48 42 fig = plt.figure(figsize=(2, 2), dpi=256, facecolor="white") ··· 51 45 ax.axis('off') 52 46 53 47 # rotate & project 54 - R = rot_xyz(math.radians(roll_deg), math.radians(PITCH_DEG), math.radians(YAW_DEG)) 48 + R = rot_xyz(math.radians(roll_deg), math.radians(pitch_deg), math.radians(yaw_deg)) 55 49 verts2d = project_ortho(V @ R.T) 56 50 57 51 # draw circles ··· 74 68 plt.close(fig) 75 69 return buf.getvalue() 76 70 77 - # ─────────────────────────── avatar update logic ───────────────────────── 78 - 79 - def compute_deg(now_utc: dt.datetime | None = None) -> int: 80 - now = now_utc or dt.datetime.now(dt.timezone.utc) 81 - elapsed_min = int((now - START_DATETIME).total_seconds() // 60) 82 - steps = elapsed_min // 15 # integer 15‑min buckets 83 - deg = (steps * 7) % 360 # wrap at 360 84 - return deg 85 - 86 - 87 71 def update_bluesky_avatar(now_utc: dt.datetime | None = None, dry_run=False): 88 72 handle = os.getenv('BLUESKY_HANDLE') 89 73 app_pw = os.getenv('BLUESKY_APP_PASSWORD') 90 74 if not handle or not app_pw: 91 75 raise RuntimeError('BLUESKY_HANDLE and BLUESKY_APP_PASSWORD must be set') 92 76 93 - roll = compute_deg(now_utc) 94 - png = render_frame(roll) 77 + now = now_utc or dt.datetime.now(dt.timezone.utc) 78 + elapsed_min = int((now - START_DATETIME).total_seconds() // 60) 79 + steps = elapsed_min // 15 # integer 15‑min buckets 80 + deg_roll = (steps * 7) % 360 # wrap at 360 81 + deg_pitch = (steps * 3) % 360 82 + deg_yaw = (steps * 5) % 360 83 + png = render_frame(deg_roll, deg_pitch, deg_yaw) 95 84 96 85 if dry_run: 97 - with open(f'cube-{roll}.png', 'wb') as f: 86 + with open(f'cube-{steps}.png', 'wb') as f: 98 87 f.write(png) 99 88 return 100 89 ··· 140 129 141 130 def sweep_through_images(): 142 131 INCREMENT = dt.timedelta(minutes=15) 143 - timestamps = [START_DATETIME + i * INCREMENT for i in range(13)] 132 + timestamps = [START_DATETIME + i * INCREMENT for i in range(104)] 144 133 for ts in timestamps: 145 134 update_bluesky_avatar(now_utc=ts, dry_run=True) 146 135