lj-clitools/filters/kaleidoscope.py

174 lines
5.6 KiB
Python
Executable File

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
kaleidoscop
v0.1.0
A simple effect : mirror a quadrant of the input
Licensed under GNU GPLv3
by Sam Neurohack
'''
from __future__ import print_function
import sys
import ast
import os
import argparse
ljpath = r'%s' % os.getcwd().replace('\\','/')
sys.path.append(ljpath +'/../libs/')
sys.path.append(ljpath +'/libs/')
import time
name = "filters::kaleidoscope"
argsparser = argparse.ArgumentParser(description="Redis exporter LJ")
argsparser.add_argument("-x","--centerX",help="geometrical center X position",default=400,type=int)
argsparser.add_argument("-y","--centerY",help="geometrical center Y position",default=400,type=int)
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose")
args = argsparser.parse_args()
fps = args.fps
centerX = args.centerX
centerY = args.centerY
verbose = args.verbose
optimal_looptime = 1 / fps
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
def kaleidoscope( pl ):
# Stage 1: Crop points in single quadrant
quad1 = []
# Iterate trough the segments
for i in range( 0, len(pl) ):
#debug(name+" point #", i)
currentpoint = cp = pl[i]
cx,cy,cc = [cp[0],cp[1],cp[2]]
# Exception: escape early if last point
if i == len(pl) - 1:
if cx >= centerX and cy >= centerY :
quad1.append( currentpoint )
break
# Search for the couple of points
nextpoint = pl[i+1]
nx,ny,nc = [nextpoint[0],nextpoint[1],nextpoint[2]]
rect=[[cx,cy],[cx,ny],[nx,ny],[nx,cy]]
right = wrong = 0
#debug(name+" rect: ", rect,"curr",currentpoint,"next",nextpoint )
# Enumerate the points in rectangle to see
# how many right / wrong there are
# either to add or skip early
for iterator, p in enumerate(rect):
if p[0] >= centerX and p[1] >= centerY:
right += 1
else:
#if p[0] <= centerX and p[1] <= centerY:
wrong += 1
# If all rectangle points are in the right quadrant, Add and Skip
if right == 4:
quad1.append(pl[i])
#debug(name+" found valid point", pl[i])
continue
# If all rectangle points in wrong quadrant, Skip
if wrong == 4:
#debug(name+" found bad point", pl[i])
continue
# Find the (x,y) intersections
#
#debug(name+" Looking for crossing point between ("+str(cx)+","+str(cy)+") and ("+str(nx)+","+str(ny)+")")
delta=[ nx - cx, ny - cy ]
#debug(name+" delta:",delta)
crossX = None
crossY = None
absnewX = 0
absnewY = 0
# If one point has negative x, search y axis crossing
if cx < centerX or nx < centerX:
if delta[0] == 0 :
delta[0] = 0.0000001
v=[ delta[0]/abs(delta[0]), delta[1]/abs(delta[0]) ]
absnewX = abs( centerX - cx )
#print("on y axis, v=",str(v)," and absnewX=",str(absnewX))
crossX = [( absnewX*v[0] + cx ),( absnewX*v[1]+cy ), nc]
# If one point has negative y, search x axis crossing
if cy < centerY or ny < centerY:
if delta[1] == 0 :
delta[1] = 0.0000001
v=[ delta[0]/abs(delta[1]), delta[1]/abs(delta[1])]
absnewY = abs( centerY - cy )
#print("on x axis, v=",str(v)," and absnewY=",str(absnewY))
crossY = [( absnewY*v[0] + cy ),( absnewY*v[1]+cy ), nc]
# Inject in order
# If current point is the quadrant, add it
if cx >= centerX and cy >= centerY :
quad1.append( currentpoint )
# If absnewX smaller, it is closest to currentPoint
if absnewX < absnewY:
if None != crossX : quad1.append( crossX )
if None != crossY : quad1.append( crossY )
else :
if None != crossY : quad1.append( crossY )
if None != crossX : quad1.append( crossX )
# Add a black point at the end
#lastQuad1Point = quad1[-1]
#quad1.append( [lastQuad1Point[0],lastQuad1Point[1],0] )
## Stage 2 : Mirror points
#
quad2 = []
# quad2 = vertical symetric of quad1
for iterator in range( len(quad1) -1 , -1, -1):
point = quad1[iterator]
quad2.append([ point[0], 2*centerY - point[1], point[2] ])
# quad3 is the merge of 1 and 2
quad3 = quad1 + quad2
# quad4 is the horizontal symetric of quad3
quad4 = []
for iterator in range( len(quad3) -1, -1, -1):
point = quad3[iterator]
quad4.append([ 2*centerX - point[0], point[1], point[2] ])
#debug(name+" quad1:",quad1)
#debug(name+" quad2:", quad2 )
#debug(name+" quad3:", quad3 )
#debug(name+" quad4:", quad4 )
return quad3+quad4
try:
while True:
start = time.time()
line = sys.stdin.readline()
if line == "":
time.sleep(0.01)
line = line.rstrip('\n')
pointsList = ast.literal_eval(line)
# Do the filter
result = kaleidoscope( pointsList )
if len(result) : print( result, flush=True )
looptime = time.time() - start
# debug(name+" looptime:"+str(looptime))
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
# debug(name+" micro sleep:"+str( optimal_looptime - looptime))
except EOFError:
debug(name+" break")# no more information