Neurasense / app.py
Sephfox's picture
Create app.py
0611560 verified
raw
history blame
1.66 kB
import streamlit as st
import numpy as np
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
from bokeh.events import Tap
Constants
WIDTH, HEIGHT = 600, 600
ELASTICITY = 0.3
DAMPING = 0.7
Create touch points
num_points = 20
x = np.linspace(50, WIDTH-50, num_points)
y = np.linspace(50, HEIGHT-50, num_points)
xx, yy = np.meshgrid(x, y)
touch_points = np.column_stack((xx.ravel(), yy.ravel()))
original_points = touch_points.copy()
velocities = np.zeros_like(touch_points)
source = ColumnDataSource(data=dict(x=touch_points[:, 0], y=touch_points[:, 1]))
Set up the Bokeh plot
p = figure(width=WIDTH, height=HEIGHT, tools="", toolbar_location=None)
p.circle('x', 'y', size=5, color="navy", alpha=0.5, source=source)
Streamlit app
st.title("Artificial Touch Simulation")
Create a Streamlit container for the Bokeh plot
chart = st.bokeh_chart(p)
def update_points():
global touch_points, velocities
# Apply spring force
force = (original_points - touch_points) * ELASTICITY
# Update velocity
velocities += force
# Apply damping
velocities *= DAMPING
# Update position
touch_points += velocities
# Update Bokeh data source
source.data = dict(x=touch_points[:, 0], y=touch_points[:, 1])
def on_tap(event):
global touch_points, velocities
x, y = event.x, event.y
distances = np.sqrt(np.sum((touch_points - [x, y])**2, axis=1))
affected = distances < 30
force = (touch_points[affected] - [x, y]) / distances[affected, np.newaxis]
velocities[affected] -= force * 10
st.write(f"Touch at ({x:.2f}, {y:.2f})")
update_points()
p.on_event(Tap, on_tap)
Main loop
while True:
update_points()
chart.bokeh_chart(p)
st.experimental_rerun()