Skip to content

Commit

Permalink
chars re-use
Browse files Browse the repository at this point in the history
  • Loading branch information
compartia committed Jun 25, 2023
1 parent 3528953 commit e53e0b8
Show file tree
Hide file tree
Showing 5 changed files with 396 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ glsl_torus/Backup/**
torus-clock/Backup/**
render
render ?/

render_0_complete
Binary file added _common/Literata-VariableFont_wght.ttf
Binary file not shown.
392 changes: 392 additions & 0 deletions poem_letter_cache_2/poem.pyde
Original file line number Diff line number Diff line change
@@ -0,0 +1,392 @@


DEBUG = False
DEV_MODE = True

SAVE_IMAGES=True #save each frame to /render folder
subframes = 25 #for motion blur, the more the smoother motion
screeen_size_divider = 2

minFramesStill = 70 #number of frames a glyph sits in its target pos


poem_prod = u'''
Секретные мысли,
согретые в прядях, все
найдено, все же,
настойчивый дактиль,
не кончит выискивать
в точках родимых созвездия,
в белом, в ознобе, язык
мокрой спикулой
чертит артерии,
кожа — текст Брайля,
губами прочитан стократно,
пульс общий, обратный
отсчет, темп — престиссимо.
Тянутся пальцы
к источнику влаги,
к дракону, к ядру,
к генератору ритма
синхронных биений и вы-
дохов экзотермических
форте, фортиссимо,
в самое пекло, укус,
через мускул, сквозь ребра,
до хруста, скула льнет
к скуле, совпадение, тел
излучение, рык
в шелк, клык
в левую мочку,
дыханием рваным удержан
губ крик,
вой, весь мир — волна,
трепет пневмы
в обертонах.
Это было тогда.
'''



poem_t = poem_prod

letters = []
glyphs = []
bbox = None

lineHeight = 1.62




text_size = 15

f=PFont()

currentLetter = 0
current_frame = 0
number_of_lines = 0

ATTRACTION_MAG = 20.0


if DEV_MODE:
#low res, for performance
screeen_size_divider = 4
subframes = 1
SAVE_IMAGES=False
poem_t = poem_prod[0:100]

poem = None
print('begin', poem_t)
#-------------------------
class Letter:
def __init__(self, c):
self.pos = PVector()
self.c = c
#-------------------------
class Glyph:
def __init__(self, c):

# super().__init__(c)

self.c = c
self.last_glyph = None

self.pos = PVector()
self.stillFrames = 0
self.target = None
self.deg = 0.0
self.phase = 0.0

self.speed = PVector()
self.repulsion = PVector()



def draw(self):
# print('g draw 1', self.pos)
lastpos = self.pos.copy()
# print('g draw 1.1', lastpos)
lastdeg = self.deg
# print('g draw 1.2')
self.animate()
# print('g draw 2')

fill(230, 255//subframes)
if DEBUG:
if self.canReuse():
fill(120, 255//subframes)
else:
fill(255, 255//subframes)

blendMode(ADD)
if DEBUG:
pushMatrix()
translate(self.pos.x , self.pos.y )
stroke(255,0,0)
line(0,0,self.repulsion.x*10, self.repulsion.y*10)
popMatrix()

for k in range(subframes):
subframe = float(k) / float(subframes)
v = PVector.lerp(self.pos, lastpos, subframe)
pushMatrix()

s_x = sin(float(frameCount) / 50.0 + 5.0 * self.pos.y / width)
s_y = cos(float(frameCount) / 30.0 + 5.0 * self.pos.x / width)

x = (0.6 * height/100.) * s_x
y = (1.2 *height/100.) * s_y
translate(v.x + x, v.y + y)

_angle =radians(lerp(self.deg, lastdeg, subframe))+ s_x * 0.05 - s_y * 0.05
rotate(_angle)
text( self.c, 0, 0)


popMatrix()

def setNewTarget(self, t):
self.target = t

def animate(self):
global glyphs, text_size

# repulsion ----------------------------
self.repulsion = PVector(0,0)
for g in glyphs:
if g !=self:
_dir = PVector.sub( self.pos, g.pos)
# _distSq = _dir.magSq() #TODO: try repulsion ~ inverse square dist
_dist = _dir.mag()

if _dist > 0.5: #no hyperforce at small distances
_dir.normalize()
if _dist < 1.0:
_dist = 1.0 #no hyperforce at small distances )

_dir.mult(0.03) #TODO: tune, see ATTRACTION_MAG

if _dist < width/2:
self.repulsion.add(_dir)

if _dist > text_size * 1.4 and self == g.last_glyph:
_dir.mult(ATTRACTION_MAG)
self.repulsion.sub(_dir)


if self.target is not None:
dspeed = PVector.sub(self.target.pos, self.pos).mult(0.02)
dist = self.pos.dist(self.target.pos)
_mag = dspeed.mag()
if _mag > 20:
dspeed.setMag(20) #speedlimit, sorry letters

self.speed.add(dspeed)

if dist < 0.4: #has came to desired pos
self.stillFrames += 1
else:
self.stillFrames = 0

if _mag < 20:
_mag = 0

self.repulsion.mult( _mag )

else:
self.stillFrames -= 1
rnd = 0.2
# self.speed.x += randomGaussian() * rnd
# self.speed.y += randomGaussian() * rnd

self.speed.add(self.repulsion)

_deg_inc = self.speed.mag() * 5.
# self.deg +=
if self.speed.x < 0:
self.deg -=_deg_inc
else:
self.deg += _deg_inc

self.deg *= 0.7575
if self.c in [u"а", u"о",u"у",u"е",u"ю"]:
self.speed.mult(0.8)
else:
self.speed.mult(0.8)

self.pos = self.pos.add(self.speed)

if self.stillFrames > minFramesStill*1.2:
self.target = None

def canReuse(self):
return self.target is None or self.stillFrames > minFramesStill



#------------------------------------------------------------------------------------------------
def makeLetters(poem):

print('makeLetters 1', len(poem), textWidth )

letters = [None] * len(poem)
glyphs = [] #[None] * len(poem)

x = 0.0
y = 0.0

maxX = 0.0
maxY = 0.0

last_glyph = None

print('makeLetters 2', len(poem), textWidth )
for i in range(len(poem)):

_char = poem[i]
w = textWidth(_char)

letters[i] = Letter(_char)
letters[i].pos = PVector(x, y)
# print('makeLetters 3', len(poem), textWidth )

if not (_char == ' ' or _char== '\n'):
_g = Glyph(_char)
_g.pos = letters[i].pos.copy()
_g.last_glyph = last_glyph

glyphs.append(_g)
last_glyph = _g

if x > maxX:
maxX = x
if y > maxY:
maxY = y

x = x+w

if _char == '\n':
y = y + (lineHeight * text_size)
x = 0.0


print('makeLetters 4', len(glyphs), len(letters) )

# Randomizing initial positions
for g in glyphs:
# print('makeLetters 3.1', g)
g.pos = PVector(maxX * randomGaussian(), maxY * abs(randomGaussian()))
# g.deg = randomGaussian()*300.0

print('makeLetters bbox:', maxX, maxY)
return letters, glyphs, PVector(maxX, maxY)



def setup():
print('setup -0')

global poem, poem_t, bbox, text_size, f, number_of_lines, letters, glyphs

# with open("poem_1.txt", 'r+') as file: #DOES not work with non-ascii (
# lines = file.readlines()
# lines = loadStrings("poem_1.txt") #DOES not work with non-ascii (

print('setup -11')
poem = poem_t.replace("--", "—").replace(" ", " ")
print(poem_t)
size(1080/screeen_size_divider, 1920/screeen_size_divider, JAVA2D) # Instagram best reel 1920

background(20)

pixelDensity(2) #retina
frameRate(30) #ha ha ha
smooth(4)

text_size = height // 45
print('setup 1')
f = createFont("../_common/Literata-VariableFont_wght.ttf", text_size, True)
# print(f)

textFont(f, text_size)
textSize(text_size)

print(makeLetters)

letters, glyphs, bbox = makeLetters(poem)

print('setup done:', len(letters), len(glyphs), bbox)


def findFreeGlyph(l, glyphs):
candidate = None
minDist = 2000*2000
#finding just nearest available for moving
#TODO: try to find one with bes alligned speed vector, so it starts smoothly
for g in glyphs:
if g.canReuse() and g.c == l.c:
_d = l.pos.dist(g.pos)
if _d < minDist:
minDist = _d
candidate = g
return candidate



last_y_translation =0

def drawPoem():

global last_y_translation
global glyphs, letters, current_frame, currentLetter


pushMatrix()

new_y_translation = lerp(last_y_translation, -letters[currentLetter].pos.y + height/3, 0.005)

translate(0, new_y_translation)
last_y_translation = new_y_translation


for g in glyphs:
g.draw()


if current_frame % 2 == 0 and current_frame > 100:
cl = letters[currentLetter]
currentLetter = (currentLetter + 1) % len(letters)

cg = findFreeGlyph(cl, glyphs)
if cg is not None:
cg.setNewTarget(cl)


popMatrix()


def draw():
global current_frame
current_frame = current_frame+1
pushMatrix()
translate((width - bbox.x) / 2, 0) # center text on screen
scale(0.8) #TODO: calculate it on text size

# translate((width - bbox.x) / 2, (height - bbox.y) / 2) # center text on screen

background(0)

fill(255, 140)


drawPoem()

if frameCount < 4000 and SAVE_IMAGES:
if frameCount % 100 == 0:
print(frameCount)
saveFrame("render/poem_####.png")
popMatrix()


Binary file added poem_letter_cache_2/poem_3887.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit e53e0b8

Please sign in to comment.