Je suis en train d'étudier la possibilité de créer un algorithme de coulée d'ombre simple pour un petit jeu 2D. Autant que possible, je voudrais essayer moi-même avant d'utiliser des librairies optimisées. Je me sens comme je suis presque là mais pour une raison quelconque, la méthode que j'utilise pour détecter l'intersection entre le rayon de ma source de ligne et un segment (de chaque côté d'un obstacle ou bord d'écran) ne semble pas capturer tous les collisions.Intersection entre deux segments L'algorithme passe à côté des intersections
Je ai réduit l'erreur à cette fonction, mais je ne trouve pas l'erreur en elle. Je l'ai traversé de nombreuses fois et n'arrive toujours pas à comprendre pourquoi cela ne fonctionne pas toujours. Tous mes rayons sortent de l'écran et je devrais au moins détecter une collision avec les bords de l'écran. J'ai également vérifié que l'algorithme circulait dans tous les rayons et segments.
C'est la méthode de vérification des collisions:
def check_col(self, ray, source):
'''
segment1 = (self.start,self.end)
segment2 = (source.pos,ray.far_pt)'''
X1,Y1 = self.start #start pt of segment 1
X2,Y2 = self.end #end pt of segment 1
X3,Y3 = source.pos #start pt of segment 2
X4,Y4 = ray.far_pt #end pt of segment 2
'''we are looking to express the segments as:
A*x + b = y '''
'''ensuring mutual abscisse exists'''
if (max(X1,X2) < min(X3,X4)) or (min(X1,X2) > max(X3,X4))\
or (max(Y1,Y2) < min(Y3,Y4)) or (min(Y1,Y2) > max(Y3,Y4)):
return False,0 #no mutual abscisse, 0 added to return a tulpe
'''ensures no division by 0
when calculating the segment
slopes A1 and A2'''
if float(X1-X2) == 0:
X1 +=0.1 #add a small increment to avoid difference to be null
if float(X3-X4) == 0:
X3 += 0.1 #add a small increment to avoid difference to be null
'''calculating segment slopes'''
A1 = (Y1-Y2)/float(X1-X2) # Pay attention to not dividing by zero
A2 = (Y3-Y4)/float(X3-X4) # Pay attention to not dividing by zero
b1 = Y1-A1*X1# = Y2-A1*X2
b2 = Y3-A2*X3# = Y4-A2*X4
'''if slopes are the same, offsets one slightly
to avoid dividing by 0 later on'''
if (A1 == A2):
A1 += 0.0001
'''finding out intersect between the two segments at (Xa,Ya)'''
#A1 * Xa + b1 = A2 * Xa + b2
Xa = int((b2 - b1)/(A1 - A2))# Once again, pay attention to not dividing by zero
Ya = int(A1 * Xa + b1)
#Ya = int(A2 * Xa + b2)
col_pt = (Xa,Ya)
'''make sure intersection is within bounds'''
if max(min(X1,X2),min(X3,X4)) <= Xa <= min(max(X1,X2),max(X3,X4)):
'''calculates distance between the light source and the collision point'''
dist = sqrt((source.pos[0]-col_pt[0])**2+(source.pos[1]-col_pt[1])**2)
return True,col_pt,dist
else:
return False,0 #0 added to return a tulpe
Et voici une capture d'écran montrant que certains rayons ne sont pas entrer en collision avec l'obstacle bleu ou le mur quand ils doivent clairement: