import cv2
import numpy as np
import math
def proj(x1, y1, x2, y2, xp, yp):
x12 = x2 - x1
y12 = y2 - y1
dotp = x12 * (xp - x1) + y12 * (yp - y1)
dot12 = x12 * x12 + y12 * y12
if dot12:
coeff = dotp / dot12
lx = x1 + x12 * coeff
ly = y1 + y12 * coeff
return np.int(lx), np.int(ly)
else:
return None
def perpendicular_finder(line, point):
x1, y1 = line[0]
x2, y2 = line[1]
x3, y3 = point
if ((y2 - y1) ^ 2 + (x2 - x1) ^ 2) !=0:
k = ((y2 - y1) * (x3 - x1) - (x2 - x1) * (y3 - y1)) / ((y2 - y1) ^ 2 + (x2 - x1) ^ 2)
x4 = x3 - k * (y2 - y1)
y4 = y3 + k * (x2 - x1)
x4 = np.int(x4)
y4 = np.int(y4)
return x4,y4
cnt = 0
ballCircle = (200, 200)
purBall = (540,300)
cueX1 = 200
cueY1 = 200
cueX2 = 400
cueY2 = 400
count = 0
while True:
if count < 400:
cueX2 -= 1
elif count < 800:
cueY2 -= 1
elif count < 1200:
cueX2 += 1
else:
cueY2 += 1
if count == 1600:
count = 0
else:
count += 1
cueX2 = cueX1 + int(500 * math.cos(cnt / 1000))
cueY2 = cueY1 + int(500 * math.sin(cnt / 1000))
cueX3 = cueX1 - int(500 * math.cos(cnt / 1000))
cueY3 = cueY1 - int(500 * math.sin(cnt / 1000))
cnt += 1
blank = np.zeros((500, 900, 3), np.uint8) # Create canvas the size of table
#kek = perpendicular_finder((ballCircle, (cueX2,cueY2)), purBall)
kek = proj(ballCircle[0], ballCircle[1], cueX2, cueY2, purBall[0], purBall[1])
cv2.line(blank, purBall, kek, (0, 255, 255), 1) # good path
cv2.circle(blank, ballCircle, 10, (255, 255, 255), -1) # Ball
cv2.circle(blank, purBall, 10, (0, 255, 255), -1) # Purple Ball
cv2.arrowedLine(blank, (cueX1, cueY1), (cueX2, cueY2), (255, 255, 255), 3) # Cue
cv2.arrowedLine(blank, (cueX1, cueY1), (cueX3, cueY3), (100, 100, 100), 2) # Cue
cv2.circle(blank, kek, 10, (0, 0, 255), -1) # Ball
cv2.imshow("kk", blank)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
aW1wb3J0IGN2MgppbXBvcnQgbnVtcHkgYXMgbnAKaW1wb3J0IG1hdGgKCgpkZWYgcHJvaih4MSwgeTEsIHgyLCB5MiwgeHAsIHlwKToKICAgIHgxMiA9IHgyIC0geDEKICAgIHkxMiA9IHkyIC0geTEKICAgIGRvdHAgPSB4MTIgKiAoeHAgLSB4MSkgKyB5MTIgKiAoeXAgLSB5MSkKICAgIGRvdDEyID0geDEyICogeDEyICsgeTEyICogeTEyCiAgICBpZiBkb3QxMjoKICAgICAgICBjb2VmZiA9IGRvdHAgLyBkb3QxMgogICAgICAgIGx4ID0geDEgKyB4MTIgKiBjb2VmZgogICAgICAgIGx5ID0geTEgKyB5MTIgKiBjb2VmZgogICAgICAgIHJldHVybiBucC5pbnQobHgpLCBucC5pbnQobHkpCiAgICBlbHNlOgogICAgICAgIHJldHVybiBOb25lCgoKZGVmIHBlcnBlbmRpY3VsYXJfZmluZGVyKGxpbmUsIHBvaW50KToKICAgIHgxLCB5MSA9IGxpbmVbMF0KICAgIHgyLCB5MiA9IGxpbmVbMV0KICAgIHgzLCB5MyA9IHBvaW50CiAgICBpZiAoKHkyIC0geTEpIF4gMiArICh4MiAtIHgxKSBeIDIpICE9MDoKICAgICAgICBrID0gKCh5MiAtIHkxKSAqICh4MyAtIHgxKSAtICh4MiAtIHgxKSAqICh5MyAtIHkxKSkgLyAoKHkyIC0geTEpIF4gMiArICh4MiAtIHgxKSBeIDIpCiAgICAgICAgeDQgPSB4MyAtIGsgKiAoeTIgLSB5MSkKICAgICAgICB5NCA9IHkzICsgayAqICh4MiAtIHgxKQogICAgICAgIHg0ID0gbnAuaW50KHg0KQogICAgICAgIHk0ID0gbnAuaW50KHk0KQoKICAgICAgICByZXR1cm4geDQseTQKCgpjbnQgPSAwCgpiYWxsQ2lyY2xlID0gKDIwMCwgMjAwKQpwdXJCYWxsID0gKDU0MCwzMDApCmN1ZVgxID0gMjAwCmN1ZVkxID0gMjAwCmN1ZVgyID0gNDAwCmN1ZVkyID0gNDAwCmNvdW50ID0gMAp3aGlsZSBUcnVlOgogICAgaWYgY291bnQgPCA0MDA6CiAgICAgICAgY3VlWDIgLT0gMQogICAgZWxpZiBjb3VudCA8IDgwMDoKICAgICAgICBjdWVZMiAtPSAxCiAgICBlbGlmIGNvdW50IDwgMTIwMDoKICAgICAgICBjdWVYMiArPSAxCiAgICBlbHNlOgogICAgICAgIGN1ZVkyICs9IDEKICAgIGlmIGNvdW50ID09IDE2MDA6CiAgICAgICAgY291bnQgPSAwCiAgICBlbHNlOgogICAgICAgIGNvdW50ICs9IDEKCiAgICBjdWVYMiA9IGN1ZVgxICsgaW50KDUwMCAqIG1hdGguY29zKGNudCAvIDEwMDApKQogICAgY3VlWTIgPSBjdWVZMSArIGludCg1MDAgKiBtYXRoLnNpbihjbnQgLyAxMDAwKSkKICAgIGN1ZVgzID0gY3VlWDEgLSBpbnQoNTAwICogbWF0aC5jb3MoY250IC8gMTAwMCkpCiAgICBjdWVZMyA9IGN1ZVkxIC0gaW50KDUwMCAqIG1hdGguc2luKGNudCAvIDEwMDApKQogICAgY250ICs9IDEKCiAgICBibGFuayA9IG5wLnplcm9zKCg1MDAsIDkwMCwgMyksIG5wLnVpbnQ4KSAgIyBDcmVhdGUgY2FudmFzIHRoZSBzaXplIG9mIHRhYmxlCgogICAgI2tlayA9IHBlcnBlbmRpY3VsYXJfZmluZGVyKChiYWxsQ2lyY2xlLCAoY3VlWDIsY3VlWTIpKSwgcHVyQmFsbCkKICAgIGtlayA9IHByb2ooYmFsbENpcmNsZVswXSwgYmFsbENpcmNsZVsxXSwgY3VlWDIsIGN1ZVkyLCBwdXJCYWxsWzBdLCBwdXJCYWxsWzFdKQoKICAgIGN2Mi5saW5lKGJsYW5rLCBwdXJCYWxsLCBrZWssICgwLCAyNTUsIDI1NSksIDEpICAjIGdvb2QgcGF0aAogICAgY3YyLmNpcmNsZShibGFuaywgYmFsbENpcmNsZSwgMTAsICgyNTUsIDI1NSwgMjU1KSwgLTEpICAjIEJhbGwKICAgIGN2Mi5jaXJjbGUoYmxhbmssIHB1ckJhbGwsIDEwLCAoMCwgMjU1LCAyNTUpLCAtMSkgICMgUHVycGxlIEJhbGwKICAgIGN2Mi5hcnJvd2VkTGluZShibGFuaywgKGN1ZVgxLCBjdWVZMSksIChjdWVYMiwgY3VlWTIpLCAoMjU1LCAyNTUsIDI1NSksIDMpICAjIEN1ZQogICAgY3YyLmFycm93ZWRMaW5lKGJsYW5rLCAoY3VlWDEsIGN1ZVkxKSwgKGN1ZVgzLCBjdWVZMyksICgxMDAsIDEwMCwgMTAwKSwgMikgICMgQ3VlCiAgICBjdjIuY2lyY2xlKGJsYW5rLCBrZWssIDEwLCAoMCwgMCwgMjU1KSwgLTEpICAjIEJhbGwKCiAgICBjdjIuaW1zaG93KCJrayIsIGJsYW5rKQogICAgaWYgY3YyLndhaXRLZXkoMSkgJiAweEZGID09IG9yZCgncScpOgogICAgICAgIGJyZWFrCmN2Mi5kZXN0cm95QWxsV2luZG93cygp