1

I tried a math formula from analytic geometry but I didn't get the desired results.

As you can see in the code, the user draw two lines and a green circle(point of intersection) appear.

I have tried to fix the problem for hours but I failed. Sometimes the point doesn't appear or appear but in the wrong position.

Source of the formula I used in the code

Docs of pygame the library I used

#!/usr/bin/env python from pygame import * from time import sleep init(); win = display.set_mode((500,500)); lines = [] cords = [] preview = False xi = -100 yi = -100 def drawlines(flines): for fcords in flines: draw.line(win,(0,0,0),fcords[0],fcords[1],4) while True: win.fill((255,255,255)) for ev in event.get(): if ev.type == QUIT: quit(); exit(); elif ev.type == MOUSEBUTTONDOWN: if ev.button == 1: preview = True a = mouse.get_pos() cords.append(mouse.get_pos()) elif ev.type == MOUSEBUTTONUP: if ev.button == 1: cords.append(mouse.get_pos()) lines.append((cords)) cords = [] preview = False ######################################## THIS BROKEN PART ################################# if len(lines) == 2: #line 1 points_line1 = lines[0] point1_line1 = points_line1[0] point2_line1 = points_line1[1] line1_vector = (point2_line1[0]-point1_line1[0],point2_line1[1]-point1_line1[1]) a_line1 = line1_vector[1] b_line1 = -line1_vector[0] c_line1 = -((a_line1*point1_line1[0]) + (b_line1*point1_line1[1])) #line2 points_line2 = lines[1] point1_line2 = points_line2[0] point2_line2 = points_line2[1] line2_vector = (point2_line2[0]-point1_line2[0],point2_line2[1]-point1_line2[1]) a_line2 = line2_vector[1] b_line2 = -line2_vector[0] c_line2 = -((a_line2*point1_line2[0]) + (b_line2*point1_line2[1])) if (a_line2 != 0 and b_line2 != 0): if (a_line1 / a_line2) != ( b_line1/b_line2): #intersection between line1 and line2 yi = ((((a_line1*c_line2) / a_line2) + c_line1) / -b_line1) xi = (((-b_line1*yi)-c_line1) / a_line1) ########################################################################################### elif preview: draw.line(win,(0,0,0),a,mouse.get_pos(),4) drawlines(lines) draw.circle(win,(0,200,0),(int(xi),int(yi)),10) display.flip() 
1

1 Answer 1

3

It's hard to dig through your code. Especially c_line1 = -((a_line1*point1_line1[0]) + (b_line1*point1_line1[1])) seems to be odd, because it calculates the Dot product of vector and a point.
Therefore I don't know exactly what's wrong with your code, but I know how to intersect lines. See Problem with calculating line intersections and Collision and Intersection - Line and line.

Write functions that can add, subtract, scale vectors and rotate vectors by 90°. Write a function which calculates the Dot product:

def add(a, b): return a[0]+b[0], a[1]+b[1] def sub(a, b): return a[0]-b[0], a[1]-b[1] def rot90(v): return -v[1], v[0] def mul(v, s): return v[0]*s, v[1]*s def dot(a, b): return a[0]*b[0] + a[1]*b[1] 

Calculate the vector from the beginning of the lines to the end of the lines and the normal vectors to the lines. The normal vector is obtained by rotating the line vector by 90°:

#line 1 point1_line1, point2_line1 = lines[0] line1_vector = sub(point2_line1, point1_line1) line1_norml = rot90(line1_vector) #line2 point1_line2, point2_line2 = lines[1] line2_vector = sub(point2_line2, point1_line2) line2_norml = rot90(line2_vector) 

Calculate the intersection of the line segments. Make sure the lines are not parallel and that the intersection point is on the line segments:

# vector from start point of line 2 to start point of line 1 l2p1_l1p1 = sub(point1_line1, point1_line2) # intersection d = dot(line2_vector, line1_norml) if d != 0: # prallel lines t = dot(l2p1_l1p1, line1_norml) / d u = dot(l2p1_l1p1, line2_norml) / d if 0 <= t <= 1 and 0 <= u <= 1: # intersection on line segments xi, yi = add(point1_line2, mul(line2_vector, t)) 

Minimal example:

from pygame import * init() win = display.set_mode((500,500)) lines = [] cords = [] preview = False xi, yi = -100, -100 def drawlines(flines): for fcords in flines: draw.line(win,(0,0,0),fcords[0],fcords[1],4) def add(a, b): return a[0]+b[0], a[1]+b[1] def sub(a, b): return a[0]-b[0], a[1]-b[1] def rot90(v): return -v[1], v[0] def mul(v, s): return v[0]*s, v[1]*s def dot(a, b): return a[0]*b[0] + a[1]*b[1] run = True while run: for ev in event.get(): if ev.type == QUIT: run = False elif ev.type == MOUSEBUTTONDOWN: if ev.button == 1: preview = True a = ev.pos cords.append(a) elif ev.type == MOUSEBUTTONUP: if ev.button == 1: cords.append(ev.pos) lines.append((cords)) cords = [] preview = False intersections = [] for i, line1 in enumerate(lines): for line2 in lines[i+1:]: #line 1 point1_line1, point2_line1 = line1 line1_vector = sub(point2_line1, point1_line1) line1_norml = rot90(line1_vector) #line2 point1_line2, point2_line2 = line2 line2_vector = sub(point2_line2, point1_line2) line2_norml = rot90(line2_vector) # vector from start point of line 2 to start point of line 1 l2p1_l1p1 = sub(point1_line1, point1_line2) # intersection d = dot(line2_vector, line1_norml) if d != 0: # prallel lines t = dot(l2p1_l1p1, line1_norml) / d u = dot(l2p1_l1p1, line2_norml) / d if 0 <= t <= 1 and 0 <= u <= 1: # intersection on line segments xi, yi = add(point1_line2, mul(line2_vector, t)) intersections.append((xi, yi)) win.fill((255,255,255)) if len(cords) % 2 == 1: draw.line(win,(0,0,0), a, mouse.get_pos(), 4) drawlines(lines) for p in intersections: draw.circle(win, (0,200,0), (round(p[0]), round(p[1])), 10) display.flip() quit() exit() 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.