from kivymd.app import MDApp from kivymd.uix.label import MDLabel from kivymd.uix.screen import Screen from kivymd.uix.textfield import MDTextField from kivymd.uix.button import MDRectangleFlatButton from kivy.graphics import Color, Ellipse, Line from functools import partial # creating Demo Class(base class) class Demo(MDApp): def build(self): screen = Screen() self.canvas = screen.canvas self.start_x = None self.start_y = None self.current_color = (1, 0, 1, 1) # Set initial color index to 0 self.current_color_index = 0 # Set initial counter to 0 self.cross_counter = 0 # Create dictionary to store line segments for each color self.lines = {} # Use partial to specify the self argument when calling the event handlers screen.bind(on_touch_down=partial(self.on_touch_down), on_touch_up=partial(self.on_touch_up), on_touch_move=partial(self.on_touch_move)) l = MDLabel(text="0", halign='center', theme_text_color="Custom", pos_hint={"center_x": 0.3, "center_y": 0.3}, text_color=(0.5, 0, 0.5, 1), font_style='Caption') btn = MDRectangleFlatButton(text="ChangeColor", pos_hint={ 'center_x': 0.1, 'center_y': 0.1}, on_release=self.change_line_color) clear_btn = MDRectangleFlatButton(text="Clear", pos_hint={ 'center_x': 0.3, 'center_y': 0.1}, on_release=self.clear_canvas) # Create instance variables for the buttons and the label self.btn = btn self.clear_btn = clear_btn self.l = l screen.add_widget(btn) screen.add_widget(clear_btn) screen.add_widget(l) return screen def clear_canvas(self, instance): # Clear the widgets on the screen self.root.clear_widgets() # Clear the canvas self.canvas.clear() # Add the buttons and the label back to the screen self.root.add_widget(self.btn) self.root.add_widget(self.clear_btn) self.root.add_widget(self.l) def change_line_color(self, obj): # Define a list of colors to cycle through colors = [(0, 0, 3, 1), (0, 0, 0, 1), (1, 0, 0, 1), (0, 0, 1, 1)] # Increment the current color index self.current_color_index = (self.current_color_index + 1) % len(colors) # Set the current_color variable to the color at the current index self.current_color = colors[self.current_color_index] def draw_circle(self, center_x, center_y, radius, color): with self.canvas: Color(*color) Ellipse(pos=(center_x - radius, center_y - radius), size=(2 * radius, 2 * radius)) def draw_line(self, start_x, start_y, end_x, end_y): with self.canvas: # Set the color of the lines using the current_color variable Color(*self.current_color) line = Line(points=[start_x, start_y, end_x, end_y], width=1.8) def on_touch_down(self, instance, touch): self.start_x = touch.x self.start_y = touch.y def line_intersection(self, x1, y1, x2, y2, x3, y3, x4, y4): # Calculate the denominator of the equation den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) # Check if the lines are parallel if den == 0: return None # Calculate the intersection point t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den # Check if the intersection point is within both line segments if 0 <= t <= 1 and 0 <= u <= 1: return (x1 + t * (x2 - x1), y1 + t * (y2 - y1)) return None def on_touch_up(self, instance, touch): # Obtener las coordenadas de la nueva línea start_x, start_y, end_x, end_y = self.start_x, self.start_y, touch.x, touch.y # Recorrer todas las líneas almacenadas for color, lines in self.lines.items(): for line in lines: # Verificar si hay un punto de cruce entre la nueva línea y la línea actual intersect = self.line_intersection(start_x, start_y, end_x, end_y, *line) if intersect: # Si hay un punto de cruce, dibujar un círculo en esa posición self.draw_circle(*intersect, radius=7, color=self.current_color) # Dibujar la nueva línea self.draw_line(self.start_x, self.start_y, touch.x, touch.y) # Agregar la nueva línea al diccionario de líneas self.lines[self.current_color] = self.lines.get(self.current_color, []) + [(start_x, start_y, end_x, end_y)] def on_touch_move(self, instance, touch): print("counting...") if __name__ == "__main__": Demo().run()