Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Angle Collisions
#41
(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!
Reply
#42
(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:
Reply
#43
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
Reply
#44
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
Reply
#45
(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
Reply
#46
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
Reply
#47
(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!
Reply
#48
(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:
Reply
#49
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
Reply
#50
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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Angle difference bplus 8 1,623 01-31-2023, 10:32 PM
Last Post: OldMoses

Forum Jump:


Users browsing this thread: 1 Guest(s)