Created
October 6, 2024 15:23
-
-
Save colonelpanic8/15e17782ab7a7d87b2ea55200a35deb0 to your computer and use it in GitHub Desktop.
Revisions
-
colonelpanic8 created this gist
Oct 6, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,117 @@ import math import matplotlib.pyplot as plt import numpy as np from matplotlib.widgets import Button, Slider def find_angle_of_vector_that_comes_within(distance, point, direction="left"): x_p, y_p = point if x_p != 0: theta_min = np.arctan2(y_p, x_p) else: theta_min = np.pi / 2 if y_p > 0 else -np.pi / 2 # Now, we need to adjust theta_min to achieve the exact specified distance # The current minimum distance is the perpendicular distance from (x_p, y_p) # to the line at theta_min current_distance = np.abs(np.sin(theta_min) * x_p - np.cos(theta_min) * y_p) # If the current distance is greater than the specified distance, adjust theta accordingly if current_distance != distance: theta_adjust = np.arcsin(distance / np.sqrt(x_p**2 + y_p**2)) if direction == "left": theta = theta_min + theta_adjust else: theta = theta_min - theta_adjust else: theta = theta_min # Calculate the point on the line that is exactly 'distance' away from the given point # The line passes through the point (x_p, y_p) and has the angle 'theta' if direction == "left": x_line = x_p - distance * np.sin(theta) y_line = y_p + distance * np.cos(theta) else: x_line = x_p + distance * np.sin(theta) y_line = y_p - distance * np.cos(theta) return theta, (x_line, y_line) def update_plot(val): x = x_slider.val y = y_slider.val distance = distance_slider.val ax.clear() ax.set_aspect("equal") ax.set_xlim(-10, 10) ax.set_ylim(-10, 10) ax.axhline(0, color="black", lw=0.5) ax.axvline(0, color="black", lw=0.5) # Plot the point based on x and y values ax.plot(x, y, "bo") # Compute the endpoint of the line originating from the origin try: theta, (point_x, point_y) = find_angle_of_vector_that_comes_within( distance, (x, y), direction ) ax.plot(point_x, point_y, "ro", label="Approach Point") end_x = math.cos(theta) * 30 end_y = math.sin(theta) * 30 start_x = math.cos(theta) * -30 start_y = math.sin(theta) * -30 # Plot the line from the origin to the endpoint ax.plot([start_x, end_x], [start_y, end_y], color="red") except ValueError: pass # Handle case where distance is too large for the given point fig.canvas.draw_idle() def toggle_direction(event): global direction direction = "right" if direction == "left" else "left" direction_button.label.set_text(f"Direction: {direction}") update_plot(None) # Set up the plot fig, ax = plt.subplots() plt.subplots_adjust(left=0.25, bottom=0.45) ax.set_aspect("equal") ax.set_xlim(-10, 10) ax.set_ylim(-10, 10) ax.axhline(0, color="black", lw=0.5) ax.axvline(0, color="black", lw=0.5) # Sliders for x, y, and distance ax_x = plt.axes([0.25, 0.25, 0.65, 0.03]) ax_y = plt.axes([0.25, 0.20, 0.65, 0.03]) ax_distance = plt.axes([0.25, 0.15, 0.65, 0.03]) x_slider = Slider(ax_x, "X", -10.0, 10.0, valinit=3.0) y_slider = Slider(ax_y, "Y", -10.0, 10.0, valinit=4.0) distance_slider = Slider(ax_distance, "Distance", 0.1, 10.0, valinit=5.0) # Button for toggling direction ax_button = plt.axes([0.4, 0.05, 0.2, 0.05]) direction_button = Button(ax_button, "Direction: left") direction_button.on_clicked(toggle_direction) # Initial direction direction = "left" # Update plot when sliders are changed x_slider.on_changed(update_plot) y_slider.on_changed(update_plot) distance_slider.on_changed(update_plot) # Initial plot update_plot(None) plt.show()