Referencia: Optica – Rayo reflejado en plano inclinado
Para el análisis de rayo reflejado en un perfil de terreno, se realiza calculando el punto reflejado para cada tramo del perfil usando como base el algoritmo de rayo reflejado en plano inclinado.

Instrucciones en Python
# rayo incidente y reflejado
# en perfil por tramos
# blog.espol.edu.ec/girni
import numpy as np
import matplotlib.pyplot as plt
# INGRESO
# posición de antenas tx, rx
xi = [1,11]
yi = [4,2]
# perfil suelo
sx = [1,4,8,11]
sy = [1,0.5,0.4,1]
# PROCEDIMIENTO
def reflejotramo(xi,yi,sx,sy):
# posición de antenas tx, rx
xa,xb = xi
ya,yb = yi
# perfil suelo
xas,xbs = sx
sa ,sb = sy
# pendiente de suelo
ms = (sb-sa)/(xbs-xas)
bs = sa-ms*xas
# punto de reflejo
numerador = bs*(xa+xb)-(xa*yb+xb*ya)+2*ms*xa*xb
denominador = 2*bs-(ya+yb)+ms*(xa+xb)
xc = numerador/denominador
sc = ms*xc+bs
reflejado = []
if xc>=xas and xc<=xbs:
reflejado = [xc,sc]
return(reflejado)
# analiza para cada tramo del suelo
n = len(sx)
xc = [] ; sc = []
for k in range(0,n-1,1):
sxk = sx[k:k+2] # un tramo de suelo
syk = sy[k:k+2]
reflejado = reflejotramo(xi,yi,sxk,syk)
if len(reflejado)>0:
xc.append(reflejado[0])
sc.append(reflejado[1])
# SALIDA
print('puntos reflejados:')
print('xc:',xc)
print('sc',sc)
# GRAFICA
# antenas puntos en el plano
plt.scatter([xi[0],xi[1]],
[yi[0],yi[1]],
label='antenas')
plt.plot([xi[0],xi[1]],
[yi[0],yi[1]],
color='green',
linestyle='dashed',
label='directo')
# analiza para cada tramo del suelo
nc = len(sc)
plt.scatter(xc,sc,color='orange',
label='punto reflejo')
# lineas de rayos
for k in range(0,nc,1):
# lado izquierdo
plt.plot([xi[0],xc[k]],
[yi[0],sc[k]],
color='blue',
linestyle='dashdot')
# lado derecho
plt.plot([xc[k],xi[1]],
[sc[k],yi[1]],
color='blue',
linestyle='dashdot')
# etiquetas anotadas
#plt.annotate(' reflejo',[xc,sc])
# perfil de suelo
plt.plot(sx,sy,color='brown',
label='perfil suelo')
# etiquetas
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.title('reflexión de rayos en suelo por tramos')
plt.grid()
plt.show()