Маги c не задействованы. Просто перевод из (0,0) в (x1, y1) и поворот на угол, определяемый dx и dy. Синус этого угла равен dy / L, а косинус dx / L. Использование numpy массивов удобно для написания функции - это краткая форма, а также ускорение вычислений.
В приведенном ниже коде я изменил пример функции, чтобы сделать ее более понятной как функция преобразуется. Кроме того, соотношение сторон установлено равным. В противном случае повернутая функция будет выглядеть искаженной.
import matplotlib.pyplot as plt
import numpy as np
def foo(x):
# some function on [0, L]
return np.sin(x*20)/(x+1)
def function_on_new_axis(foo, point1, point2):
"""
Plot foo from point1 to point2
:param foo: function
:param point1: tuple (x1, y1) or list [x1, y1]
:param point2: tuple (x2, y2) or list [x2, y2]
:return:
"""
# create modified function along new local x' axis using points in initial x,y axis?
# create new axis, rotate and move them?
dx = x2 - x1
dy = y2 - y1
L = np.sqrt(dx * dx + dy * dy)
XI = np.linspace(0, L, 500) # initial coordinate system
YI = foo(XI)
s = dy / L # sine of the rotation angle
c = dx / L # cosine of the rotation angle
XM = c * XI - s * YI + x1 # modified coordinate system
YM = s * XI + c * YI + y1
plt.plot(XI, YI, color='crimson', alpha=0.3)
plt.plot(XM, YM, color='crimson')
plt.plot([x1, x2], [y1, y2], 'go')
x1, y1 = 1, 1 # first point coordinates
x2, y2 = 2, 3 # second point coordinates
fig, ax = plt.subplots()
function_on_new_axis(foo, (x1,y1), (x2, y2))
ax.axis('equal') # equal aspect ratio between x and y axis to prevent that the function would look skewed
# show the axes at (0,0)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
plt.show()