Posts: 229
Threads: 25
Joined: Aug 2022
Reputation:
23
(10-18-2022, 03:27 PM)bplus Wrote: (10-18-2022, 03:57 AM)james2464 Wrote: Changed from arrow keys to mouse wheel for rotating the wall
Code: (Select All) 'vector reflection demo
'james2464
Screen _NewImage(800, 600, 32)
Const PI = 3.141592654#
Dim Shared x, y, h, dx, dy, nx, ny, na As Single
Dim c(10) As Long
c(0) = _RGB(30, 30, 30)
c(1) = _RGB(255, 255, 255)
c(2) = _RGB(255, 255, 0)
c(3) = _RGB(255, 0, 0)
'0,0 origin
xx = 400
yy = 300
Line (0, yy)-(800, yy), c(0)
Line (xx, 0)-(xx, 600), c(0)
x = 70: y = 90 'ball position
na = 60 'reflecting surface angle
flag = 0
Do
_Limit 10
Cls
'chip starting pos - using mouse
mouseclick1 = 0
Do While _MouseInput
na = na + _MouseWheel
Loop
mx% = _MouseX
my% = _MouseY
If mx% < xx - 400 Then mx% = xx - 400
If mx% > xx + 400 Then mx% = xx + 400
If my% < yy - 300 Then my% = yy - 300
If my% > yy + 300 Then my% = yy + 300
lc% = _MouseButton(1)
If lc% = -1 Then mouseclick1 = 1
x = 0 - xx + mx%
y = yy - my%
'origin lines
Line (0, yy)-(800, yy), c(0)
Line (xx, 0)-(xx, 600), c(0)
h = _Hypot(-x, y)
nx = Sin(na * (PI / 180)) 'normalize wall angle
ny = Cos(na * (PI / 180)) 'normalize wall angle
dx = -x * nx * -1: dy = y * ny: ndp = dx + dy
'dot product V.N - used to find distance of N
'The distance of N is from the point of origin to the middle of line A
'line A is a line from point I to point R (parallel to the angled wall)
ard = Sqr(h ^ 2 - ndp ^ 2) 'distance from mid point of line A to point R
w2x = ny * ard: w2y = nx * ard
u2x = nx * ndp: u2y = ny * ndp
rx = w2x + u2x: ry = w2y - u2y 'point R
Circle (xx + rx, yy + ry), 10, c(3) 'point R
Line (xx, yy)-(xx + rx, yy + ry), c(3) 'line from origin to point R
'angled wall
A = (Sin(na * (PI / 180))) * 200
B = (Cos(na * (PI / 180))) * 200
Line (xx, yy)-(xx + B, yy + A), c(1)
Line (xx, yy)-(xx - B, yy - A), c(1)
Circle (xx + x, yy - y), 10, c(2) 'point I
Line (xx, yy)-(xx + x, yy - y), c(2)
Locate 1, 1
Print "Vector Reflection"
Print "Use mouse wheel to rotate wall"
Locate 35, 1
Print "Wall angle:"; na
Locate 1, 70
Print "I ="; x; ","; y;
Locate 35, 70
Print "R ="; Int(rx); ","; Int(-ry)
_Display
Loop Until flag = 1
Nice app, I would have done it this way https://qb64phoenix.com/forum/showthread...74#pid8074
Yes indeed, that is excellent - thank you!
Posts: 315
Threads: 16
Joined: Apr 2022
Reputation:
43
(10-16-2022, 12:17 AM)james2464 Wrote: This video explains the reflection of a vector, but I don't know what 'n' is. At 10:27 he says "don't forget if n is unit length you know that n.n is 1 and you can cross that out". But there are still more n's in the formula and I can't figure out what they are supposed to represent. He just said n=1 !! Or n.n = 1 anyway. I just wish there were numbers involved instead of just letters. That would be a huge help.
https://youtu.be/naaeH1qbjdQ
I took a shot at doing a test bed program that uses the video procedure.
This is what I came up with, that is mostly vector based.
Code: (Select All) TYPE V2
x AS SINGLE
y AS SINGLE
END TYPE
DIM AS V2 wall, ball, reflec, orth, tempv
wall.x = -1: wall.y = 2
orth.x = -wall.y: orth.y = wall.x
SCREEN _NEWIMAGE(600, 600, 32) ' setup screen & display grid
WINDOW (-300, 300)-(300, -300)
DO UNTIL x% > 300
IF x% = 0 THEN c~& = &HFF00FF00 ELSE c~& = &H7F7F7F7F
LINE (-300, x%)-(300, x%), c~&
LINE (-300, -x%)-(300, -x%), c~&
LINE (x%, 300)-(x%, -300), c~&
LINE (-x%, 300)-(-x%, -300), c~&
x% = x% + 50
LOOP
back& = _COPYIMAGE(0)
DO
WHILE _MOUSEINPUT: WEND ' get inputs
ball.x = PMAP(_MOUSEX, 2): ball.y = PMAP(_MOUSEY, 3)
IF _KEYDOWN(18432) THEN ' up arrow
d! = _ATAN2(wall.y, wall.x)
d! = d! + (_PI / 180)
wall.x = COS(d!): wall.y = SIN(d!)
orth.x = -wall.y: orth.y = wall.x
END IF
IF _KEYDOWN(20480) THEN ' down arrow
d! = _ATAN2(wall.y, wall.x)
d! = d! - (_PI / 180)
wall.x = COS(d!): wall.y = SIN(d!)
orth.x = -wall.y: orth.y = wall.x
END IF
CLS
_PUTIMAGE , back&
R2_Norm wall, wall, 200 ' draw wall legs 200 long
R2_Norm orth, orth, 50 ' draw orthogonals 50 long
LINE (wall.x, wall.y)-(-wall.x, -wall.y)
LINE (orth.x, orth.y)-(-orth.x, -orth.y), &HFF0000FF
CIRCLE (ball.x, ball.y), 30 ' draw incoming ball & vector
LINE (ball.x, ball.y)-(0, 0)
R2_Norm orth, orth, 1 ' reset orthogonal to unit length
R2_Norm tempv, orth, DotP(ball, orth) * 2 ' get ball projection to orthogonal * 2
reflec.x = tempv.x - ball.x ' compute reflection vector
reflec.y = tempv.y - ball.y
LINE (0, 0)-(reflec.x, reflec.y), &HFFFF0000 ' move reflection to impact point
CIRCLE (reflec.x, reflec.y), 30, &HFFFF0000 ' show reflected ball
_LIMIT 100
_DISPLAY
LOOP UNTIL _KEYDOWN(27)
_FREEIMAGE back&
END
FUNCTION DotP (a AS V2, b AS V2)
DotP = a.x * b.x + a.y * b.y
END FUNCTION 'DotP
SUB R2_Norm (re AS V2, v AS V2, scalar AS INTEGER)
x! = v.x: y! = v.y
m! = _HYPOT(x!, y!)
IF m! = 0 THEN
re.x = 0: re.y = 0
ELSE
re.x = (x! / m!) * scalar
re.y = (y! / m!) * scalar
END IF
END SUB 'R2_Norm
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Posts: 4,707
Threads: 224
Joined: Apr 2022
Reputation:
322
Thumbs up! Works without a hitch, nice job!
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
Posts: 2,910
Threads: 305
Joined: Apr 2022
Reputation:
167
10-18-2022, 08:44 PM
(This post was last modified: 10-18-2022, 08:44 PM by Pete.)
Mark, did you ever get your balls ball unstuck? Your ball in the cave routine worked great, but like you stated, it eventually gets stuck, too. I think I ran it 5 or 10 minutes before that happened, and it got stuck in the same place as the pic you posted.
Pete
Posts: 4,707
Threads: 224
Joined: Apr 2022
Reputation:
322
10-18-2022, 10:10 PM
(This post was last modified: 10-18-2022, 10:17 PM by bplus.)
(10-18-2022, 08:44 PM)Pete Wrote: Mark, did you ever get your balls ball unstuck? Your ball in the cave routine worked great, but like you stated, it eventually gets stuck, too. I think I ran it 5 or 10 minutes before that happened, and it got stuck in the same place as the pic you posted.
Pete
I have been thinking of a hack for that, eg if x,y in same place for too long to just kick it off the normal angle for the line segment. Maybe if I do a pinball machine app...
BTW this morning I was revisiting my Pool app which does use a ton of vector stuff: https://qb64phoenix.com/forum/showthread...748#pid748
Old Moses got the perfect link for doing serious calculations, the rack breaks pretty darn well.
I know Pete just wants to talk about bplus balls, do you remember my first post in my little corner?
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
Posts: 2,910
Threads: 305
Joined: Apr 2022
Reputation:
167
Put my SAM routine to work for ya!
Code: (Select All) z = TIMER
DO
x = foo: y = foo2
IF oldx = x AND oldy = y THEN
IF z < TIMER THEN z = z - 86400 ' midnight adj.
IF z - TIMER > .2 THEN
' MOVE VARMINT!
z = TIMER
END IF
oldx = x: oldy = y
END IF
LOOP
Pete
Posts: 229
Threads: 25
Joined: Aug 2022
Reputation:
23
(10-18-2022, 08:20 PM)OldMoses Wrote: (10-16-2022, 12:17 AM)james2464 Wrote: This video explains the reflection of a vector, but I don't know what 'n' is. At 10:27 he says "don't forget if n is unit length you know that n.n is 1 and you can cross that out". But there are still more n's in the formula and I can't figure out what they are supposed to represent. He just said n=1 !! Or n.n = 1 anyway. I just wish there were numbers involved instead of just letters. That would be a huge help.
https://youtu.be/naaeH1qbjdQ
I took a shot at doing a test bed program that uses the video procedure.
This is what I came up with, that is mostly vector based.
Code: (Select All) TYPE V2
x AS SINGLE
y AS SINGLE
END TYPE
DIM AS V2 wall, ball, reflec, orth, tempv
wall.x = -1: wall.y = 2
orth.x = -wall.y: orth.y = wall.x
SCREEN _NEWIMAGE(600, 600, 32) ' setup screen & display grid
WINDOW (-300, 300)-(300, -300)
DO UNTIL x% > 300
IF x% = 0 THEN c~& = &HFF00FF00 ELSE c~& = &H7F7F7F7F
LINE (-300, x%)-(300, x%), c~&
LINE (-300, -x%)-(300, -x%), c~&
LINE (x%, 300)-(x%, -300), c~&
LINE (-x%, 300)-(-x%, -300), c~&
x% = x% + 50
LOOP
back& = _COPYIMAGE(0)
DO
WHILE _MOUSEINPUT: WEND ' get inputs
ball.x = PMAP(_MOUSEX, 2): ball.y = PMAP(_MOUSEY, 3)
IF _KEYDOWN(18432) THEN ' up arrow
d! = _ATAN2(wall.y, wall.x)
d! = d! + (_PI / 180)
wall.x = COS(d!): wall.y = SIN(d!)
orth.x = -wall.y: orth.y = wall.x
END IF
IF _KEYDOWN(20480) THEN ' down arrow
d! = _ATAN2(wall.y, wall.x)
d! = d! - (_PI / 180)
wall.x = COS(d!): wall.y = SIN(d!)
orth.x = -wall.y: orth.y = wall.x
END IF
CLS
_PUTIMAGE , back&
R2_Norm wall, wall, 200 ' draw wall legs 200 long
R2_Norm orth, orth, 50 ' draw orthogonals 50 long
LINE (wall.x, wall.y)-(-wall.x, -wall.y)
LINE (orth.x, orth.y)-(-orth.x, -orth.y), &HFF0000FF
CIRCLE (ball.x, ball.y), 30 ' draw incoming ball & vector
LINE (ball.x, ball.y)-(0, 0)
R2_Norm orth, orth, 1 ' reset orthogonal to unit length
R2_Norm tempv, orth, DotP(ball, orth) * 2 ' get ball projection to orthogonal * 2
reflec.x = tempv.x - ball.x ' compute reflection vector
reflec.y = tempv.y - ball.y
LINE (0, 0)-(reflec.x, reflec.y), &HFFFF0000 ' move reflection to impact point
CIRCLE (reflec.x, reflec.y), 30, &HFFFF0000 ' show reflected ball
_LIMIT 100
_DISPLAY
LOOP UNTIL _KEYDOWN(27)
_FREEIMAGE back&
END
FUNCTION DotP (a AS V2, b AS V2)
DotP = a.x * b.x + a.y * b.y
END FUNCTION 'DotP
SUB R2_Norm (re AS V2, v AS V2, scalar AS INTEGER)
x! = v.x: y! = v.y
m! = _HYPOT(x!, y!)
IF m! = 0 THEN
re.x = 0: re.y = 0
ELSE
re.x = (x! / m!) * scalar
re.y = (y! / m!) * scalar
END IF
END SUB 'R2_Norm
Works great! Thanks for giving this a go. I'm still trying to figure it out but I think I'll get there. Right now I'm trying to get the full 360 degree rotation but I did get the reflection to work at least. Cheers!
Posts: 315
Threads: 16
Joined: Apr 2022
Reputation:
43
(10-18-2022, 10:47 PM)james2464 Wrote: [quote pid="8096" dateline="1666124430"]
Works great! Thanks for giving this a go. I'm still trying to figure it out but I think I'll get there. Right now I'm trying to get the full 360 degree rotation but I did get the reflection to work at least. Cheers!
[/quote]
It was giving me a screwy result until I realized that the orthogonal vector had to be a unit length before applying the dot product calculation. After that the diagonal of the parallelogram was the proper length for obtaining the reflecting vector.
I was pleasantly surprised that dot product handles either side of the reflecting wall perfectly and...
it doesn't matter which orthogonal is constructed...
both...
orth.x = -wall.y: orth.y = wall.x
and...
orth.x = wall.y: orth.y = -wall.x
work exactly the same. I originally thought there would be a difference. I might be starting to get the hang of this stuff.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Posts: 229
Threads: 25
Joined: Aug 2022
Reputation:
23
I finally got it. Had to make use of _ATAN2 and that made a huge difference. I didn't know what it meant but it's a great command for this. Without using degrees it captures the radian value of any x,y position and you can add and subtract these radian values to get a reflection. That makes this simple. I threw out most of my code once I got this concept going.
Code: (Select All) 'vector reflection demo
'james2464
Screen _NewImage(800, 600, 32)
Const PI = 3.141592654#
Dim c(10) As Long
c(0) = _RGB(30, 30, 30)
c(1) = _RGB(255, 255, 255)
c(2) = _RGB(255, 255, 0)
c(3) = _RGB(255, 0, 0)
c(4) = _RGB(0, 255, 0)
c(5) = _RGB(0, 255, 255)
'0,0 origin
xx = 400
yy = 300
na = 45 'wall starting angle (mouse wheel controlled)
flag = 0
Do
_Limit 50
Cls
'=====================================================
mouseclick1 = 0
Do While _MouseInput
na = na + _MouseWheel * 5
Loop
mx% = _MouseX
my% = _MouseY
If mx% < xx - 400 Then mx% = xx - 400
If mx% > xx + 400 Then mx% = xx + 400
If my% < yy - 300 Then my% = yy - 300
If my% > yy + 300 Then my% = yy + 300
lc% = _MouseButton(1)
If lc% = -1 Then mouseclick1 = 1
x = 0 - xx + mx%
y = yy - my%
'=====================================================
h = _Hypot(-x, y)
'=====================================================
'origin lines
Line (0, yy)-(800, yy), c(0)
Line (xx, 0)-(xx, 600), c(0)
'=====================================================
'angled wall
a = (Sin(na * .017453292)) * 200
b = (Cos(na * .017453292)) * 200
Line (xx, yy)-(xx + b, yy + a), c(1)
Line (xx, yy)-(xx - b, yy - a), c(1)
'=====================================================
Circle (xx + x, yy - y), 10, c(2) 'point I
Line (xx, yy)-(xx + x, yy - y), c(2) 'line from origin to point I
'=====================================================
nx = Cos(na * (PI / 180)) 'normalize wall angle
ny = Sin(na * (PI / 180)) 'normalize wall angle
dx = -x * ny * -1: dy = y * nx: ndp = dx + dy
'dot product V.N - used to find distance of N
'The distance of N is from the point of origin to the middle of line A
'line A is a line from point I to point R (parallel to the angled wall)
ndpx = Sin(na * (PI / 180)) * ndp
ndpy = Cos(na * (PI / 180)) * ndp
'=====================================================
'calculate point R
th1 = _Atan2(-y, x) 'radian value of ball (point I)
th2 = _Atan2(-ndpy, ndpx) 'radian value of line N
thd = th1 - th2 'find difference
th3 = th2 - thd 'subtract difference from line N
rx = Cos(th3) * h: ry = Sin(th3) * h 'point R position - th3 * length of point I to origin
Circle (xx + rx, yy + ry), 10, c(3) 'point R
Line (xx, yy)-(xx + rx, yy + ry), c(3) 'origin to point R
_Display
Loop Until flag = 1
Posts: 4,707
Threads: 224
Joined: Apr 2022
Reputation:
322
Congrats James,
Looks like you've worked it out for yourself.
And dang if I haven't found another AAU (Aliens among us).
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
|