Sephfox commited on
Commit
b083c09
·
verified ·
1 Parent(s): be22792

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -92
app.py CHANGED
@@ -3,6 +3,8 @@ import numpy as np
3
  from typing import List, Tuple
4
  from transformers import pipeline
5
  import matplotlib.pyplot as plt
 
 
6
  import time
7
 
8
  # Constants
@@ -10,16 +12,12 @@ WIDTH, HEIGHT = 600, 600
10
  ELASTICITY = 0.3
11
  DAMPING = 0.7
12
 
13
- # Create touch points
14
- num_points = 20
15
- touch_points: List[Tuple[float, float]] = [(x, y) for x in range(50, WIDTH-50, int((WIDTH-100)/(num_points-1))) for y in range(50, HEIGHT-50, int((HEIGHT-100)/(num_points-1)))]
16
- original_points = touch_points.copy()
17
- velocities: List[Tuple[float, float]] = [(0.0, 0.0)] * len(touch_points)
18
- is_affected: List[bool] = [False] * len(touch_points)
19
-
20
- # Create pain and pleasure points
21
- pain_points = [(100, 100), (500, 500)]
22
- pleasure_points = [(300, 300), (200, 400)]
23
 
24
  # Set up the Hugging Face pipeline
25
  @st.cache_resource
@@ -34,50 +32,16 @@ st.title("Advanced Artificial Touch Simulation")
34
  # Create a Streamlit container for the touch simulation
35
  touch_container = st.container()
36
 
37
- def update_points():
38
- global touch_points, velocities, is_affected
39
-
40
- # Apply spring force
41
- for i, (x, y) in enumerate(touch_points):
42
- force_x = (original_points[i][0] - x) * ELASTICITY
43
- force_y = (original_points[i][1] - y) * ELASTICITY
44
- velocities[i] = (velocities[i][0] + force_x, velocities[i][1] + force_y)
45
-
46
- # Apply damping
47
- for i, (vx, vy) in enumerate(velocities):
48
- velocities[i] = (vx * DAMPING, vy * DAMPING)
49
-
50
- # Update position
51
- for i, (x, y) in enumerate(touch_points):
52
- vx, vy = velocities[i]
53
- touch_points[i] = (x + vx, y + vy)
54
-
55
- # Reset affected flags
56
- is_affected = [False] * len(touch_points)
57
-
58
  def calculate_sensation(x, y, pressure, duration):
59
- sensation = 0
60
- for px, py in pain_points:
61
- distance = np.sqrt((x - px)**2 + (y - py)**2)
62
- if distance < 50:
63
- sensation -= (50 - distance) * pressure * (duration ** 1.5) / 50
64
- for px, py in pleasure_points:
65
- distance = np.sqrt((x - px)**2 + (y - py)**2)
66
- if distance < 50:
67
- sensation += (50 - distance) * pressure / 50
68
- return sensation
69
-
70
- def on_tap(x, y, pressure, duration):
71
- global touch_points, velocities, is_affected
72
 
73
- for i, (tx, ty) in enumerate(touch_points):
74
- distance = ((tx - x)**2 + (ty - y)**2)**0.5
75
- if distance < 30:
76
- force_x = (tx - x) / distance
77
- force_y = (ty - y) / distance
78
- velocities[i] = (velocities[i][0] - force_x * 10 * pressure, velocities[i][1] - force_y * 10 * pressure)
79
- is_affected[i] = True
80
 
 
 
 
81
  sensation = calculate_sensation(x, y, pressure, duration)
82
 
83
  # Generate a description of the touch
@@ -87,53 +51,60 @@ def on_tap(x, y, pressure, duration):
87
  prompt = f"The user touched the screen at ({x:.2f}, {y:.2f}) with a pressure of {pressure:.2f} for {duration:.2f} seconds, resulting in a sensation of {sensation:.2f}. Describe the experience:"
88
  text = text_generator(prompt, max_length=100, num_return_sequences=1, do_sample=True, top_k=50, top_p=0.95, num_beams=1)[0]['generated_text']
89
  st.write(text)
90
-
91
- update_points()
92
 
93
  # Initialize session state
94
- if 'x' not in st.session_state:
95
- st.session_state.x = 0
96
- if 'y' not in st.session_state:
97
- st.session_state.y = 0
98
- if 'pressure' not in st.session_state:
99
- st.session_state.pressure = 1.0
100
- if 'duration' not in st.session_state:
101
- st.session_state.duration = 0.0
102
  if 'touch_start_time' not in st.session_state:
103
  st.session_state.touch_start_time = None
 
 
104
 
105
  # Main app logic
106
  fig, ax = plt.subplots(figsize=(6, 6))
107
- ax.set_xlim(0, WIDTH)
108
- ax.set_ylim(0, HEIGHT)
109
-
110
- for i, (x, y) in enumerate(touch_points):
111
- color = "red" if is_affected[i] else "navy"
112
- ax.add_artist(plt.Circle((x, y), 5, color=color, alpha=0.5))
113
-
114
- for x, y in pain_points:
115
- ax.add_artist(plt.Circle((x, y), 10, color="red", alpha=0.3))
116
-
117
- for x, y in pleasure_points:
118
- ax.add_artist(plt.Circle((x, y), 10, color="green", alpha=0.3))
119
-
120
- touch_container.pyplot(fig)
121
-
122
- col1, col2 = st.columns(2)
123
- with col1:
124
- st.session_state.x = st.slider("X coordinate", 0, WIDTH, st.session_state.x)
125
- st.session_state.y = st.slider("Y coordinate", 0, HEIGHT, st.session_state.y)
126
- with col2:
127
- st.session_state.pressure = st.slider("Pressure", 0.1, 2.0, st.session_state.pressure)
128
-
129
- if touch_container.button("Start Touch"):
130
- st.session_state.touch_start_time = time.time()
131
-
132
- if touch_container.button("End Touch"):
133
- if st.session_state.touch_start_time is not None:
134
- st.session_state.duration = time.time() - st.session_state.touch_start_time
135
- on_tap(st.session_state.x, st.session_state.y, st.session_state.pressure, st.session_state.duration)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  st.session_state.touch_start_time = None
137
- st.session_state.duration = 0.0
138
 
139
- update_points()
 
 
3
  from typing import List, Tuple
4
  from transformers import pipeline
5
  import matplotlib.pyplot as plt
6
+ from matplotlib.backends.backend_agg import RendererAgg
7
+ from streamlit_drawable_canvas import st_canvas
8
  import time
9
 
10
  # Constants
 
12
  ELASTICITY = 0.3
13
  DAMPING = 0.7
14
 
15
+ # Create sensation map
16
+ sensation_map = np.zeros((HEIGHT, WIDTH))
17
+ for y in range(HEIGHT):
18
+ for x in range(WIDTH):
19
+ # Create a complex sensation map with various regions
20
+ sensation_map[y, x] = np.sin(x/30) * np.cos(y/30) * 5 + np.random.normal(0, 0.5)
 
 
 
 
21
 
22
  # Set up the Hugging Face pipeline
23
  @st.cache_resource
 
32
  # Create a Streamlit container for the touch simulation
33
  touch_container = st.container()
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  def calculate_sensation(x, y, pressure, duration):
36
+ # Get sensation from the map
37
+ base_sensation = sensation_map[int(y), int(x)]
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ # Modify sensation based on pressure and duration
40
+ modified_sensation = base_sensation * pressure * (1 + np.log(duration + 1))
 
 
 
 
 
41
 
42
+ return modified_sensation
43
+
44
+ def on_touch(x, y, pressure, duration):
45
  sensation = calculate_sensation(x, y, pressure, duration)
46
 
47
  # Generate a description of the touch
 
51
  prompt = f"The user touched the screen at ({x:.2f}, {y:.2f}) with a pressure of {pressure:.2f} for {duration:.2f} seconds, resulting in a sensation of {sensation:.2f}. Describe the experience:"
52
  text = text_generator(prompt, max_length=100, num_return_sequences=1, do_sample=True, top_k=50, top_p=0.95, num_beams=1)[0]['generated_text']
53
  st.write(text)
 
 
54
 
55
  # Initialize session state
 
 
 
 
 
 
 
 
56
  if 'touch_start_time' not in st.session_state:
57
  st.session_state.touch_start_time = None
58
+ if 'last_touch_position' not in st.session_state:
59
+ st.session_state.last_touch_position = None
60
 
61
  # Main app logic
62
  fig, ax = plt.subplots(figsize=(6, 6))
63
+ ax.imshow(sensation_map, cmap='coolwarm', extent=[0, WIDTH, HEIGHT, 0])
64
+ ax.axis('off')
65
+
66
+ # Use streamlit-drawable-canvas for interaction
67
+ canvas_result = st_canvas(
68
+ fill_color="rgba(255, 165, 0, 0.3)",
69
+ stroke_width=3,
70
+ stroke_color="#e00",
71
+ background_color="#eee",
72
+ background_image=fig,
73
+ update_streamlit=True,
74
+ height=HEIGHT,
75
+ width=WIDTH,
76
+ drawing_mode="point",
77
+ point_display_radius=0,
78
+ key="canvas",
79
+ )
80
+
81
+ # Handle touch events
82
+ if canvas_result.json_data is not None:
83
+ objects = canvas_result.json_data["objects"]
84
+ if len(objects) > 0:
85
+ last_object = objects[-1]
86
+ current_position = (last_object["left"], last_object["top"])
87
+
88
+ if st.session_state.touch_start_time is None:
89
+ st.session_state.touch_start_time = time.time()
90
+ st.session_state.last_touch_position = current_position
91
+ else:
92
+ # Calculate pressure based on movement
93
+ if st.session_state.last_touch_position is not None:
94
+ dx = current_position[0] - st.session_state.last_touch_position[0]
95
+ dy = current_position[1] - st.session_state.last_touch_position[1]
96
+ distance = np.sqrt(dx**2 + dy**2)
97
+ pressure = 1 + distance / 10 # Adjust this formula as needed
98
+ else:
99
+ pressure = 1.0
100
+
101
+ duration = time.time() - st.session_state.touch_start_time
102
+ on_touch(current_position[0], current_position[1], pressure, duration)
103
+
104
+ st.session_state.last_touch_position = current_position
105
+ else:
106
  st.session_state.touch_start_time = None
107
+ st.session_state.last_touch_position = None
108
 
109
+ st.write("Click and drag on the image to simulate touch. The color represents different sensations.")
110
+ st.write("Red areas are more sensitive (pain or intense pleasure), while blue areas are less sensitive.")