'how to make code check all boundrys that can ray cast hit and it returns the closest boundry
So I was working in python Tkinter to do raycasting when I faced this problem I have solved the problem with the "if statement", but I made a feature to create boundaries so that made the "if statement" useless
The code (i have actually edited and tried to fix it and it didn't work so i will show the original here)
import tkinter as tk
import numpy
root = tk.Tk()
cv = tk.Canvas(root,bg = "black",height = "900" ,width="1020")
cv.pack()
def raycast(boundrys,x3,y3,x4,y4):
for i in boundrys:
x1 = i[0]
y1 = i[1]
x2 = i[2]
y2 = i[3]
den = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
if den == 0:
return None
t = ((x1-x3)*(y3-y4)- (y1-y3)*(x3-x4)) / den
u = -((x1-x2)*(y3-y3)- (y1-y2)*(x1-x3)) / den
if t>=0 and t<=1 and u >=0 and u<=1 :
x = x1 + t * (x2-x1)
y = y1 + t * (y2-y1)
return x,y
def create_circle(x, y, r, canvasName): #center coordinates, radius
x0 = x - r
y0 = y - r
x1 = x + r
y1 = y + r
return canvasName.create_oval(x0, y0, x1, y1,fill="black",width=5)
#def redraw(event):
# cv.delete("all")
#
# msx = event.x - 250
# msy = event.y - 250
# mag = (msx*msx + msy*msy) ** 0.5
# x4 = (msx/mag*length)+250
# y4 = (msy/mag*length)+250
# print(x4-250,y4-250)
# cv.create_line(250, 250, x4,y4, fill="red")
# cv.create_line(400,100,400,400)
# if raycast(400,100,400,400,250,250,x4,y4) != None:
# create_circle(raycast(400,100,400,400,250,250,x4,y4)[0],raycast(400,100,400,400,250,250,x4,y4)[1],5,cv)
def redraw(event):
cv.delete("all")
length = 100
for i in data:
x = cv.create_line(i[0],i[1],i[2],i[3],fill="red")
for x in range(0,360):
Line1=cv.create_line(450,550,450,700, fill="red")
Line2=cv.create_line(500,200,500,550, fill="blue")
boundry = [[500,200,500,550],[450,550,450,700]] + data
angle = numpy.radians(x)
line_length = 300
msx = event.x
msy = event.y
end_x = msx + line_length * numpy.cos(angle)
end_y = msy + line_length * numpy.sin(angle)
if not raycast(boundry,msx,msy,end_x,end_y):
cv.create_line(msx,msy,end_x,end_y, fill="white")
else:
x = cv.create_line(msx,msy,raycast(boundry,msx,msy,end_x,end_y)[0],raycast(boundry,msx,msy,end_x,end_y)[1],fill="white")
# Define a function to draw the line between two points
def cleanData():
data = []
def draw_line(event):
global click_num
global x1,y1
if click_num==0:
x1=event.x
y1=event.y
click_num=1
else:
x2=event.x
y2=event.y
click_num=0
data.append([x1,y1,x2,y2])
click_num=0
data = []
cv.bind("<Motion>",redraw)
cv.bind("<Button-1>",draw_line)
cv.bind("<Button-2>",cleanData)
root.mainloop()
i have tried this but it didn't work
def raycast(boundrys,x3,y3,x4,y4):
Total = len(boundrys)
result = []
Filtered=[]
for i in boundrys:
x1 = i[0]
y1 = i[1]
x2 = i[2]
y2 = i[3]
den = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
if den == 0:
return None
t = ((x1-x3)*(y3-y4)- (y1-y3)*(x3-x4)) / den
u = -((x1-x2)*(y3-y3)- (y1-y2)*(x1-x3)) / den
if t>=0 and t<=1 and u >=0 and u<=1 :
x = x1 + t * (x2-x1)
y = y1 + t * (y2-y1)
result.append([x,y,t,u])
if len(result) > 1 :
print(result)
for i in result:
Filtered.append(i[2] + i [3])
Boundry = Filtered.index(min(Filtered))
return result[Boundry]
elif len(result) == 1:
return result[0][0],result[0][1]
What is the problem? :
[enter image description here][1]
as u see, Instead of returning the x,y of the place the ray cast ends it returned another x,y for the line next to the line that the ray cast should end [enter image description here] [1]: https://i.stack.imgur.com/3H0FB.jpg
*Why is this happening? This happens because of the structure of the code so going back to the code
this is the boundry array : boundry = [[500,200,500,550],[450,550,450,700]] + data this is the "For loop" for all boundrys in ray casting:
for i in boundrys:
x1 = i[0]
y1 = i[1]
x2 = i[2]
y2 = i[3]
den = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
if den == 0:
return None
t = ((x1-x3)*(y3-y4)- (y1-y3)*(x3-x4)) / den
u = -((x1-x2)*(y3-y3)- (y1-y2)*(x1-x3)) / den
if t>=0 and t<=1 and u >=0 and u<=1 :
x = x1 + t * (x2-x1)
y = y1 + t * (y2-y1)
return x,y
so let us simulate the code: so the code will check if there's raycasting if there's raycasting it will instantly return without saying if there's a line that it should be ray cast than the line it should land in
End so to solve this we need to do some kind of for loop and see if there's another end for this ray cast and then do some things and reveal the truth (There's more than 3 boundries)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
