forked from protonphoton/LJ
Planetarium first functions
This commit is contained in:
parent
e6366649a4
commit
4131126734
@ -1,17 +0,0 @@
|
|||||||
# coding=UTF-8
|
|
||||||
'''
|
|
||||||
Etat global (anciennement singleton de la classe GameState + autres VARIABLES nécessaires partout)"
|
|
||||||
'''
|
|
||||||
|
|
||||||
from globalVars import *
|
|
||||||
|
|
||||||
# Etat global général
|
|
||||||
app_path = ""
|
|
||||||
|
|
||||||
# anciennement GameState
|
|
||||||
fs = GAME_FS_GAMEOVER
|
|
||||||
plyr = None
|
|
||||||
score = None
|
|
||||||
bmprs = None
|
|
||||||
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
|||||||
# coding=UTF-8
|
|
||||||
'''
|
|
||||||
Created on 13 nov. 2014
|
|
||||||
|
|
||||||
@author: pclf
|
|
||||||
'''
|
|
||||||
import math
|
|
||||||
|
|
||||||
class Polar2D(object):
|
|
||||||
'''
|
|
||||||
classdocs
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, r, theta):
|
|
||||||
'''
|
|
||||||
Constructor
|
|
||||||
'''
|
|
||||||
self.r = r
|
|
||||||
self.theta = theta
|
|
||||||
|
|
||||||
def Rotate(self, theta):
|
|
||||||
return Polar2D(self.r, self.theta + theta)
|
|
||||||
|
|
||||||
def RotateSelf(self, theta):
|
|
||||||
self.theta += theta
|
|
||||||
|
|
||||||
def Zoom(self, r):
|
|
||||||
return Polar2D(self.r * r, self.theta)
|
|
||||||
|
|
||||||
def ZoomSelf(self, r):
|
|
||||||
self.r *= r
|
|
||||||
|
|
||||||
def RotateZoom(self, r, theta):
|
|
||||||
return Polar2D(self.r * r, self.theta + theta)
|
|
||||||
|
|
||||||
def RotateZoomSelf(self, r, theta):
|
|
||||||
self.r *= r
|
|
||||||
self.theta += theta
|
|
||||||
|
|
||||||
def ToXY(self):
|
|
||||||
theta_rd = math.radians(self.theta)
|
|
||||||
return Vector2D(self.r * math.sin(theta_rd), - self.r * math.cos(theta_rd))
|
|
||||||
|
|
||||||
class Vector2D(object):
|
|
||||||
|
|
||||||
def __init__(self, x, y):
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
return Vector2D(self.x + other.x, self.y + other.y)
|
|
||||||
|
|
||||||
def __sub__(self, other):
|
|
||||||
return Vector2D(self.x - other.x, self.y - other.y)
|
|
||||||
|
|
||||||
# __iadd__ et __isub__ si nécessaire
|
|
||||||
|
|
||||||
def __mul__(self, k):
|
|
||||||
return Vector2D(self.x * k, self.y * k)
|
|
||||||
|
|
||||||
def __div__(self, k):
|
|
||||||
return Vector2D(self.x / k, self.y / k)
|
|
||||||
|
|
||||||
def ScalarProduct(self, v):
|
|
||||||
return self.x*v.x + self.y*v.y
|
|
||||||
|
|
||||||
def Det(self, v):
|
|
||||||
return self.x*v.y - self.y*v.x
|
|
||||||
|
|
||||||
def MatrixProduct(self, vx, vy):
|
|
||||||
return Vector2D(self.ScalarProduct(vx),self.ScalarProduct(vy))
|
|
||||||
|
|
||||||
def ToTuple(self):
|
|
||||||
return (self.x,self.y)
|
|
||||||
|
|
28
clients/planetarium/Readme.txt
Normal file
28
clients/planetarium/Readme.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
Le projet planetarium laser style.
|
||||||
|
|
||||||
|
Il y a plusieurs idees liees entre elles. En etant tres conservateur disons 150 etoiles par laser, on peut avec 4 lasers affiché 600 etoiles :) zoomer dans une constellation, etc..
|
||||||
|
|
||||||
|
On veut, sans connexion internet (donc stocker les infos en local), choisir/afficher les etoiles dans une direction du ciel avec pour origine un lieu sur terre (Paris ?) a telle date/heure.
|
||||||
|
|
||||||
|
Les ressources trouvées pour l'instant qui machent le travail skyfield, jplephem (du meme auteur)
|
||||||
|
et le catalogue hipparcos :
|
||||||
|
https://rhodesmill.org/skyfield/stars.html
|
||||||
|
https://in-the-sky.org//staratlas.php?ra=15.358411414&dec=73.47660962&limitmag=2
|
||||||
|
http://www.physics.csbsju.edu/astro/SF/SF.06.html
|
||||||
|
|
||||||
|
En sortie on a besoin d'une liste de coordonnées, ca serait le luxe avec la couleur, la position 3D et la constellation le cas echeant. Pas besoin d'interface graphique on a deja.
|
||||||
|
|
||||||
|
N'importe quelle contribution sera grandement utile : recherche, code,... Evidement toutes les personnes qui participent sont creditées dans les auteurs.
|
||||||
|
|
||||||
|
Les etoiles ont des positions dans plusieurs reperes, quel est le nom de celui qui nous importe : un endroit sur terre a une date qui peut changer cf skyfield ? Quelle base de données utiliser ? Si c'est bien hipparcos, comment avoir la liste des x etoiles les plus brillantes, comment avoir une liste des constellations classique ? comment les dessiner ? Ursa minor a plein d'etoiles, la liste exhaustive est tres interessante aussi, tout ce qui vous interessera,...
|
||||||
|
|
||||||
|
La position 3D est interessante parce qu'on a deja l'algo pour faire de l'anaglyph, vert pour un oeil et rouge pour l'autre et les gens ont souvent une impression de proximité dans une constellation ce qui est tres faux et donc je me vois bien faire une rotation autour d'une constellation pour montrer les distances colossales en Z.
|
||||||
|
|
||||||
|
Pour l'instant en python, j'affiche la position des planetes (des points) dans le systeme solaire grace a jplephem tel jour a telle heure.
|
||||||
|
|
||||||
|
Il y a donc besoin de jplephem et d'une base pour cet exemple texte :
|
||||||
|
|
||||||
|
pip install jplephem
|
||||||
|
wget http://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de430.bsp
|
||||||
|
|
||||||
|
Je peux evidement donner tout le projet avec simulateur de laser si besoin.
|
316
clients/planetarium/lj3.py
Normal file
316
clients/planetarium/lj3.py
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
# coding=UTF-8
|
||||||
|
|
||||||
|
'''
|
||||||
|
LJ v0.8.1 in python3
|
||||||
|
Some LJ functions useful for python clients (was framy.py)
|
||||||
|
|
||||||
|
OSC functions commented, waiting working on OSC in python3
|
||||||
|
|
||||||
|
Config(redisIP, client number)
|
||||||
|
PolyLineOneColor
|
||||||
|
rPolyLineOneColor
|
||||||
|
|
||||||
|
Text(word, color, PL, xpos, ypos, resize, rotx, roty, rotz) : Display a word
|
||||||
|
Send(adress,message) : remote control. See commands.py
|
||||||
|
WebStatus(message) : display message on webui
|
||||||
|
DrawPL(point list number) : once you stacked all wanted elements, like 2 polylines, send them to lasers.
|
||||||
|
|
||||||
|
LICENCE : CC
|
||||||
|
Sam Neurohack
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
import math
|
||||||
|
import redis
|
||||||
|
#from OSC import OSCServer, OSCClient, OSCMessage
|
||||||
|
|
||||||
|
redisIP = '127.0.0.1'
|
||||||
|
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
|
||||||
|
|
||||||
|
ClientNumber = 0
|
||||||
|
|
||||||
|
point_list = []
|
||||||
|
pl = [[],[],[],[]]
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
LJIP = "127.0.0.1"
|
||||||
|
|
||||||
|
osclientlj = OSCClient()
|
||||||
|
oscmsg = OSCMessage()
|
||||||
|
osclientlj.connect((redisIP, 8002))
|
||||||
|
'''
|
||||||
|
|
||||||
|
'''
|
||||||
|
def Send(oscaddress,oscargs=''):
|
||||||
|
|
||||||
|
oscmsg = OSCMessage()
|
||||||
|
oscmsg.setAddress(oscaddress)
|
||||||
|
oscmsg.append(oscargs)
|
||||||
|
|
||||||
|
#print ("sending to bhorosc : ",oscmsg)
|
||||||
|
try:
|
||||||
|
osclientlj.sendto(oscmsg, (redisIP, 8002))
|
||||||
|
oscmsg.clearData()
|
||||||
|
except:
|
||||||
|
print ('Connection to LJ refused : died ?')
|
||||||
|
pass
|
||||||
|
#time.sleep(0.001
|
||||||
|
|
||||||
|
def WebStatus(message):
|
||||||
|
Send("/status",message)
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
ASCII_GRAPHICS = [
|
||||||
|
|
||||||
|
#implementé
|
||||||
|
|
||||||
|
[(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)], #0
|
||||||
|
[(-20,30), (0,-30), (-20,30)], #1
|
||||||
|
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #2
|
||||||
|
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #3
|
||||||
|
[(30,10), (-30,10), (0,-30), (0,30)], #4
|
||||||
|
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #5
|
||||||
|
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #6
|
||||||
|
[(-30,-30), (30,-30), (-30,30)], #7
|
||||||
|
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #8
|
||||||
|
[(30,0), (-30,0), (-30,-10), (0,-30), (30,-30), (30,10), (0,30), (-30,30)], #9
|
||||||
|
|
||||||
|
# A implementer
|
||||||
|
[(-30,10), (30,-10), (30,10), (0,30), (-30,10), (-30,-10), (0,-30), (30,-10)], #:
|
||||||
|
[(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #;
|
||||||
|
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #<
|
||||||
|
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #=
|
||||||
|
[(30,10), (-30,10), (0,-30), (0,30)], #>
|
||||||
|
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #?
|
||||||
|
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #@
|
||||||
|
|
||||||
|
# Implementé
|
||||||
|
|
||||||
|
|
||||||
|
[(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A
|
||||||
|
[(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A
|
||||||
|
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #B
|
||||||
|
[(30,30), (-30,30), (-30,-30), (30,-30)], #C
|
||||||
|
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30)], #D
|
||||||
|
[(30,30), (-30,30), (-30,-0), (30,0), (-30,0), (-30,-30), (30,-30)], #E
|
||||||
|
[(-30,30), (-30,-0), (30,0), (-30,0), (-30,-30), (30,-30)], #F
|
||||||
|
[(0,0), (30,0), (30,30), (-30,30), (-30,-30),(30,-30)], #G
|
||||||
|
[(-30,-30), (-30,30), (-30,0), (30,0), (30,30), (30,-30)], #H
|
||||||
|
[(0,30), (0,-30)], #I
|
||||||
|
[(-30,30), (0,-30), (0,-30), (-30,-30), (30,-30)], #J
|
||||||
|
[(-30,-30), (-30,30), (-30,0), (30,-30), (-30,0), (30,30)], #K
|
||||||
|
[(30,30), (-30,30), (-30,-30)], #L
|
||||||
|
[(-30,30), (-30,-30), (0,0), (30,-30), (30,30)], #M
|
||||||
|
[(-30,30), (-30,-30), (30,30), (30,-30)], #N
|
||||||
|
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30)], #O
|
||||||
|
[(-30,0), (30,0), (30,-30), (-30,-30), (-30,30)], #P
|
||||||
|
[(30,30), (30,-30), (-30,-30), (-30,30), (30,30),(35,35)], #Q
|
||||||
|
[(-30,30), (-30,-30), (30,-30), (30,0), (-30,0), (30,30)], #R
|
||||||
|
[(30,-30), (-30,-30), (-30,0), (30,0), (30,30), (-30,30)], #S
|
||||||
|
[(0,30), (0,-30), (-30,-30), (30,-30)], #T
|
||||||
|
[(-30,-30), (-30,30), (30,30), (30,-30)], #U
|
||||||
|
[(-30,-30), (0,30), (30,-30)], #V
|
||||||
|
[(-30,-30), (-30,30), (0,0), (30,30), (30,-30)], #W
|
||||||
|
[(-30,30), (30,-30)], [(-30,-30), (30,30)], #X
|
||||||
|
[(0,30), (0,0), (30,-30), (0,0), (-30,-30)], #Y
|
||||||
|
[(30,30), (-30,30), (30,-30), (-30,-30)], #Z
|
||||||
|
|
||||||
|
# A implementer
|
||||||
|
|
||||||
|
[(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #[
|
||||||
|
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #\
|
||||||
|
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #]
|
||||||
|
[(30,10), (-30,10), (0,-30), (0,30)], #^
|
||||||
|
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #_
|
||||||
|
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #`
|
||||||
|
|
||||||
|
# Implementé
|
||||||
|
|
||||||
|
[(-20,20), (-20,-20), (20,-20), (20,20), (20,0), (-20,0)], #a
|
||||||
|
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20), (-20,0), (20,0)], #b
|
||||||
|
[(20,20), (-20,20), (-20,-20), (20,-20)], #c
|
||||||
|
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20)], #d
|
||||||
|
[(20,20), (-20,20), (-20,-0), (20,0), (-20,0), (-20,-20), (20,-20)], #e
|
||||||
|
[(-20,20), (-20,-0), (20,0), (-20,0), (-20,-20), (20,-20)], #f
|
||||||
|
[(0,0), (20,0), (20,20), (-20,20), (-20,-20),(20,-20)], #g
|
||||||
|
[(-20,-20), (-20,20), (-20,0), (20,0), (20,20), (20,-20)], #H
|
||||||
|
[(0,20), (0,-20)], #I
|
||||||
|
[(-20,20), (0,-20), (0,-20), (-20,-20), (20,-20)], #J
|
||||||
|
[(-20,-20), (-20,20), (-20,0), (20,-20), (-20,0), (20,20)], #K
|
||||||
|
[(20,20), (-20,20), (-20,-20)], #L
|
||||||
|
[(-20,20), (-20,-20), (0,0), (20,-20), (20,20)], #M
|
||||||
|
[(-20,20), (-20,-20), (20,20), (20,-20)], #N
|
||||||
|
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20)], #O
|
||||||
|
[(-20,0), (20,0), (20,-20), (-20,-20), (-20,20)], #P
|
||||||
|
[(20,20), (20,-20), (-20,-20), (-20,20), (20,20),(25,25)], #Q
|
||||||
|
[(-20,20), (-20,-20), (20,-20), (20,0), (-20,0), (20,20)], #R
|
||||||
|
[(20,-20), (-20,-20), (-20,0), (20,0), (20,20), (-20,20)], #S
|
||||||
|
[(0,20), (0,-20), (-20,-20), (20,-20)], #T
|
||||||
|
[(-20,-20), (-20,20), (20,20), (20,-20)], #U
|
||||||
|
[(-20,-20), (0,20), (20,-20)], #V
|
||||||
|
[(-20,-20), (-20,20), (0,0), (20,20), (20,-20)], #W
|
||||||
|
[(-20,20), (20,-20)], [(-20,-20), (20,20)], #X
|
||||||
|
[(0,20), (0,0), (20,-20), (0,0), (-20,-20)], #Y
|
||||||
|
[(20,20), (-20,20), (20,-20), (-20,-20)], #Z
|
||||||
|
|
||||||
|
[(-2,15), (2,15)] # Point a la place de {
|
||||||
|
]
|
||||||
|
|
||||||
|
def Config(redisIP,client):
|
||||||
|
global ClientNumber
|
||||||
|
|
||||||
|
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
|
||||||
|
ClientNumber = client
|
||||||
|
|
||||||
|
|
||||||
|
def LineTo(xy, c, PL):
|
||||||
|
|
||||||
|
pl[PL].append((xy + (c,)))
|
||||||
|
|
||||||
|
def Line(xy1, xy2, c, PL):
|
||||||
|
LineTo(xy1, 0, PL)
|
||||||
|
LineTo(xy2, c , PL)
|
||||||
|
|
||||||
|
|
||||||
|
def PolyLineOneColor(xy_list, c, PL , closed ):
|
||||||
|
#print "--"
|
||||||
|
#print "c",c
|
||||||
|
#print "xy_list",xy_list
|
||||||
|
#print "--"
|
||||||
|
xy0 = None
|
||||||
|
for xy in xy_list:
|
||||||
|
if xy0 is None:
|
||||||
|
xy0 = xy
|
||||||
|
#print "xy0:",xy0
|
||||||
|
LineTo(xy0,0, PL)
|
||||||
|
LineTo(xy0,c, PL)
|
||||||
|
else:
|
||||||
|
#print "xy:",xy
|
||||||
|
LineTo(xy,c, PL)
|
||||||
|
if closed:
|
||||||
|
LineTo(xy0,c, PL)
|
||||||
|
|
||||||
|
|
||||||
|
# Computing points coordinates for rPolyline function from 3D and around 0,0 to pygame coordinates
|
||||||
|
def Pointransf(xy, xpos = 0, ypos =0, resize =1, rotx =0, roty =0 , rotz=0):
|
||||||
|
|
||||||
|
x = xy[0] * resize
|
||||||
|
y = xy[1] * resize
|
||||||
|
z = 0
|
||||||
|
|
||||||
|
rad = rotx * math.pi / 180
|
||||||
|
cosaX = math.cos(rad)
|
||||||
|
sinaX = math.sin(rad)
|
||||||
|
|
||||||
|
y2 = y
|
||||||
|
y = y2 * cosaX - z * sinaX
|
||||||
|
z = y2 * sinaX + z * cosaX
|
||||||
|
|
||||||
|
rad = roty * math.pi / 180
|
||||||
|
cosaY = math.cos(rad)
|
||||||
|
sinaY = math.sin(rad)
|
||||||
|
|
||||||
|
z2 = z
|
||||||
|
z = z2 * cosaY - x * sinaY
|
||||||
|
x = z2 * sinaY + x * cosaY
|
||||||
|
|
||||||
|
rad = rotz * math.pi / 180
|
||||||
|
cosZ = math.cos(rad)
|
||||||
|
sinZ = math.sin(rad)
|
||||||
|
|
||||||
|
x2 = x
|
||||||
|
x = x2 * cosZ - y * sinZ
|
||||||
|
y = x2 * sinZ + y * cosZ
|
||||||
|
|
||||||
|
#print xy, (x + xpos,y+ ypos)
|
||||||
|
return (x + xpos,y+ ypos)
|
||||||
|
'''
|
||||||
|
to understand why it get negative Y
|
||||||
|
|
||||||
|
# 3D to 2D projection
|
||||||
|
factor = 4 * gstt.cc[22] / ((gstt.cc[21] * 8) + z)
|
||||||
|
print xy, (x * factor + xpos, - y * factor + ypos )
|
||||||
|
return (x * factor + xpos, - y * factor + ypos )
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Send 2D point list around 0,0 with 3D rotation resizing and reposition around xpos ypos
|
||||||
|
#def rPolyLineOneColor(self, xy_list, c, PL , closed, xpos = 0, ypos =0, resize =1, rotx =0, roty =0 , rotz=0):
|
||||||
|
def rPolyLineOneColor(xy_list, c, PL , closed, xpos = 0, ypos =0, resize =0.7, rotx =0, roty =0 , rotz=0):
|
||||||
|
xy0 = None
|
||||||
|
for xy in xy_list:
|
||||||
|
if xy0 is None:
|
||||||
|
xy0 = xy
|
||||||
|
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),0, PL)
|
||||||
|
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),c, PL)
|
||||||
|
else:
|
||||||
|
LineTo(Pointransf(xy, xpos, ypos, resize, rotx, roty, rotz),c, PL)
|
||||||
|
if closed:
|
||||||
|
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),c, PL)
|
||||||
|
|
||||||
|
|
||||||
|
def LinesPL(PL):
|
||||||
|
print ("Stupido !! your code is to old : use DrawPL() instead of LinesPL()")
|
||||||
|
DrawPL(PL)
|
||||||
|
|
||||||
|
def DrawPL(PL):
|
||||||
|
#print '/pl/0/'+str(PL), str(pl[PL])
|
||||||
|
if r.set('/pl/'+str(ClientNumber)+'/'+str(PL), str(pl[PL])) == True:
|
||||||
|
pl[PL] = []
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def ResetPL(self, PL):
|
||||||
|
pl[PL] = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def DigitsDots(number,color):
|
||||||
|
dots =[]
|
||||||
|
for dot in ASCII_GRAPHICS[number]:
|
||||||
|
#print dot
|
||||||
|
dots.append((gstt.xy_center[0]+dot[0],gstt.xy_center[1]+dot[1],color))
|
||||||
|
#self.point_list.append((xy + (c,)))
|
||||||
|
return dots
|
||||||
|
|
||||||
|
def CharDots(char,color):
|
||||||
|
|
||||||
|
dots =[]
|
||||||
|
for dot in ASCII_GRAPHICS[ord(char)-46]:
|
||||||
|
dots.append((dot[0],dot[1],color))
|
||||||
|
return dots
|
||||||
|
|
||||||
|
def Text(message,c, PL, xpos, ypos, resize, rotx, roty, rotz):
|
||||||
|
|
||||||
|
dots =[]
|
||||||
|
|
||||||
|
l = len(message)
|
||||||
|
i= 0
|
||||||
|
#print message
|
||||||
|
|
||||||
|
for ch in message:
|
||||||
|
|
||||||
|
#print ""
|
||||||
|
# texte centre en x automatiquement selon le nombre de lettres l
|
||||||
|
x_offset = 26 * (- (0.9*l) + 3*i)
|
||||||
|
#print i,x_offset
|
||||||
|
if ord(ch)<58:
|
||||||
|
char_pl_list = ASCII_GRAPHICS[ord(ch) - 48]
|
||||||
|
else:
|
||||||
|
char_pl_list = ASCII_GRAPHICS[ord(ch) - 46]
|
||||||
|
|
||||||
|
char_draw = []
|
||||||
|
#dots.append((char_pl_list[0][0] + x_offset,char_pl_list[0][1],0))
|
||||||
|
|
||||||
|
for xy in char_pl_list:
|
||||||
|
char_draw.append((xy[0] + x_offset,xy[1],c))
|
||||||
|
i +=1
|
||||||
|
#print ch,char_pl_list,char_draw
|
||||||
|
rPolyLineOneColor(char_draw, c, PL , False, xpos, ypos, resize, rotx, roty, rotz)
|
||||||
|
#dots.append(char_draw)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
225
clients/planetarium/main.py
Normal file
225
clients/planetarium/main.py
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
# coding=UTF-8
|
||||||
|
|
||||||
|
'''
|
||||||
|
Multi Laser planetarium in python3
|
||||||
|
|
||||||
|
Remember : LJ will automatically warp geometry according to alignement data. See webUI.
|
||||||
|
|
||||||
|
LICENCE : CC
|
||||||
|
'''
|
||||||
|
|
||||||
|
#import redis
|
||||||
|
import lj3
|
||||||
|
import numpy as np
|
||||||
|
import math,time
|
||||||
|
|
||||||
|
from astropy.coordinates import SkyCoord, EarthLocation, AltAz
|
||||||
|
from astropy import units as u
|
||||||
|
from astropy.time import Time
|
||||||
|
|
||||||
|
from skyfield.api import Star, load, Topos,Angle
|
||||||
|
from skyfield.data import hipparcos
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
is_py2 = sys.version[0] == '2'
|
||||||
|
if is_py2:
|
||||||
|
from Queue import Queue
|
||||||
|
else:
|
||||||
|
from queue import Queue
|
||||||
|
'''
|
||||||
|
|
||||||
|
#
|
||||||
|
# Arguments handler
|
||||||
|
#
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
print ("")
|
||||||
|
print ("Arguments parsing if needed...")
|
||||||
|
argsparser = argparse.ArgumentParser(description="Planetarium for LJ")
|
||||||
|
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
|
||||||
|
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
|
||||||
|
argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int)
|
||||||
|
|
||||||
|
args = argsparser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if args.client:
|
||||||
|
ljclient = args.client
|
||||||
|
else:
|
||||||
|
ljclient = 0
|
||||||
|
|
||||||
|
if args.laser:
|
||||||
|
plnumber = args.laser
|
||||||
|
else:
|
||||||
|
plnumber = 0
|
||||||
|
|
||||||
|
# Redis Computer IP
|
||||||
|
if args.redisIP != None:
|
||||||
|
redisIP = args.redisIP
|
||||||
|
else:
|
||||||
|
redisIP = '127.0.0.1'
|
||||||
|
|
||||||
|
lj3.Config(redisIP,ljclient)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Inits Laser
|
||||||
|
#
|
||||||
|
|
||||||
|
fov = 256
|
||||||
|
viewer_distance = 2.2
|
||||||
|
width = 450
|
||||||
|
height = 450
|
||||||
|
centerX = width / 2
|
||||||
|
centerY = height / 2
|
||||||
|
|
||||||
|
samparray = [0] * 100
|
||||||
|
# (x,y,color in integer) 65280 is color #00FF00
|
||||||
|
# Green rectangular shape :
|
||||||
|
pl0 = [(100,300,65280),(200,300,65280),(200,200,65280),(100,200,65280),(100,300,65280)]
|
||||||
|
|
||||||
|
# If you want to use rgb for color :
|
||||||
|
def rgb2int(r,g,b):
|
||||||
|
return int('0x%02x%02x%02x' % (r,g,b),0)
|
||||||
|
|
||||||
|
white = rgb2int(255,255,255)
|
||||||
|
red = rgb2int(255,0,0)
|
||||||
|
blue = rgb2int(0,0,255)
|
||||||
|
green = rgb2int(0,255,0)
|
||||||
|
|
||||||
|
|
||||||
|
def Proj(x,y,z,angleX,angleY,angleZ):
|
||||||
|
|
||||||
|
rad = angleX * math.pi / 180
|
||||||
|
cosa = math.cos(rad)
|
||||||
|
sina = math.sin(rad)
|
||||||
|
y2 = y
|
||||||
|
y = y2 * cosa - z * sina
|
||||||
|
z = y2 * sina + z * cosa
|
||||||
|
|
||||||
|
rad = angleY * math.pi / 180
|
||||||
|
cosa = math.cos(rad)
|
||||||
|
sina = math.sin(rad)
|
||||||
|
z2 = z
|
||||||
|
z = z2 * cosa - x * sina
|
||||||
|
x = z2 * sina + x * cosa
|
||||||
|
|
||||||
|
rad = angleZ * math.pi / 180
|
||||||
|
cosa = math.cos(rad)
|
||||||
|
sina = math.sin(rad)
|
||||||
|
x2 = x
|
||||||
|
x = x2 * cosa - y * sina
|
||||||
|
y = x2 * sina + y * cosa
|
||||||
|
|
||||||
|
|
||||||
|
""" Transforms this 3D point to 2D using a perspective projection. """
|
||||||
|
factor = fov / (viewer_distance + z)
|
||||||
|
x = x * factor + centerX
|
||||||
|
y = - y * factor + centerY
|
||||||
|
return (x,y)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Objects in Planetarium Field of View
|
||||||
|
#
|
||||||
|
|
||||||
|
# Compute Equatorial Right Ascension and Declinaison from given observator Altitude and Azimuth
|
||||||
|
def aa2radec(azimuth,altitude,lati,longi,elevation,t):
|
||||||
|
Observer = EarthLocation(lat=lati * u.deg, lon=longi *u.deg, height= elevation*u.m,)
|
||||||
|
ObjectCoord = SkyCoord(alt = altitude * u.deg, az = azimuth *u.deg, obstime = t, frame = 'altaz', location = Observer)
|
||||||
|
print("icrs",ObjectCoord.icrs)
|
||||||
|
print("ICRS Right Ascension", ObjectCoord.icrs.ra)
|
||||||
|
print("ICRS Declination", ObjectCoord.icrs.dec)
|
||||||
|
return ObjectCoord.icrs.ra.degree, ObjectCoord.icrs.dec.degree
|
||||||
|
|
||||||
|
|
||||||
|
# Compute given object apparent positions (ra,dec,alt,az) and distance from given gps earth position (in decimal degrees) at UTC time (in skyfield format)
|
||||||
|
def EarthObjPosition(gpslat,gpslong,object,t):
|
||||||
|
|
||||||
|
Observer = earth + Topos(gpslat, gpslong)
|
||||||
|
astrometric = earth.at(t).observe(object)
|
||||||
|
ra, dec, distance = astrometric.radec()
|
||||||
|
print("Right ascencion",ra)
|
||||||
|
print("RA in degree",ra._degrees)
|
||||||
|
print("RA in radians",ra.radians)
|
||||||
|
print("declinaison",dec)
|
||||||
|
print (distance)
|
||||||
|
ApparentPosition = Observer.at(t).observe(object).apparent()
|
||||||
|
alt, az, distance = ApparentPosition.altaz('standard')
|
||||||
|
print("UTC",t.utc_iso())
|
||||||
|
print ("Altitude",alt)
|
||||||
|
print("Altitude in radians",alt.radians)
|
||||||
|
print("Altitude in degrees",alt.degrees)
|
||||||
|
print("Altitude in dms",alt.dms(0))
|
||||||
|
print("Altitude in signed_dms",alt.signed_dms(0))
|
||||||
|
print("Azimuth", az.dstr())
|
||||||
|
print ("Distance from position", distance)
|
||||||
|
return ra._degrees, dec, alt.degrees, az, distance
|
||||||
|
|
||||||
|
def azimuth2scrX(leftAzi,rightAzi,s):
|
||||||
|
a1, a2 = leftAzi,rightAzi
|
||||||
|
b1, b2 = -width/2, width/2
|
||||||
|
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
|
||||||
|
|
||||||
|
def altitude2scrY(topAlti,botAlti,s):
|
||||||
|
a1, a2 = botAlti, topAlti
|
||||||
|
b1, b2 = -heigth/2, heigth/2
|
||||||
|
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
|
||||||
|
|
||||||
|
print("Loading hipparcos catalog...")
|
||||||
|
#hipparcosURL = 'ftp://cdsarc.u-strasbg.fr/cats/I/239/hip_main.dat.gz'
|
||||||
|
hipparcosURL = 'data/hip_main.dat.gz'
|
||||||
|
with load.open(hipparcosURL) as f:
|
||||||
|
hipdata = hipparcos.load_dataframe(f)
|
||||||
|
print("Loaded")
|
||||||
|
|
||||||
|
# Sky objects
|
||||||
|
ts = load.timescale()
|
||||||
|
hipparcos_epoch = ts.tt(1991.25)
|
||||||
|
barnards_star = Star.from_dataframe(hipdata.loc[87937])
|
||||||
|
polaris = Star.from_dataframe(hipdata.loc[11767])
|
||||||
|
# de421.bps https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/a_old_versions/de421.bsp
|
||||||
|
planets = load('data/de421.bsp')
|
||||||
|
print('de421 loaded.')
|
||||||
|
earth = planets['earth']
|
||||||
|
mars = planets['mars']
|
||||||
|
|
||||||
|
# On Earth Gps positions
|
||||||
|
|
||||||
|
# https://github.com/lutangar/cities.json.git
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main functions
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
def DrawPL():
|
||||||
|
|
||||||
|
Shape = []
|
||||||
|
counter =0
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
t = ts.now()
|
||||||
|
|
||||||
|
gpslat = '48.866669 N'
|
||||||
|
gpslong = '2.33333 E'
|
||||||
|
'''
|
||||||
|
for curve in np.arange(-1, 1, 0.2):
|
||||||
|
zsine = ssine(100,5,curve+counter)
|
||||||
|
|
||||||
|
zfactor = 7
|
||||||
|
Shape = []
|
||||||
|
x = curve
|
||||||
|
#x = 0
|
||||||
|
y = -1
|
||||||
|
for step in zsine:
|
||||||
|
Shape.append( Proj(x,y,step/zfactor,0,0,0))
|
||||||
|
y += 0.02
|
||||||
|
lj3.rPolyLineOneColor(Shape, c = white, PL = 0, closed = False, xpos = -450, ypos = -350, resize = 2.5, rotx =0, roty =0 , rotz=0)
|
||||||
|
|
||||||
|
lj3.DrawPL(0)
|
||||||
|
'''
|
||||||
|
counter += 0.001
|
||||||
|
time.sleep(0.01)
|
||||||
|
print("Running...")
|
||||||
|
DrawPL()
|
@ -151,6 +151,9 @@ def NoteOn(note):
|
|||||||
gstt.Laser = note -24
|
gstt.Laser = note -24
|
||||||
print "Current Laser switched to",gstt.Laser
|
print "Current Laser switched to",gstt.Laser
|
||||||
|
|
||||||
|
def Mouse(x1,y1,x2,y2):
|
||||||
|
print "Mouse", x1,y1,x2,y2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def handler(oscpath, args):
|
def handler(oscpath, args):
|
||||||
@ -158,11 +161,13 @@ def handler(oscpath, args):
|
|||||||
print ""
|
print ""
|
||||||
print "Handler"
|
print "Handler"
|
||||||
|
|
||||||
if oscpath[1] == "client" or oscpath[1] =="noteon":
|
if oscpath[1] == "client" or oscpath[1] =="noteon" or oscpath[1]=="mouse":
|
||||||
if oscpath[1] == "client":
|
if oscpath[1] == "client":
|
||||||
LasClientChange(int(args[0]))
|
LasClientChange(int(args[0]))
|
||||||
else:
|
elif oscpath[1] == "noteon":
|
||||||
NoteOn(int(args[0]))
|
NoteOn(int(args[0]))
|
||||||
|
elif oscpath[1] == "mouse":
|
||||||
|
Mouse(int(args[0]),int(args[1]),int(args[2]),int(args[3]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pathlength = len(oscpath)
|
pathlength = len(oscpath)
|
||||||
|
@ -139,18 +139,18 @@
|
|||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="loffset/X/0" diameter="60" min="-320" max="320" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/X/0" diameter="60" min="-320" max="320" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="loffset/Y/0" diameter="60" min="-320" max="320" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/Y/0" diameter="60" min="-320" max="320" value="0"></webaudio-knob></div>
|
||||||
|
<div class="lasertext">Offset X</div>
|
||||||
|
<div class="lasertext">Offset Y</div>
|
||||||
<div><webaudio-param link="loffset/X/0" value="0"></webaudio-param></div>
|
<div><webaudio-param link="loffset/X/0" value="0"></webaudio-param></div>
|
||||||
<div><webaudio-param link="loffset/Y/0" value="0"></webaudio-param></div>
|
<div><webaudio-param link="loffset/Y/0" value="0"></webaudio-param></div>
|
||||||
<div class="lasertext">Offset X</div>
|
|
||||||
<div class="lasertext">Offset Y</div>
|
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="scale/X/0" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/X/0" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="scale/Y/0" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/Y/0" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-param link="scale/X/0" value="0"></webaudio-param></div>
|
|
||||||
<div><webaudio-param link="scale/Y/0" value="0"></webaudio-param></div>
|
|
||||||
<div class="lasertext">Scale X</div>
|
<div class="lasertext">Scale X</div>
|
||||||
<div class="lasertext">Scale Y</div>
|
<div class="lasertext">Scale Y</div>
|
||||||
|
<div><webaudio-param link="scale/X/0" value="0"></webaudio-param></div>
|
||||||
|
<div><webaudio-param link="scale/Y/0" value="0"></webaudio-param></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="angle/0" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="angle/0" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
||||||
@ -188,18 +188,18 @@
|
|||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="loffset/X/1" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/X/1" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="loffset/Y/1" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/Y/1" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-param link="loffset/X/1" value="0"></webaudio-param></div>
|
<div class="lasertext">Offset X</div>
|
||||||
|
<div class="lasertext">Offset Y</div>
|
||||||
|
<div><webaudio-param link="loffset/X/1" value="0"></webaudio-param></div>
|
||||||
<div><webaudio-param link="loffset/Y/1" value="0"></webaudio-param></div>
|
<div><webaudio-param link="loffset/Y/1" value="0"></webaudio-param></div>
|
||||||
<div class="lasertext">Offset X</div>
|
|
||||||
<div class="lasertext">Offset Y</div>
|
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="scale/X/1" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/X/1" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="scale/Y/1" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/Y/1" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-param link="scale/X/1" value="0"></webaudio-param></div>
|
|
||||||
<div><webaudio-param link="scale/Y/1" value="0"></webaudio-param></div>
|
|
||||||
<div class="lasertext">Scale X</div>
|
<div class="lasertext">Scale X</div>
|
||||||
<div class="lasertext">Scale Y</div>
|
<div class="lasertext">Scale Y</div>
|
||||||
|
<div><webaudio-param link="scale/X/1" value="0"></webaudio-param></div>
|
||||||
|
<div><webaudio-param link="scale/Y/1" value="0"></webaudio-param></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="angle/1" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="angle/1" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
||||||
@ -237,18 +237,20 @@
|
|||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="loffset/X/2" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/X/2" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="loffset/Y/2" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/Y/2" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-param link="loffset/X/2" value="0"></webaudio-param></div>
|
<div class="lasertext">Offset X</div>
|
||||||
|
<div class="lasertext">Offset Y</div>
|
||||||
|
<div><webaudio-param link="loffset/X/2" value="0"></webaudio-param></div>
|
||||||
<div><webaudio-param link="loffset/Y/2" value="0"></webaudio-param></div>
|
<div><webaudio-param link="loffset/Y/2" value="0"></webaudio-param></div>
|
||||||
<div class="lasertext">Offset X</div>
|
|
||||||
<div class="lasertext">Offset Y</div>
|
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="scale/X/2" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/X/2" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="scale/Y/2" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/Y/2" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-param link="scale/X/2" value="0"></webaudio-param></div>
|
|
||||||
<div><webaudio-param link="scale/Y/2" value="0"></webaudio-param></div>
|
|
||||||
<div class="lasertext">Scale X</div>
|
<div class="lasertext">Scale X</div>
|
||||||
<div class="lasertext">Scale Y</div>
|
<div class="lasertext">Scale Y</div>
|
||||||
|
<div><webaudio-param link="scale/X/2" value="0"></webaudio-param></div>
|
||||||
|
<div><webaudio-param link="scale/Y/2" value="0"></webaudio-param></div>
|
||||||
|
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="angle/2" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="angle/2" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
||||||
@ -286,18 +288,20 @@
|
|||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="loffset/X/3" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/X/3" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="loffset/Y/3" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="loffset/Y/3" diameter="60" min="-20" max="20" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-param link="loffset/X/3" value="0"></webaudio-param></div>
|
<div class="lasertext">Offset X</div>
|
||||||
|
<div class="lasertext">Offset Y</div>
|
||||||
|
<div><webaudio-param link="loffset/X/3" value="0"></webaudio-param></div>
|
||||||
<div><webaudio-param link="loffset/Y/3" value="0"></webaudio-param></div>
|
<div><webaudio-param link="loffset/Y/3" value="0"></webaudio-param></div>
|
||||||
<div class="lasertext">Offset X</div>
|
|
||||||
<div class="lasertext">Offset Y</div>
|
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="scale/X/3" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/X/3" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-knob id="scale/Y/3" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="scale/Y/3" diameter="60" min="-10" max="10" value="0"></webaudio-knob></div>
|
||||||
<div><webaudio-param link="scale/X/3" value="0"></webaudio-param></div>
|
<div class="lasertext">Scale X</div>
|
||||||
|
<div class="lasertext">Scale Y</div>
|
||||||
|
<div><webaudio-param link="scale/X/3" value="0"></webaudio-param></div>
|
||||||
<div><webaudio-param link="scale/Y/3" value="0"></webaudio-param></div>
|
<div><webaudio-param link="scale/Y/3" value="0"></webaudio-param></div>
|
||||||
<div class="lasertext">Scale X</div>
|
|
||||||
<div class="lasertext">Scale Y</div>
|
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div><webaudio-knob id="angle/2" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
<div><webaudio-knob id="angle/2" diameter="60" min="-1" max="1" value="0"></webaudio-knob></div>
|
||||||
|
Loading…
Reference in New Issue
Block a user