I need to visualize the tilting of a 3D object.
The formular for the X-axis is:
((Δ Edge_2 + Δ Edge_1) – (Δ Edge_4 + Δ Edge_3) ) / (2*length between the edges)
for the y-axis it is:
((Δ Edge_3 + Δ Edge_1) – (Δ Edge_2 + Δ Edge_2) ) / (2*length between the edges)
but it seems like there is a bend in the volume ( in the middle)
Furthermore I also want to visualize the tilt on the XZ and the YZ plane.
HELP !!!
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
def create_3d_box(ax, corners_bottom, corners_top, color, alpha=0.6, edge_color=None, top_edge_color=None):
# Definiere die Ecken für jede Fläche des Würfels
vertices = [
[corners_bottom[0], corners_bottom[1], corners_top[1], corners_top[0]], # Vorderseite
[corners_bottom[1], corners_bottom[2], corners_top[2], corners_top[1]], # Rechte Seite
[corners_bottom[2], corners_bottom[3], corners_top[3], corners_top[2]], # Rückseite
[corners_bottom[3], corners_bottom[0], corners_top[0], corners_top[3]], # Linke Seite
[corners_top[0], corners_top[1], corners_top[2], corners_top[3]], # Oberseite
[corners_bottom[0], corners_bottom[1], corners_bottom[2], corners_bottom[3]] # Unterseite
]
box = Poly3DCollection(vertices, facecolors=color, linewidths=1, edgecolors=edge_color, alpha=alpha)
ax.add_collection3d(box)
if top_edge_color:
edges_top = [
[corners_top[0], corners_top[1]], [corners_top[1], corners_top[2]],
[corners_top[2], corners_top[3]], [corners_top[3], corners_top[0]]
]
edge_collection_top = Line3DCollection(edges_top, colors=top_edge_color, linewidths=1.5)
ax.add_collection3d(edge_collection_top)
def extract_indices_above_threshold(df, column, threshold, buffer_size=8):
values = df[column]
indices = set()
buffer_indices = []
for i, value in enumerate(values):
if value > threshold:
for idx in buffer_indices:
indices.add(idx)
indices.add(i)
buffer_indices = []
else:
buffer_indices.append(i)
if len(buffer_indices) > buffer_size:
buffer_indices.pop(0)
return sorted(indices)
def clear_axis(ax):
for collection in ax.collections:
collection.remove()
for line in ax.lines:
line.remove()
# Lade die CSV-Datei
df = pd.read_csv(r'C:UsersStudentDownloadsAutopresstraining_datacsvWerkzeug falsch verbautVersuchstag_20231214Autopress_2023-12-14_08-36-28_140357.csv')
# Extrahiere Indizes mit Werten über dem Schwellenwert und 8 davor
threshold = 9
indices = extract_indices_above_threshold(df, 'Berührungswerte', threshold, buffer_size=8)
# Finde den Index, bei dem die Berührungswerte erstmals den Schwellenwert überschreiten
first_exceed_index = None
for i, value in enumerate(df['Berührungswerte']):
if value > threshold:
first_exceed_index = i
break
if first_exceed_index is not None:
# Ignoriere das erste Mal, wenn der Schwellenwert überschritten wird
indices = [i for i in indices if i > first_exceed_index]
# Initialisiere Variablen zur Verfolgung der maximalen Verkippung
max_inclination_x = -float('inf')
max_inclination_y = -float('inf')
max_inclination_index = -1
max_inclination_time = None
diff_sensors = {}
# Erstelle eine neue Figur und 3D-Achsen
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Setze die Hintergrundfarbe des Koordinatensystems
ax.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
# Definiere das Zentrum des Koordinatensystems
center_x = 0
center_y = 0
center_z = 0
# Erstelle das hellgraue Volumen von z=-20 bis z=0
corners_bottom_gray = np.array([
[-95/2, -73/2, 0],
[95/2, -73/2, 0],
[95/2, 73/2, 0],
[-95/2, 73/2, 0]
], dtype=float)
corners_top_gray = np.array([
[-95/2, -73/2, 20],
[95/2, -73/2, 20],
[95/2, 73/2, 20],
[-95/2, 73/2, 20]
], dtype=float)
# Definiere das "Tisch"-Volumen bei z=-50
corners_bottom_tisch = np.array([
[-95/2, -73/2, -50],
[95/2, -73/2, -50],
[95/2, 73/2, -50],
[-95/2, 73/2, -50]
], dtype=float)
corners_top_tisch = np.array([
[-95/2, -73/2, -45],
[95/2, -73/2, -45],
[95/2, 73/2, -45],
[-95/2, 73/2, -45]
], dtype=float)
# Erstelle die Volumen für die 8 Zeilen vor dem Überschreiten des Schwellenwerts
for i in range(max(0, first_exceed_index - 8), first_exceed_index):
clear_axis(ax)
create_3d_box(ax, corners_bottom=corners_bottom_gray, corners_top=corners_top_gray,
color='snow', alpha=0.2, edge_color=None, top_edge_color='grey')
create_3d_box(ax, corners_bottom=corners_bottom_tisch, corners_top=corners_top_tisch,
color='gainsboro', alpha=0.2, edge_color=None)
ver1 = ver2 = ver3 = ver4 = 0
diff_z = np.array([0, 0, 0, 0])
current_corners_bottom_anim = np.array([
[-95/2, -73/2, 0],
[95/2, -73/2, 0],
[95/2, 73/2, 0],
[-95/2, 73/2, 0]
], dtype=float)
current_corners_top_anim = np.array([
[-95/2, -73/2, 20],
[95/2, -73/2, 20],
[95/2, 73/2, 20],
[-95/2, 73/2, 20]
], dtype=float)
create_3d_box(ax, corners_bottom=current_corners_bottom_anim, corners_top=current_corners_top_anim,
color='lightgray', alpha=0.8, edge_color=None)
ax.set_xlabel('X in mm/m')
ax.set_ylabel('Y in mm/m')
ax.set_zlabel('Z')
ax.set_xlim([-50, 50])
ax.set_ylim([-50, 50])
ax.set_zlim([-60, 60])
ax.grid(False)
ax.set_xticks(np.arange(-50, 51, 25))
ax.set_yticks(np.arange(-50, 51, 25))
ax.set_zticks([])
ax.set_title(f"Zeit: {df.at[i, 'Zeit']}")
# Füge die Achsenlinien durch den Ursprung hinzu
ax.plot([-50, 50], [0, 0], [-60, -60], color='black', linestyle='-', linewidth=1.5) # X-Achse
ax.plot([0, 0], [-50, 50], [-60, -60], color='black', linestyle='-', linewidth=1.5) # Y-Achse
# ax.plot([0, 0], [0, 0], [-60, 60], color='black', linestyle='-', linewidth=1.5) # Z-Achse
plt.pause(0.5)
# Iteriere durch alle relevanten Indizes zur Visualisierung
for idx in sorted(set(indices)):
clear_axis(ax)
create_3d_box(ax, corners_bottom=corners_bottom_gray, corners_top=corners_top_gray,
color='aliceblue', alpha=0.2, edge_color='aliceblue')
create_3d_box(ax, corners_bottom=corners_bottom_tisch, corners_top=corners_top_tisch,
color='gainsboro', alpha=0.5, edge_color='None')
ver1 = df.at[idx, 'Verkippung_1']
ver2 = df.at[idx, 'Verkippung_2']
ver3 = df.at[idx, 'Verkippung_3']
ver4 = df.at[idx, 'Verkippung_4']
# Berechnung der Neigung um die X-Achse gemäß der Formel
diff_ver1 = ver1 - ver2
diff_ver2 = ver2 - ver3
diff_ver3 = ver3 - ver4
diff_ver4 = ver4 - ver1
inclination_x = ((diff_ver1 + diff_ver2) - (diff_ver3 + diff_ver4)) / (2 * 74.5)
# Berechnung der Neigung um die Y-Achse gemäß der Formel
inclination_y = ((diff_ver1 + diff_ver3) - (diff_ver2 + diff_ver4)) / (2 * 95)
# Berechnung der Differenz der Z-Werte
diff_z = np.array([
(ver2 - ver4) * 30,
(ver1 - ver3) * 30,
(ver2 - ver1) * 30,
(ver4 - ver3) * 30
])
current_corners_bottom_anim = np.array([
[-95/2, -73/2, diff_z[0]],
[95/2, -73/2, diff_z[1]],
[95/2, 73/2, diff_z[2]],
[-95/2, 73/2, diff_z[3]]
], dtype=float)
current_corners_top_anim = np.array([
[-95/2, -73/2, 20 + diff_z[0]],
[95/2, -73/2, 20 + diff_z[1]],
[95/2, 73/2, 20 + diff_z[2]],
[-95/2, 73/2, 20 + diff_z[3]]
], dtype=float)
create_3d_box(ax, corners_bottom=current_corners_bottom_anim, corners_top=current_corners_top_anim,
color='lightgray', alpha=0.8, edge_color=None, top_edge_color='gray')
ax.set_xlabel('X in mm/m')
ax.set_ylabel('Y in mm/m')
ax.set_zlabel('Z')
ax.set_xlim([-50, 50])
ax.set_ylim([-50, 50])
ax.set_zlim([-60, 60])
ax.grid(False)
ax.set_xticks(np.arange(-50, 51, 25))
ax.set_yticks(np.arange(-50, 51, 25))
ax.set_zticks([])
ax.set_title(f"Zeit: {df.at[idx, 'Zeit']}")
# Füge die Achsenlinien durch den Ursprung hinzu
ax.plot([-50, 50], [0, 0], [-60, -60], color='black', linestyle='-', linewidth=1.5) # X-Achse
ax.plot([0, 0], [-50, 50], [-60, -60], color='black', linestyle='-', linewidth=1.5) # Y-Achse
# ax.plot([0, 0], [0, 0], [-60, 60], color='black', linestyle='-', linewidth=1.5) # Z-Achse
plt.pause(0.1)
# Aktualisiere die maximalen Neigungen
if inclination_x > max_inclination_x:
max_inclination_x = inclination_x
if inclination_y > max_inclination_y:
max_inclination_y = inclination_y
max_inclination_index = idx
max_inclination_time = df.at[idx, 'Zeit']
diff_sensors = {
"Sensor_1 - Sensor_2 (X)": abs((ver1 - ver2) * 30),
"Sensor_1 - Sensor_3 (Y)": abs((ver1 - ver3) * 30),
"Sensor_1 - Sensor_4 (Z)": abs((ver1 - ver4) * 30),
"Sensor_2 - Sensor_3 (X)": abs((ver2 - ver3) * 30),
"Sensor_2 - Sensor_4 (Y)": abs((ver2 - ver4) * 30),
"Sensor_3 - Sensor_4 (Z)": abs((ver3 - ver4) * 30),
}
# Zeige die Plot mit der maximalen Verkippung an
clear_axis(ax)
create_3d_box(ax, corners_bottom=corners_bottom_gray, corners_top=corners_top_gray,
color='aliceblue', alpha=0.2, edge_color='aliceblue')
create_3d_box(ax, corners_bottom=corners_bottom_tisch, corners_top=corners_top_tisch,
color='gainsboro', alpha=0.5, edge_color=None)
ver1 = df.at[max_inclination_index, 'Verkippung_1']
ver2 = df.at[max_inclination_index, 'Verkippung_2']
ver3 = df.at[max_inclination_index, 'Verkippung_3']
ver4 = df.at[max_inclination_index, 'Verkippung_4']
diff_z = np.array([
(ver2 - ver4) * 30,
(ver1 - ver3) * 30,
(ver2 - ver1) * 30,
(ver4 - ver3) * 30
])
# Berechnung der Neigung um die X-Achse
diff_ver1 = ver1 - ver2
diff_ver2 = ver2 - ver3
diff_ver3 = ver3 - ver4
diff_ver4 = ver4 - ver1
inclination_x = ((diff_ver1 + diff_ver2) - (diff_ver3 + diff_ver4)) / (2 * 74.5)
# Berechnung der Neigung um die Y-Achse
inclination_y = ((diff_ver1 + diff_ver3) - (diff_ver2 + diff_ver4)) / (2 * 95)
current_corners_bottom_anim = np.array([
[-95/2, -73/2, diff_z[0]],
[95/2, -73/2, diff_z[1]],
[95/2, 73/2, diff_z[2]],
[-95/2, 73/2, diff_z[3]]
], dtype=float)
current_corners_top_anim = np.array([
[-95/2, -73/2, 20 + diff_z[0]],
[95/2, -73/2, 20 + diff_z[1]],
[95/2, 73/2, 20 + diff_z[2]],
[-95/2, 73/2, 20 + diff_z[3]]
], dtype=float)
create_3d_box(ax, corners_bottom=current_corners_bottom_anim, corners_top=current_corners_top_anim,
color='lightgray', alpha=0.8, edge_color=None, top_edge_color='gray')
ax.set_xlabel('X in mm/m')
ax.set_ylabel('Y in mm/m')
ax.set_zlabel('Z')
ax.set_xlim([-50, 50])
ax.set_ylim([-50, 50])
ax.set_zlim([-60, 60])
ax.grid(False)
ax.set_xticks(np.arange(-50, 51, 25))
ax.set_yticks(np.arange(-50, 51, 25))
ax.set_zticks([])
ax.set_title(f"Maximale VerkippungnZeit: {max_inclination_time} ms")
# Füge die Sensorunterschiede als Textannotation unterhalb des Plots hinzu
sensor_diffs_text = "n".join(f"{k}: {v:.2f} mm/m" for k, v in diff_sensors.items())
fig.text(0.5, -0.1, sensor_diffs_text, ha='center', va='top', fontsize=10, bbox=dict(boxstyle="round,pad=0.3", edgecolor="black", facecolor=None))
# Füge die Achsenlinien durch den Ursprung hinzu
ax.plot([-50, 50], [0, 0], [-60, -60], color='black', linestyle='-', linewidth=1.5) # X-Achse
ax.plot([0, 0], [-50, 50], [-60, -60], color='black', linestyle='-', linewidth=1.5) # Y-Achse
# ax.plot([0, 0], [0, 0], [-60, 60], color='black', linestyle='-', linewidth=1.5) # Z Achse
plt.show()