Neurasense / app.py
Sephfox's picture
Update app.py
a91f6dd verified
raw
history blame
1.8 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, dtype=np.bool_)
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)
while True:
update_points()
chart.bokeh_chart(p)
st.experimental_rerun()