Planetarium first functions

This commit is contained in:
leduc 2019-01-28 14:18:19 +01:00
parent e6366649a4
commit 4131126734
7 changed files with 603 additions and 118 deletions

View File

@ -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

View File

@ -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)

View 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
View 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
View 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()

View File

@ -151,6 +151,9 @@ def NoteOn(note):
gstt.Laser = note -24
print "Current Laser switched to",gstt.Laser
def Mouse(x1,y1,x2,y2):
print "Mouse", x1,y1,x2,y2
def handler(oscpath, args):
@ -158,11 +161,13 @@ def handler(oscpath, args):
print ""
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":
LasClientChange(int(args[0]))
else:
elif oscpath[1] == "noteon":
NoteOn(int(args[0]))
elif oscpath[1] == "mouse":
Mouse(int(args[0]),int(args[1]),int(args[2]),int(args[3]))
else:
pathlength = len(oscpath)

View File

@ -139,18 +139,18 @@
<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/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/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><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-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 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><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><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-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 class="lasertext">Offset X</div>
<div class="lasertext">Offset Y</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/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 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><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><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-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 class="lasertext">Offset X</div>
<div class="lasertext">Offset Y</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/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 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><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><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-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 class="lasertext">Offset X</div>
<div class="lasertext">Offset Y</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/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 class="lasertext">Scale X</div>
<div class="lasertext">Scale Y</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>