Compare commits

...

4 Commits

Author SHA1 Message Date
9fecb97df7 [feat] drawing optimisation
add some generator to test the optoimisation:

adjust_brightness.py:
	set some rectangle to rerify the consant of brightnes
keyborad_input.py:
	is an exenmple of non blocking input reading
angleInteractive.py:
	is an interactiv version to test the angle.
	you can separatly set the lenght of each segment
	you can set the angle
	it must be run without brightnes optimization because mey be lenght have an importance
2020-12-30 19:16:18 +01:00
6994ea911f [fix]: drawing optimization
fix the adjust_brightness() function.
blank point was not included
2020-12-30 19:11:29 +01:00
f3314441d3 [feat] drawing_optimisation: in progess
the feature implement a paper: https://art-science.org/journal/v7n4/v7n4pp155/artsci-v7n4pp155.pdf

there is some generator to test the optimisation in: ./clitools/generators/drawingTests/
Now, all the optimisation will be in ./libs3/plotOptimizer.py
in ./libs3/tracer3.py the adding of point is avoid an will be replace by the optimisation from the paper
2020-12-17 20:21:04 +01:00
8164320694 [fix] to avoid temporary vim's file 2020-12-17 20:18:32 +01:00
10 changed files with 1070 additions and 28 deletions

4
.gitignore vendored
View File

@ -1,3 +1,5 @@
.*swp* .*sw*
*__pycache__ *__pycache__
www/config.js www/config.js

View File

@ -0,0 +1,73 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
This generator print different squar from big to small.
The purepose is to see the difference of brightness with the length
v0.1.0
LICENCE : CC
by lapin (aka nipal)
'''
from __future__ import print_function
import time
import argparse
import sys
import math
name="generator::endingPoint"
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
argsparser = argparse.ArgumentParser(description="dummy generator")
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-s","--speed",help="point per frame progress",default=3,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output")
args = argsparser.parse_args()
fps=args.fps
verbose=args.verbose
optimal_looptime = 1 / fps
debug(name+" optimal looptime "+str(optimal_looptime))
width = 800
height = 800
offset = 50
white = 0xFFFFFF
blank = 0x0
shape = []
def set_shape():
nb_spire = int(width / (2 * offset)) - 1
for i in range(1, nb_spire + 1):
shape.append([ i * offset, i * offset, blank])
shape.append([ i * offset, i * offset, white])
shape.append([ i * offset, height - i * offset, white])
shape.append([width - i * offset, height - i * offset, white])
shape.append([width - i * offset, i * offset, white])
shape.append([ i * offset, i * offset, white])
shape.append([ i * offset, i * offset, blank])
set_shape()
while True:
start = time.time()
print(shape, flush=True);
looptime = time.time() - start
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
debug(name+" micro sleep:"+str( optimal_looptime - looptime))

View File

@ -0,0 +1,262 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
This generator print diferent one angle but you can modify it interactively.
The key are:
* '' => *somthing*
* ...
v0.1.0
LICENCE : CC
by lapin (aka nipal)
'''
from __future__ import print_function
import time
import argparse
import math
import sys
# import for non-bloking input reading
#import sys
import select
import tty
import termios
name="generator::endingPoint"
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
def isData():
return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])
def flush_input():
try:
import msvcrt
while msvcrt.kbhit():
msvcrt.getch()
except ImportError:
import sys, termios #for linux/unix
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
old_settings = termios.tcgetattr(sys.stdin)
argsparser = argparse.ArgumentParser(description="dummy generator")
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-s","--speed",help="point per frame progress",default=3,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output")
args = argsparser.parse_args()
fps=args.fps
verbose=args.verbose
optimal_looptime = 1 / fps
#debug(name+" optimal looptime "+str(optimal_looptime))
width = 800
height = 800
white = 0xFFFFFF
blank = 0x0
seg1_length = 100
seg2_length = 100
ang = 50
incrLengthLittle= 5
incrLengthLot= 20
incrAngleLittle= 1
incrAngleLot= 10
angle_min = 0
angle_max = 90
length_min = 1
length_max = 350
shape = []
# angle
def ang_add_1():
global ang
if ang + incrAngleLittle <= angle_max:
ang += incrAngleLittle
else:
ang = angle_max
def ang_add_2():
global ang
if ang + incrAngleLot <= angle_max:
ang += incrAngleLot
else:
ang = angle_max
def ang_sub_1():
global ang
if ang - incrAngleLittle >= angle_min:
ang -= incrAngleLittle
else:
ang = angle_min
def ang_sub_2():
global ang
if ang - incrAngleLot >= angle_min:
ang -= incrAngleLot
else:
ang = angle_min
# seg1
def seg_1_add_1():
global seg1_length
if seg1_length + incrLengthLittle <= length_max:
seg1_length += incrLengthLittle
else:
seg1_length = length_max
def seg_1_add_2():
global seg1_length
if seg1_length + incrLengthLot <= length_max:
seg1_length += incrLengthLot
else:
seg1_length = length_max
def seg_1_sub_1():
global seg1_length
if seg1_length - incrLengthLittle >= length_min:
seg1_length -= incrLengthLittle
else:
seg1_length = length_min
def seg_1_sub_2():
global seg1_length
if seg1_length - incrLengthLot >= length_min:
seg1_length -= incrLengthLot
else:
seg1_length = length_min
# seg2
def seg_2_add_1():
global seg2_length
if seg2_length + incrLengthLittle <= length_max:
seg2_length += incrLengthLittle
else:
seg2_length = length_max
def seg_2_add_2():
global seg2_length
if seg2_length + incrLengthLot <= length_max:
seg2_length += incrLengthLot
else:
seg2_length = length_max
def seg_2_sub_1():
global seg2_length
if seg2_length - incrLengthLittle >= length_min:
seg2_length -= incrLengthLittle
else:
seg2_length = length_min
def seg_2_sub_2():
global seg2_length
if seg2_length - incrLengthLot >= length_min:
seg2_length -= incrLengthLot
else:
seg2_length = length_min
action = {
# segment 1
'q': seg_1_sub_1,
'w': ssg_1_add_1,
'a': seg_1_sub_2,
's': seg_1_add_2,
# segment 2
'o': seg_2_sub_1,
'p': seg_2_add_1,
'l': seg_2_sub_2,
';': seg_2_add_2,
# angle
't': ang_sub_1,
'y': ang_add_1,
'g': ang_sub_2,
'h': ang_add_2,
}
def print_param():
debug("\n\n===")
debug("segment 1 length:", seg1_length)
debug("segment 2 length:", seg2_length)
debug("angle:", ang)
def set_shape():
global shape
shape.clear()
cx = width / 2
cy = height / 2
px1 = int(seg1_length * math.cos(math.radians(ang)))
py1 = int(seg1_length * math.sin(math.radians(ang)))
px2 = int(seg2_length * math.cos(math.radians(ang)))
py2 = int(seg2_length * math.sin(math.radians(ang)))
# line up
shape.append([-px1 + cx, -py1 + cy, blank])
shape.append([-px1 + cx, -py1 + cy, white])
shape.append([ cx, + cy, white])
shape.append([ px2 + cx, -py2 + cy, white])
shape.append([ px2 + cx, -py2 + cy, blank])
# line down
shape.append([ px1 + cx, py1 + cy, blank])
shape.append([ px1 + cx, py1 + cy, white])
shape.append([ cx, + cy, white])
shape.append([-px2 + cx, py2 + cy, white])
shape.append([-px2 + cx, py2 + cy, blank])
def update_param(c):
if c in action:
action[c]()
print_param()
set_shape()
try:
tty.setcbreak(sys.stdin.fileno())
set_shape()
print_param()
print(shape, flush=True);
while 1:
if isData():
c = sys.stdin.read(1)
update_param(c)
start = time.time()
print(shape, flush=True);
looptime = time.time() - start
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
#debug(name+" micro sleep:"+str( optimal_looptime - looptime))
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)

View File

@ -0,0 +1,98 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
This generator print different angle form 0 to 180 degres
v0.1.0
LICENCE : CC
by lapin (aka nipal)
'''
from __future__ import print_function
import time
import argparse
import sys
import math
name="generator::endingPoint"
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
argsparser = argparse.ArgumentParser(description="dummy generator")
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-s","--speed",help="point per frame progress",default=3,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output")
args = argsparser.parse_args()
fps=args.fps
verbose=args.verbose
optimal_looptime = 1 / fps
debug(name+" optimal looptime "+str(optimal_looptime))
width = 800
height = 800
white = 0xFFFFFF
blank = 0
radius = 100
offset_circles = 10
beg_angle = 0
end_angle = 90
offset_angle = 10
angles_lines = []
shape = []
def set_angles_lines():
margin = radius + offset_circles
spacing_betwen = 2 * radius + offset_circles
circles_per_line = math.floor((width - margin) / spacing_betwen)
for ang in range(beg_angle, end_angle + offset_angle, offset_angle):
nb = int(ang / offset_angle)
cx = margin + (nb % circles_per_line) * spacing_betwen
cy = margin + int(nb / circles_per_line) * spacing_betwen
px = radius * math.cos(math.radians(ang))
py = radius * math.sin(math.radians(ang))
# line up
angles_lines.append([-px + cx, py + cy, blank])
angles_lines.append([-px + cx, py + cy, white])
angles_lines.append([ cx, 2 + cy, white])
angles_lines.append([ px + cx, py + cy, white])
#angles_lines.append([ px + cx, py + cy, blank])
# line down
angles_lines.append([-px + cx, -py + cy, blank])
angles_lines.append([-px + cx, -py + cy, white])
angles_lines.append([ cx, -2 + cy, white])
angles_lines.append([ px + cx, -py + cy, white])
#angles_lines.append([ px + cx, -py + cy, blank])
set_angles_lines()
shape = angles_lines
# print(angles_lines)
while True:
start = time.time()
print(shape, flush=True);
looptime = time.time() - start
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
debug(name+" micro sleep:"+str( optimal_looptime - looptime))

View File

@ -0,0 +1,117 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
This generator print a shape with 3 discinected component, 2 non eulerian and one eulerian.
v0.1.0
LICENCE : CC
by lapin (aka nipal)
'''
from __future__ import print_function
import time
import argparse
import sys
import math
name="generator::endingPoint"
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
def debug2(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
argsparser = argparse.ArgumentParser(description="dummy generator")
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-s","--speed",help="point per frame progress",default=3,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output")
args = argsparser.parse_args()
fps=args.fps
verbose=args.verbose
optimal_looptime = 1 / fps
debug(name+" optimal looptime "+str(optimal_looptime))
width = 800
height = 800
white = 0xFFFFFF
blank = 0
def shape_scale(shape, scale_factor):
new_shape = []
for p in shape:
new_shape.append([p[0] * scale_factor, p[1] * scale_factor, p[2]])
return new_shape
def shape_incr(shape, x, y):
new_shape = []
for p in shape:
new_shape.append([p[0] + x, p[1] + y, p[2]])
return new_shape
comp_a = []
comp_b = []
comp_c = []
comp_b.append([ 0, 3, blank])
comp_b.append([ 0, 4, white])
comp_b.append([ 0, 0, white])
comp_b.append([ 3, 0, white])
comp_b.append([ 3, 6, white])
comp_b.append([ 3, 6, white])
comp_b.append([ 3, 0, white])
comp_b.append([ 3, 0, blank])
comp_b.append([ 3, 0, white])
comp_b.append([ 5, 4, white])
comp_b.append([ 5, 4, blank])
comp_a.append([ 5, 17, blank])
comp_a.append([ 5, 17, white])
comp_a.append([ 0, 5, white])
comp_a.append([12, 0, white])
comp_a.append([17, 12, white])
comp_a.append([ 5, 17, white])
comp_a.append([ 5, 17, blank])
comp_c.append([-3, 5, blank])
comp_c.append([-3, 5, white])
comp_c.append([ 0, 4, white])
comp_c.append([ 0, 0, white])
comp_c.append([ 4, 0, white])
comp_c.append([ 4, 4, white])
comp_c.append([ 7, 5, white])
comp_c.append([ 7, 5, blank])
comp_a = shape_scale(comp_a, 11)
comp_a = shape_incr(comp_a, 300, 75)
comp_b = shape_scale(comp_b, 45)
comp_b = shape_incr(comp_b, 0, 300)
comp_c = shape_scale(comp_c, 30)
comp_c = shape_incr(comp_c, 600, 300)
shape = comp_a + comp_b + comp_c
while True:
start = time.time()
print(shape, flush=True);
looptime = time.time() - start
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
debug(name+" micro sleep:"+str( optimal_looptime - looptime))

View File

@ -0,0 +1,77 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
This generator print 3 static vertical line.
The aim is to show The aim is to show the laser beam ignition time.
beam when ther is no optimisation
v0.1.0
LICENCE : CC
by lapin (aka nipal)
'''
from __future__ import print_function
import time
import argparse
import sys
name="generator::endingPoint"
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
argsparser = argparse.ArgumentParser(description="dummy generator")
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-s","--speed",help="point per frame progress",default=3,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output")
args = argsparser.parse_args()
fps=args.fps
verbose=args.verbose
optimal_looptime = 1 / fps
debug(name+" optimal looptime "+str(optimal_looptime))
white = 0xFFFFFF
blank = 0
offset_y = 100
offset_x = 50
begin_x = 200
begin_y = 200
shape_factor = [
[0, 0, white],
[0, 1, blank],
[1, 1, white],
[1, 0, blank],
[2, 0, white],
[2, 1, blank],
[2, 1, blank],
]
shape = []
for point in shape_factor:
shape.append([begin_x + offset_x * point[0],
begin_y + offset_y * point[1],
point[2]])
while True:
start = time.time()
print(shape, flush=True);
looptime = time.time() - start
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
debug(name+" micro sleep:"+str( optimal_looptime - looptime))

View File

@ -0,0 +1,77 @@
# code exemple find at : https://stackoverflow.com/questions/2408560/python-nonblocking-console-input
import sys
import select
import tty
import termios
def isData():
return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])
old_settings = termios.tcgetattr(sys.stdin)
try:
tty.setcbreak(sys.stdin.fileno())
i = 0
while 1:
#if i % 100000 == 0:
# print("i", i)
#i += 1
if isData():
c = sys.stdin.read(1)
print(c)
if c == '\x1b': # x1b is ESC
break
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
### for windows
#import msvcrt
#
#num = 0
#done = False
#while not done:
# print(num)
# num += 1
#
# if msvcrt.kbhit():
# print "you pressed",msvcrt.getch(),"so now i will quit"
# done = True
#
## cross platforme (but may be a bit huge to import pygame...)
#import pygame
#from pygame.locals import *
#
#def display(str):
# text = font.render(str, True, (255, 255, 255), (159, 182, 205))
# textRect = text.get_rect()
# textRect.centerx = screen.get_rect().centerx
# textRect.centery = screen.get_rect().centery
#
# screen.blit(text, textRect)
# pygame.display.update()
#
#pygame.init()
#screen = pygame.display.set_mode( (640,480) )
#pygame.display.set_caption('Python numbers')
#screen.fill((159, 182, 205))
#
#font = pygame.font.Font(None, 17)
#
#num = 0
#done = False
#while not done:
# display( str(num) )
# num += 1
#
# pygame.event.pump()
# keys = pygame.key.get_pressed()
# if keys[K_ESCAPE]:
# done = True
#

View File

@ -0,0 +1,84 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
This generator print a shape with best angle representation when the path is redraw
v0.1.0
LICENCE : CC
by lapin (aka nipal)
'''
from __future__ import print_function
import time
import argparse
import sys
import math
name="generator::endingPoint"
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
def debug2(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
argsparser = argparse.ArgumentParser(description="dummy generator")
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-s","--speed",help="point per frame progress",default=3,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose output")
args = argsparser.parse_args()
fps=args.fps
verbose=args.verbose
optimal_looptime = 1 / fps
debug(name+" optimal looptime "+str(optimal_looptime))
width = 800
height = 800
white = 0xFFFFFF
blank = 0
point_offset = 250
point_width = 4
point_list = [
[8,7,6,10,7,3,6,2,7,11,6,9],
[5,6,1,],
[4,7,12,],
]
shape = []
# on ajoute des lilste de point
for l in point_list:
x = point_offset * ((l[0] - 1) % (point_width))
y = point_offset * int((l[0] - 1) / (point_width))
shape.append([x, y, blank])
debug2("=====")
debug2(f"id: {l[0]}\tx: {x}\ty: {y}\t\tpoint_width: {point_width}\t\n")
for p in l:
x = point_offset * ((p - 1) % (point_width))
y = point_offset * int((p - 1) / (point_width))
shape.append([x, y, white])
debug2(f"id: {p}\tx: {x}\ty: {y}\t\tpoint_width: {point_width}\t\n")
while True:
start = time.time()
print(shape, flush=True);
looptime = time.time() - start
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
debug(name+" micro sleep:"+str( optimal_looptime - looptime))

255
libs3/plotOptimizer.py Normal file

File diff suppressed because one or more lines are too long

View File

@ -81,7 +81,8 @@ import pdb
import ast import ast
import redis import redis
from libs3 import homographyp from libs3 import homographyp, plotOptimizer as po
import numpy as np import numpy as np
import binascii import binascii
@ -223,43 +224,39 @@ class DAC(object):
while True: while True:
#pdb.set_trace() self.pl = po.optimizer(self.pl)
for indexpoint,currentpoint in enumerate(self.pl): for indexpoint,currentpoint in enumerate(self.pl):
#print indexpoint, currentpoint
# transformations des point au format adapter au etherdream
xyc = [currentpoint[0],currentpoint[1],currentpoint[2]] xyc = [currentpoint[0],currentpoint[1],currentpoint[2]]
self.xyrgb = self.EtherPoint(xyc) self.xyrgb = self.EtherPoint(xyc)
#print(self.xyrgb[2:])
rgb = (round(self.xyrgb[2:][0] *self.intred/100), round(self.xyrgb[2:][1] *self.intgreen/100), round(self.xyrgb[2:][2] *self.intblue/100)) rgb = (round(self.xyrgb[2:][0] *self.intred/100), round(self.xyrgb[2:][1] *self.intgreen/100), round(self.xyrgb[2:][2] *self.intblue/100))
#print("rgb :", rgb)
#round(*self.intred/100) yield self.xyrgb
#round(*self.intgreen/100) ##**//# ajout de point pour un tracer adapter
#round(*self.intblue/100) ##**//delta_x, delta_y = self.xyrgb[0] - self.xyrgb_prev[0], self.xyrgb[1] - self.xyrgb_prev[1]
##**//#test adaptation selon longueur ligne
##**//if math.hypot(delta_x, delta_y) < 4000:
delta_x, delta_y = self.xyrgb[0] - self.xyrgb_prev[0], self.xyrgb[1] - self.xyrgb_prev[1] ##**// # For glitch art : decrease lsteps
##**// #l_steps = [ (1.0, 8)]
##**// l_steps = gstt.stepshortline
#test adaptation selon longueur ligne ##**//else:
if math.hypot(delta_x, delta_y) < 4000: ##**// # For glitch art : decrease lsteps
##**// #l_steps = [ (0.25, 3), (0.75, 3), (1.0, 10)]
##**// l_steps = gstt.stepslongline
# For glitch art : decrease lsteps ##**//for e in l_steps:
#l_steps = [ (1.0, 8)] ##**// step = e[0]
l_steps = gstt.stepshortline
else: ##**// for i in range(0,e[1]):
# For glitch art : decrease lsteps
#l_steps = [ (0.25, 3), (0.75, 3), (1.0, 10)]
l_steps = gstt.stepslongline
for e in l_steps: ##**// self.xyrgb_step = (self.xyrgb_prev[0] + step*delta_x, self.xyrgb_prev[1] + step*delta_y) + rgb # + self.xyrgb_prev[2:]# + rgb
step = e[0] ##**// #print(self.xyrgb_step)
##**// yield self.xyrgb_step
for i in range(0,e[1]): ##**//self.xyrgb_prev = self.xyrgb
self.xyrgb_step = (self.xyrgb_prev[0] + step*delta_x, self.xyrgb_prev[1] + step*delta_y) + rgb # + self.xyrgb_prev[2:]# + rgb
#print(self.xyrgb_step)
yield self.xyrgb_step
self.xyrgb_prev = self.xyrgb
def GetPoints(self, n): def GetPoints(self, n):