Skip to content

Instantly share code, notes, and snippets.

@horstjens
Created October 14, 2024 09:49
Show Gist options
  • Save horstjens/eb594f03d7c4b579a597ffce25bc84af to your computer and use it in GitHub Desktop.
Save horstjens/eb594f03d7c4b579a597ffce25bc84af to your computer and use it in GitHub Desktop.
vpython label pixel_pos problem
import vpython as vp
import random
#import math
# description: a world with vertical cylinders (axis = vp.vec(0,0,1), base of all cylinders is at world position z=0
# the base of the cylinder has a location label (white text)
# the top of each cylinder has a value label (green text)
# problem: finding out pixel_pos of location labels (at the base of a cylinder) and the value labels( at the top of a cylinder)
# the pixel pos is not the world coordinates, but the coordinate in pixels
# (from the screen center or from the lower left corner)
# where an object (a label) appears on the screen.
class Sim:
demand = {}
width = 1200
height = 800
min_x = -10
max_x = 10
min_y = -10
max_y = 10
min_z = 0.1
max_z = 1.5
radius = 0.1
show_location_labels = True
show_value_labels = True
merge_labels = False
grid_color = vp.vec(0.7,0.7,0.7)
#factor = 0.87
class Column(vp.cylinder):
container = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
if "abbr" in kwargs:
self.abbr = kwargs["abbr"]
else:
raise ValueError("abbr missing in arguments")
Column.container.append(self)
self.original_pos = vp.vec(self.pos.x, self.pos.y, self.pos.z)
class ValueLabel(vp.label):
container = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
if "abbr" in kwargs:
self.abbr = kwargs["abbr"]
else:
raise ValueError("abbr missing in arguments")
ValueLabel.container.append(self)
self.original_pos = vp.vec(self.pos.x, self.pos.y, self.pos.z)
class LocationLabel(vp.label):
container = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
if "abbr" in kwargs:
self.abbr = kwargs["abbr"]
else:
raise ValueError("abbr missing in arguments")
LocationLabel.container.append(self)
self.original_pos = vp.vec(self.pos.x, self.pos.y, self.pos.z)
class GridLine(vp.curve):
container = []
def __init__(self,**kwargs):
super().__init__(**kwargs)
GridLine.container.append(self)
def widget_func_show_location_labels(b):
Sim.show_location_labels = b.checked
for l in LocationLabel.container:
l.visible = b.checked
def widget_func_show_value_labels(b):
Sim.show_value_labels = b.checked
for l in ValueLabel.container:
l.visible = b.checked
def widget_func_grid0(b):
# white lines at height 0
for line in GridLine.container:
if line.color == Sim.grid_color:
line.visible = b.checked
def widget_func_grid1(b):
# yellow lines at height 1
for line in GridLine.container:
if line.color == vp.color.yellow:
line.visible = b.checked
def widget_func_box(b):
for l in LocationLabel.container:
l.box = b.checked
def show_pixelpositions():
Sim.bigtext.text = ""
#for c in Column.container:
# base_pos = c.pos
# top_pos = c.pos + c.axis
# Sim.bigtext.text += f"{c.abbr}: base: {world_to_pixel(base_pos)} top: {world_to_pixel(top_pos)} _offset {c._offset}\n"
#Sim.bigtext.text +=f"vertexcount: {scene.vertexCount}\n"
Sim.bigtext.text +=f"pixel_to_world: {scene.pixel_to_world}\n"
Sim.bigtext.text +=f"world_to_pixel: {1/scene.pixel_to_world}\n"
Sim.bigtext.text +=f"scene.center: {scene.center}\n"
Sim.bigtext.text +=f"scene.range: {scene.range}\n"
Sim.bigtext.text +=f"scene.camera.pos: {scene.camera.pos}\n"
Sim.bigtext.text +=f"scene.fov: {scene.fov}\n"
Sim.bigtext.text +=f"d: {vp.mag(scene.center-scene.camera.pos)}"
# ---------------------------------------- main --------------------------------
scene = vp.canvas(width=Sim.width, height=Sim.height, background=vp.color.purple, align="left")
# make 3 arrows in the world center for orientation
vp.arrow(axis=vp.vec(1,0,0), color=vp.color.red)
vp.arrow(axis=vp.vec(0,1,0), color=vp.color.green)
vp.arrow(axis=vp.vec(0,0,1), color=vp.color.blue)
# 3d grid and bluebox
bluebox = vp.box(pos=vp.vec(0,0,-0.1), size=vp.vec(Sim.max_x*2, Sim.max_y*2, 0.049), color=vp.vec(0,0,0.5))
# white grid at height 0
for x in range(Sim.min_x, Sim.max_x+1):
GridLine(pos=[vp.vec(x,Sim.min_y,0), vp.vec(x, Sim.max_y, 0)], color=Sim.grid_color)
for y in range(Sim.min_y, Sim.max_y+1):
GridLine(pos=[vp.vec(Sim.min_x, y, 0), vp.vec(Sim.max_x, y, 0)], color=Sim.grid_color)
# yellow grid at height 1
for x in range(Sim.min_x, Sim.max_x+1):
GridLine(pos=[vp.vec(x,Sim.min_y,1), vp.vec(x, Sim.max_y, 1)], color=vp.color.yellow, visible=False)
for y in range(Sim.min_y, Sim.max_y+1):
GridLine(pos=[vp.vec(Sim.min_x, y, 1), vp.vec(Sim.max_x, y, 1)], color=vp.color.yellow, visible=False)
# generate nodes (yellow vertical cylinders that have a location label at the base and a value label at the top)
for n in range(1,6):
#x = random.uniform(Sim.min_x, Sim.max_x)
x = random.gauss(mu=0, sigma = 3)
#y = random.uniform(Sim.min_x, Sim.max_x)
y = random.gauss(mu=0, sigma = 3)
z = random.uniform(Sim.min_z, Sim.max_z)
abbr_text = f"node_{n:03}"
Sim.demand[abbr_text] = z
Column(pos=vp.vec(x,y,0), axis=vp.vec(0,0,z), color=vp.color.yellow, radius=Sim.radius, abbr=abbr_text,opacity=0.5)
LocationLabel(pos=vp.vec(x,y,0), abbr=abbr_text, text=abbr_text, align="left", yoffset=20, xoffset=20, box=False, opacity=0)
ValueLabel(pos=vp.vec(x,y,z), abbr=abbr_text, text=f"{z:.2f}", align="center",box=False, opacity=0,
color=vp.color.green, visible=True,xoffset= -20, yoffset=-20)
# green labels with pixel_pos (xy position on the screen)
for x in range(0,Sim.width+1,100):
vp.label(pixel_pos=True, pos=vp.vec(x, 10, 0), text=f"|{x}", color=vp.color.green, box=False, align="left")
for y in range(0, Sim.height+1,100):
vp.label(pixel_pos=True, pos=vp.vec(0, y, 0), text=f"-{y}", color=vp.color.green, box=False, align="left")
# green screen center label
vp.label(pixel_pos = True, pos=vp.vec(Sim.width/2,Sim.height/2,0), text="+", align="center", box=False, color=vp.color.green, opacity=0)
# ------------------ UI ------------------
scene.append_to_caption("\n toggle: ")
vp.checkbox(text="grid0", bind=widget_func_grid0, checked=True)
vp.checkbox(text="grid1", bind=widget_func_grid1, checked=False)
#vp.button(text="pixel", bind=widget_func_pixel)
vp.checkbox(text="location box", bind=widget_func_box, checked=False)
vp.checkbox(text="location labels", bind=widget_func_show_location_labels, checked=Sim.show_location_labels)
vp.checkbox(text="value labels", bind=widget_func_show_value_labels, checked=Sim.show_value_labels)
scene.append_to_caption("\n")
scene.append_to_caption("\n")
Sim.bigtext = vp.wtext(text="base, top", pos=scene.caption_anchor)
# camera restrictions
scene.userspin = False
while True:
vp.rate(60)
show_pixelpositions()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment