blob: 3ecef40f8a60a5d9598b09572494c1f363142f2d [file] [log] [blame]
Tabitha Jarvis1007a132018-12-12 21:47:54 -08001#!/usr/bin/python3
Tabitha Jarvis1007a132018-12-12 21:47:54 -08002from __future__ import print_function
3import os
Andrew Runke0f945fd2019-01-27 21:10:37 -08004import sys
Andrew Runke6842bf92019-01-26 15:38:25 -08005import copy
Tabitha Jarvis1007a132018-12-12 21:47:54 -08006from color import Color, palette
7import random
8import gi
9import numpy as np
10import scipy.spatial.distance
11gi.require_version('Gtk', '3.0')
John Park91e69732019-03-03 13:12:43 -080012gi.require_version('Gdk', '3.0')
Andrew Runke6842bf92019-01-26 15:38:25 -080013from gi.repository import Gdk, Gtk, GLib
Tabitha Jarvis1007a132018-12-12 21:47:54 -080014import cairo
John Park91e69732019-03-03 13:12:43 -080015from libspline import Spline, DistanceSpline, Trajectory
Tabitha Jarvis1007a132018-12-12 21:47:54 -080016import enum
John Park91e69732019-03-03 13:12:43 -080017import json
18from basic_window import *
19from constants import *
20from drawing_constants import *
21from points import Points
22from graph import Graph
Andrew Runke6842bf92019-01-26 15:38:25 -080023
Tabitha Jarvis1007a132018-12-12 21:47:54 -080024
25class Mode(enum.Enum):
26 kViewing = 0
27 kPlacing = 1
28 kEditing = 2
29 kExporting = 3
30 kImporting = 4
Andrew Runke6842bf92019-01-26 15:38:25 -080031
32
John Park91e69732019-03-03 13:12:43 -080033class GTK_Widget(BaseWindow):
Andrew Runke6842bf92019-01-26 15:38:25 -080034 """Create a GTK+ widget on which we will draw using Cairo"""
Ravago Jones26f7ad02021-02-05 15:45:59 -080035
Tabitha Jarvis1007a132018-12-12 21:47:54 -080036 def __init__(self):
37 super(GTK_Widget, self).__init__()
38
John Park91e69732019-03-03 13:12:43 -080039 self.points = Points()
40
Tabitha Jarvis1007a132018-12-12 21:47:54 -080041 # init field drawing
42 # add default spline for testing purposes
43 # init editing / viewing modes and pointer location
44 self.mode = Mode.kPlacing
45 self.x = 0
46 self.y = 0
Andrew Runke0f945fd2019-01-27 21:10:37 -080047 module_path = os.path.dirname(os.path.realpath(sys.argv[0]))
48 self.path_to_export = os.path.join(module_path,
John Park91e69732019-03-03 13:12:43 -080049 'points_for_pathedit.json')
50
Tabitha Jarvis1007a132018-12-12 21:47:54 -080051 # update list of control points
52 self.point_selected = False
53 # self.adding_spline = False
54 self.index_of_selected = -1
55 self.new_point = []
56
57 # For the editing mode
Andrew Runke6842bf92019-01-26 15:38:25 -080058 self.index_of_edit = -1 # Can't be zero beause array starts at 0
Tabitha Jarvis1007a132018-12-12 21:47:54 -080059 self.held_x = 0
Andrew Runke6842bf92019-01-26 15:38:25 -080060 self.spline_edit = -1
Tabitha Jarvis1007a132018-12-12 21:47:54 -080061
Andrew Runke6842bf92019-01-26 15:38:25 -080062 self.curves = []
63
64 self.colors = []
65
66 for c in palette:
67 self.colors.append(palette[c])
68
Tabitha Jarvis1007a132018-12-12 21:47:54 -080069 self.reinit_extents()
70
Andrew Runke6842bf92019-01-26 15:38:25 -080071 self.inStart = None
72 self.inEnd = None
Andrew Runke6842bf92019-01-26 15:38:25 -080073 self.inValue = None
74 self.startSet = False
75
John Park909c0392020-03-05 23:56:30 -080076 self.module_path = os.path.dirname(os.path.realpath(sys.argv[0]))
77
Andrew Runke6842bf92019-01-26 15:38:25 -080078 """set extents on images"""
Ravago Jones26f7ad02021-02-05 15:45:59 -080079
Tabitha Jarvis1007a132018-12-12 21:47:54 -080080 def reinit_extents(self):
John Park91e69732019-03-03 13:12:43 -080081 self.extents_x_min = -1.0 * SCREEN_SIZE
82 self.extents_x_max = SCREEN_SIZE
83 self.extents_y_min = -1.0 * SCREEN_SIZE
84 self.extents_y_max = SCREEN_SIZE
Tabitha Jarvis1007a132018-12-12 21:47:54 -080085
86 # this needs to be rewritten with numpy, i dont think this ought to have
87 # SciPy as a dependecy
88 def get_index_of_nearest_point(self):
89 cur_p = [[self.x, self.y]]
90 distances = scipy.spatial.distance.cdist(cur_p, self.all_controls)
91
92 return np.argmin(distances)
93
94 # return the closest point to the loc of the click event
95 def get_nearest_point(self):
96 return self.all_controls[self.get_index_of_nearest_point()]
97
John Parka30a7782019-02-01 18:47:26 -080098 def draw_field_elements(self, cr):
Ravago Jones5f787df2021-01-23 16:26:27 -080099 if FIELD.year == 2019:
John Parkcf545162020-02-23 20:07:25 -0800100 draw_HAB(cr)
101 draw_rockets(cr)
102 draw_cargo_ship(cr)
Ravago Jones5f787df2021-01-23 16:26:27 -0800103 elif FIELD.year == 2020:
John Parkcf545162020-02-23 20:07:25 -0800104 set_color(cr, palette["BLACK"])
105 markers(cr)
106 draw_shield_generator(cr)
107 draw_trench_run(cr)
108 draw_init_lines(cr)
109 draw_control_panel(cr)
Ravago Jones5f787df2021-01-23 16:26:27 -0800110 elif FIELD.year == 2021:
111 draw_at_home_grid(cr)
John Parka30a7782019-02-01 18:47:26 -0800112
John Park91e69732019-03-03 13:12:43 -0800113 def draw_robot_at_point(self, cr, i, p, spline):
114 p1 = [mToPx(spline.Point(i)[0]), mToPx(spline.Point(i)[1])]
115 p2 = [mToPx(spline.Point(i + p)[0]), mToPx(spline.Point(i + p)[1])]
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800116
John Park91e69732019-03-03 13:12:43 -0800117 #Calculate Robot
118 distance = np.sqrt((p2[1] - p1[1])**2 + (p2[0] - p1[0])**2)
119 x_difference_o = p2[0] - p1[0]
120 y_difference_o = p2[1] - p1[1]
Ravago Jones5e09c072021-03-27 13:21:03 -0700121 x_difference = x_difference_o * mToPx(FIELD.robot.length / 2) / distance
122 y_difference = y_difference_o * mToPx(FIELD.robot.length / 2) / distance
John Park91e69732019-03-03 13:12:43 -0800123
124 front_middle = []
125 front_middle.append(p1[0] + x_difference)
126 front_middle.append(p1[1] + y_difference)
127
128 back_middle = []
129 back_middle.append(p1[0] - x_difference)
130 back_middle.append(p1[1] - y_difference)
131
132 slope = [-(1 / x_difference_o) / (1 / y_difference_o)]
133 angle = np.arctan(slope)
134
Ravago Jones5e09c072021-03-27 13:21:03 -0700135 x_difference = np.sin(angle[0]) * mToPx(FIELD.robot.width / 2)
136 y_difference = np.cos(angle[0]) * mToPx(FIELD.robot.width / 2)
John Park91e69732019-03-03 13:12:43 -0800137
138 front_1 = []
139 front_1.append(front_middle[0] - x_difference)
140 front_1.append(front_middle[1] - y_difference)
141
142 front_2 = []
143 front_2.append(front_middle[0] + x_difference)
144 front_2.append(front_middle[1] + y_difference)
145
146 back_1 = []
147 back_1.append(back_middle[0] - x_difference)
148 back_1.append(back_middle[1] - y_difference)
149
150 back_2 = []
151 back_2.append(back_middle[0] + x_difference)
152 back_2.append(back_middle[1] + y_difference)
153
154 x_difference = x_difference_o * mToPx(
Ravago Jones5e09c072021-03-27 13:21:03 -0700155 FIELD.robot.length / 2 + ROBOT_SIDE_TO_BALL_CENTER) / distance
John Park91e69732019-03-03 13:12:43 -0800156 y_difference = y_difference_o * mToPx(
Ravago Jones5e09c072021-03-27 13:21:03 -0700157 FIELD.robot.length / 2 + ROBOT_SIDE_TO_BALL_CENTER) / distance
John Park91e69732019-03-03 13:12:43 -0800158
159 #Calculate Ball
160 ball_center = []
161 ball_center.append(p1[0] + x_difference)
162 ball_center.append(p1[1] + y_difference)
163
164 x_difference = x_difference_o * mToPx(
Ravago Jones5e09c072021-03-27 13:21:03 -0700165 FIELD.robot.length / 2 + ROBOT_SIDE_TO_HATCH_PANEL) / distance
John Park91e69732019-03-03 13:12:43 -0800166 y_difference = y_difference_o * mToPx(
Ravago Jones5e09c072021-03-27 13:21:03 -0700167 FIELD.robot.length / 2 + ROBOT_SIDE_TO_HATCH_PANEL) / distance
John Park91e69732019-03-03 13:12:43 -0800168
169 #Calculate Panel
170 panel_center = []
171 panel_center.append(p1[0] + x_difference)
172 panel_center.append(p1[1] + y_difference)
173
174 x_difference = np.sin(angle[0]) * mToPx(HATCH_PANEL_WIDTH / 2)
175 y_difference = np.cos(angle[0]) * mToPx(HATCH_PANEL_WIDTH / 2)
176
177 panel_1 = []
178 panel_1.append(panel_center[0] + x_difference)
179 panel_1.append(panel_center[1] + y_difference)
180
181 panel_2 = []
182 panel_2.append(panel_center[0] - x_difference)
183 panel_2.append(panel_center[1] - y_difference)
184
185 #Draw Robot
186 cr.move_to(front_1[0], front_1[1])
187 cr.line_to(back_1[0], back_1[1])
188 cr.line_to(back_2[0], back_2[1])
189 cr.line_to(front_2[0], front_2[1])
190 cr.line_to(front_1[0], front_1[1])
191
192 cr.stroke()
193
194 #Draw Ball
195 set_color(cr, palette["ORANGE"], 0.5)
196 cr.move_to(back_middle[0], back_middle[1])
197 cr.line_to(ball_center[0], ball_center[1])
198 cr.arc(ball_center[0], ball_center[1], mToPx(BALL_RADIUS), 0,
199 2 * np.pi)
200 cr.stroke()
201
202 #Draw Panel
203 set_color(cr, palette["YELLOW"], 0.5)
204 cr.move_to(panel_1[0], panel_1[1])
205 cr.line_to(panel_2[0], panel_2[1])
206
207 cr.stroke()
208 cr.set_source_rgba(0, 0, 0, 1)
209
210 def handle_draw(self, cr): # main
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800211 # Fill the background color of the window with grey
John Park91e69732019-03-03 13:12:43 -0800212 set_color(cr, palette["WHITE"])
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800213 cr.paint()
214
215 # Draw a extents rectangle
216 set_color(cr, palette["WHITE"])
217 cr.rectangle(self.extents_x_min, self.extents_y_min,
218 (self.extents_x_max - self.extents_x_min),
219 self.extents_y_max - self.extents_y_min)
220 cr.fill()
221
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800222 cr.move_to(0, 50)
223 cr.show_text('Press "e" to export')
224 cr.show_text('Press "i" to import')
225
James Kuszmaul1c933e02020-03-07 16:17:51 -0800226 cr.save()
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800227 set_color(cr, palette["BLACK"])
Ravago Jones5f787df2021-01-23 16:26:27 -0800228
229 if FIELD.year == 2019: # half field
James Kuszmaul1c933e02020-03-07 16:17:51 -0800230 cr.rectangle(0, -SCREEN_SIZE / 2, SCREEN_SIZE, SCREEN_SIZE)
Ravago Jones5f787df2021-01-23 16:26:27 -0800231 else: # full field
232 cr.translate(mToPx(FIELD.width) / 2.0, 0.0)
233 cr.rectangle(-mToPx(FIELD.width) / 2.0, -mToPx(FIELD.length) / 2.0,
234 mToPx(FIELD.width), mToPx(FIELD.length))
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800235 cr.set_line_join(cairo.LINE_JOIN_ROUND)
236 cr.stroke()
John Parka30a7782019-02-01 18:47:26 -0800237 self.draw_field_elements(cr)
Ravago Jones5f787df2021-01-23 16:26:27 -0800238
Andrew Runke6842bf92019-01-26 15:38:25 -0800239 y = 0
Andrew Runke6842bf92019-01-26 15:38:25 -0800240
John Park91e69732019-03-03 13:12:43 -0800241 # update everything
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800242
John Park91e69732019-03-03 13:12:43 -0800243 if self.mode == Mode.kPlacing or self.mode == Mode.kViewing:
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800244 set_color(cr, palette["BLACK"])
John Park91e69732019-03-03 13:12:43 -0800245 cr.move_to(-SCREEN_SIZE, 170)
246 plotPoints = self.points.getPoints()
247 if plotPoints:
248 for i, point in enumerate(plotPoints):
John Park13d3e282019-01-26 20:16:48 -0800249 draw_px_x(cr, mToPx(point[0]), mToPx(point[1]), 10)
250 cr.move_to(mToPx(point[0]), mToPx(point[1]) - 15)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800251 display_text(cr, str(i), 0.5, 0.5, 2, 2)
John Park91e69732019-03-03 13:12:43 -0800252 set_color(cr, palette["WHITE"])
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800253
254 elif self.mode == Mode.kEditing:
255 set_color(cr, palette["BLACK"])
John Park91e69732019-03-03 13:12:43 -0800256 cr.move_to(-SCREEN_SIZE, 170)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800257 display_text(cr, "EDITING", 1, 1, 1, 1)
John Park91e69732019-03-03 13:12:43 -0800258 if self.points.getSplines():
259 self.draw_splines(cr)
260 for i, points in enumerate(self.points.getSplines()):
Andrew Runke6842bf92019-01-26 15:38:25 -0800261
John Park91e69732019-03-03 13:12:43 -0800262 p0 = np.array([mToPx(points[0][0]), mToPx(points[0][1])])
263 p1 = np.array([mToPx(points[1][0]), mToPx(points[1][1])])
264 p2 = np.array([mToPx(points[2][0]), mToPx(points[2][1])])
265 p3 = np.array([mToPx(points[3][0]), mToPx(points[3][1])])
266 p4 = np.array([mToPx(points[4][0]), mToPx(points[4][1])])
267 p5 = np.array([mToPx(points[5][0]), mToPx(points[5][1])])
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800268
John Park91e69732019-03-03 13:12:43 -0800269 draw_control_points(cr, [p0, p1, p2, p3, p4, p5])
270 first_tangent = p0 + 2.0 * (p1 - p0)
271 second_tangent = p5 + 2.0 * (p4 - p5)
272 cr.set_source_rgb(0, 0.5, 0)
273 cr.move_to(p0[0], p0[1])
274 cr.set_line_width(1.0)
275 cr.line_to(first_tangent[0], first_tangent[1])
276 cr.move_to(first_tangent[0], first_tangent[1])
277 cr.line_to(p2[0], p2[1])
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800278
John Park91e69732019-03-03 13:12:43 -0800279 cr.move_to(p5[0], p5[1])
280 cr.line_to(second_tangent[0], second_tangent[1])
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800281
John Park91e69732019-03-03 13:12:43 -0800282 cr.move_to(second_tangent[0], second_tangent[1])
283 cr.line_to(p3[0], p3[1])
284
285 cr.stroke()
286 cr.set_line_width(2.0)
287 self.points.update_lib_spline()
288 set_color(cr, palette["WHITE"])
289
290 cr.paint_with_alpha(0.2)
291
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800292 draw_px_cross(cr, self.x, self.y, 10)
James Kuszmaul1c933e02020-03-07 16:17:51 -0800293 cr.restore()
294 mygraph = Graph(cr, self.points)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800295
John Park91e69732019-03-03 13:12:43 -0800296 def draw_splines(self, cr):
297 holder_spline = []
298 for i, points in enumerate(self.points.getSplines()):
299 array = np.zeros(shape=(6, 2), dtype=float)
300 for j, point in enumerate(points):
301 array[j, 0] = point[0]
302 array[j, 1] = point[1]
303 spline = Spline(np.ascontiguousarray(np.transpose(array)))
304 for k in np.linspace(0.01, 1, 100):
Ravago Jones26f7ad02021-02-05 15:45:59 -0800305 cr.move_to(
306 mToPx(spline.Point(k - 0.01)[0]),
307 mToPx(spline.Point(k - 0.01)[1]))
308 cr.line_to(
309 mToPx(spline.Point(k)[0]), mToPx(spline.Point(k)[1]))
John Park91e69732019-03-03 13:12:43 -0800310 cr.stroke()
311 holding = [
312 spline.Point(k - 0.01)[0],
313 spline.Point(k - 0.01)[1]
314 ]
315 holder_spline.append(holding)
316 if i == 0:
317 self.draw_robot_at_point(cr, 0.00, 0.01, spline)
318 self.draw_robot_at_point(cr, 1, 0.01, spline)
319 self.curves.append(holder_spline)
320
321 def mouse_move(self, event):
322 old_x = self.x
323 old_y = self.y
Ravago Jones5f787df2021-01-23 16:26:27 -0800324 self.x = event.x - mToPx(FIELD.width / 2.0)
John Park91e69732019-03-03 13:12:43 -0800325 self.y = event.y
James Kuszmaul1c933e02020-03-07 16:17:51 -0800326 dif_x = self.x - old_x
327 dif_y = self.y - old_y
John Park91e69732019-03-03 13:12:43 -0800328 difs = np.array([pxToM(dif_x), pxToM(dif_y)])
329
330 if self.mode == Mode.kEditing:
James Kuszmaulb33b07c2021-02-25 22:39:24 -0800331 self.points.updates_for_mouse_move(
John Park91e69732019-03-03 13:12:43 -0800332 self.index_of_edit, self.spline_edit, self.x, self.y, difs)
333
John Park909c0392020-03-05 23:56:30 -0800334 def export_json(self, file_name):
Ravago Jones09f59722021-03-03 21:11:41 -0800335 self.path_to_export = os.path.join(
336 self.module_path, # position of the python
337 "../../..", # root of the repository
338 get_json_folder(FIELD), # path from the root
339 file_name # selected file
340 )
John Park909c0392020-03-05 23:56:30 -0800341 if file_name[-5:] != ".json":
342 print("Error: Filename doesn't end in .json")
343 else:
344 # Will export to json file
345 self.mode = Mode.kEditing
Ravago Jones3b92afa2021-02-05 14:27:32 -0800346
347 multi_spline = self.points.toMultiSpline()
348 print(multi_spline)
John Park909c0392020-03-05 23:56:30 -0800349 with open(self.path_to_export, mode='w') as points_file:
Ravago Jones3b92afa2021-02-05 14:27:32 -0800350 json.dump(multi_spline, points_file)
John Park909c0392020-03-05 23:56:30 -0800351
352 def import_json(self, file_name):
Ravago Jones09f59722021-03-03 21:11:41 -0800353 self.path_to_export = os.path.join(
354 self.module_path, # position of the python
355 "../../..", # root of the repository
356 get_json_folder(FIELD), # path from the root
357 file_name # selected file
358 )
359
John Park909c0392020-03-05 23:56:30 -0800360 if file_name[-5:] != ".json":
361 print("Error: Filename doesn't end in .json")
362 else:
363 # import from json file
364 self.mode = Mode.kEditing
James Kuszmaul1c933e02020-03-07 16:17:51 -0800365 print("LOADING LOAD FROM " + file_name) # Load takes a few seconds
John Park909c0392020-03-05 23:56:30 -0800366 with open(self.path_to_export) as points_file:
Ravago Jones3b92afa2021-02-05 14:27:32 -0800367 multi_spline = json.load(points_file)
John Park909c0392020-03-05 23:56:30 -0800368
Ravago Jones3b92afa2021-02-05 14:27:32 -0800369 # if people messed with the spline json,
370 # it might not be the right length
371 # so give them a nice error message
Ravago Jones09f59722021-03-03 21:11:41 -0800372 try: # try to salvage as many segments of the spline as possible
Ravago Jones3b92afa2021-02-05 14:27:32 -0800373 self.points.fromMultiSpline(multi_spline)
374 except IndexError:
375 # check if they're both 6+5*(k-1) long
376 expected_length = 6 + 5 * (multi_spline["spline_count"] - 1)
377 x_len = len(multi_spline["spline_x"])
378 y_len = len(multi_spline["spline_x"])
379 if x_len is not expected_length:
Ravago Jones09f59722021-03-03 21:11:41 -0800380 print(
381 "Error: spline x values were not the expected length; expected {} got {}"
382 .format(expected_length, x_len))
Ravago Jones3b92afa2021-02-05 14:27:32 -0800383 elif y_len is not expected_length:
Ravago Jones09f59722021-03-03 21:11:41 -0800384 print(
385 "Error: spline y values were not the expected length; expected {} got {}"
386 .format(expected_length, y_len))
Ravago Jones3b92afa2021-02-05 14:27:32 -0800387
John Park909c0392020-03-05 23:56:30 -0800388 print("SPLINES LOADED")
389
John Park91e69732019-03-03 13:12:43 -0800390 def do_key_press(self, event, file_name):
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800391 keyval = Gdk.keyval_to_lower(event.keyval)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800392 if keyval == Gdk.KEY_q:
393 print("Found q key and exiting.")
394 quit_main_loop()
John Park909c0392020-03-05 23:56:30 -0800395 if keyval == Gdk.KEY_e:
396 export_json(file_name)
John Park91e69732019-03-03 13:12:43 -0800397
John Park909c0392020-03-05 23:56:30 -0800398 if keyval == Gdk.KEY_i:
399 import_json(file_name)
John Park91e69732019-03-03 13:12:43 -0800400
Andrew Runke6842bf92019-01-26 15:38:25 -0800401 if keyval == Gdk.KEY_p:
402 self.mode = Mode.kPlacing
403 # F0 = A1
404 # B1 = 2F0 - E0
405 # C1= d0 + 4F0 - 4E0
John Park91e69732019-03-03 13:12:43 -0800406 spline_index = len(self.points.getSplines()) - 1
407 self.points.resetPoints()
408 self.points.extrapolate(
409 self.points.getSplines()[len(self.points.getSplines()) - 1][5],
410 self.points.getSplines()[len(self.points.getSplines()) - 1][4],
411 self.points.getSplines()[len(self.points.getSplines()) - 1][3])
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800412
413 def button_press_action(self):
Andrew Runke6842bf92019-01-26 15:38:25 -0800414 if self.mode == Mode.kPlacing:
John Park91e69732019-03-03 13:12:43 -0800415 if self.points.add_point(self.x, self.y):
416 self.mode = Mode.kEditing
Andrew Runke6842bf92019-01-26 15:38:25 -0800417 elif self.mode == Mode.kEditing:
418 # Now after index_of_edit is not -1, the point is selected, so
419 # user can click for new point
420 if self.index_of_edit > -1 and self.held_x != self.x:
John Park91e69732019-03-03 13:12:43 -0800421 self.points.setSplines(self.spline_edit, self.index_of_edit,
422 pxToM(self.x), pxToM(self.y))
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800423
James Kuszmaulb33b07c2021-02-25 22:39:24 -0800424 self.points.splineExtrapolate(self.spline_edit)
Andrew Runke6842bf92019-01-26 15:38:25 -0800425
Andrew Runke6842bf92019-01-26 15:38:25 -0800426 self.index_of_edit = -1
427 self.spline_edit = -1
428 else:
Andrew Runke6842bf92019-01-26 15:38:25 -0800429 # Get clicked point
430 # Find nearest
431 # Move nearest to clicked
John Park13d3e282019-01-26 20:16:48 -0800432 cur_p = [pxToM(self.x), pxToM(self.y)]
Andrew Runke6842bf92019-01-26 15:38:25 -0800433 # Get the distance between each for x and y
434 # Save the index of the point closest
John Park13d3e282019-01-26 20:16:48 -0800435 nearest = 1 # Max distance away a the selected point can be in meters
Andrew Runke6842bf92019-01-26 15:38:25 -0800436 index_of_closest = 0
James Kuszmaul1c933e02020-03-07 16:17:51 -0800437 for index_splines, points in enumerate(
438 self.points.getSplines()):
Andrew Runke6842bf92019-01-26 15:38:25 -0800439 for index_points, val in enumerate(points):
Andrew Runke6842bf92019-01-26 15:38:25 -0800440 distance = np.sqrt((cur_p[0] - val[0])**2 +
441 (cur_p[1] - val[1])**2)
442 if distance < nearest:
443 nearest = distance
444 index_of_closest = index_points
445 print("Nearest: " + str(nearest))
446 print("Index: " + str(index_of_closest))
447 self.index_of_edit = index_of_closest
448 self.spline_edit = index_splines
449 self.held_x = self.x
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800450
451 def do_button_press(self, event):
John Park13d3e282019-01-26 20:16:48 -0800452 # Be consistent with the scaling in the drawing_area
Ravago Jones5f787df2021-01-23 16:26:27 -0800453 self.x = event.x * 2 - mToPx(FIELD.width / 2.0)
Andrew Runkea9c8de52019-01-26 19:54:29 -0800454 self.y = event.y * 2
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800455 self.button_press_action()