Author Topic: rerotating math problem  (Read 3524 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
rerotating math problem
« on: June 26, 2020, 12:20:28 pm »
Hi !
I have a math problem with Philipines2 that I haven’t been able to solve from the beginning. I slipped over it because it wasn’t important so far, but it would be nice if it worked now. Perception of objects. Smallest unit is the rectangle. I enter this into the system by latitude, height, length, body center coordinates, and rotation angles.
When I perceive, I rotate my own coordinates negatively relative to the body, and from there I can determine with smaller or larger relations whether I am in the given rectangle or not.
DE!
This only works correctly if I only use 1 rotation. However, if I use rotation in all 3 coordinate planes, it does not sense well.
I’m slowly smashing my head into the wall because I can’t figure it out.
I tried to decipher it to the smallest element and ran into a problem.
My question:
What should I vary in the formula to get the original values ​​back when I rotate it ???
Thank you for your effort!

Code: QB64: [Select]
  1. origox = 0
  2. origoy = 0
  3. origoz = 0
  4. x = 10
  5. y = 10
  6. z = 10
  7. rotatingx = 20 * 3.141592 / 180
  8. rotatingy = 45 * 3.141592 / 180
  9. rotatingz = 20 * 3.141592 / 180
  10.  
  11. 'ROTATING
  12. px = x - origox
  13. py = y - origoy
  14. pz = z - origoz
  15. PRINT "original coordinates:"; px, py, pz
  16. rotx = rotatingx
  17. roty = rotatingy
  18. rotz = rotatingz
  19.  
  20. px2 = (px * COS(rotz)) - (py * SIN(rotz))
  21. py2 = (px * SIN(rotz)) + (py * COS(rotz))
  22. px3 = (px2 * COS(roty)) - (pz * SIN(roty))
  23. pz2 = (px2 * SIN(roty)) + (pz * COS(roty))
  24. py3 = (py2 * COS(rotx)) - (pz2 * SIN(rotx))
  25. pz3 = (py2 * SIN(rotx)) + (pz2 * COS(rotx))
  26. px3 = px3 + origox
  27. py3 = py3 + origoy
  28. pz3 = pz3 + origoz
  29.  
  30.  
  31. PRINT "rotated coordinates:"; px3, py3, pz3
  32. 'ROTATING INVERSE
  33. rotx = -rotatingx: roty = -rotatingy: rotz = -rotatingz
  34.  
  35. px = px3 - origox
  36. py = py3 - origoy
  37. pz = pz3 - origoz
  38.  
  39. px2 = (px * COS(rotz)) - (py * SIN(rotz))
  40. py2 = (px * SIN(rotz)) + (py * COS(rotz))
  41. px3 = (px2 * COS(roty)) - (pz * SIN(roty))
  42. pz2 = (px2 * SIN(roty)) + (pz * COS(roty))
  43. py3 = (py2 * COS(rotx)) - (pz2 * SIN(rotx))
  44. pz3 = (py2 * SIN(rotx)) + (pz2 * COS(rotx))
  45. px3 = px3 + origox
  46. py3 = py3 + origoy
  47. pz3 = pz3 + origoz
  48.  
  49. PRINT "re-rotated coordinates:"; px3, py3, pz3
  50.  
  51. PRINT "why don't i get the original coordinates back?"
  52.  
  53.  
« Last Edit: June 26, 2020, 12:38:57 pm by MasterGy »

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: rerotating math problem
« Reply #1 on: June 26, 2020, 12:42:10 pm »
@MasterGy In my pi-in-the-sky program (https://www.qb64.org/forum/index.php?topic=1969.0), the image of pi is rotated in all three coordinate angles.  The maths used to do this is in lines 757 - 795 of the program.  I hope that this may be if some use to you.

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: rerotating math problem
« Reply #2 on: June 26, 2020, 01:34:01 pm »
Thank you for sharing, I find the solution interesting, I will study it tomorrow. What you put into the program is the pinnacle of _MAPTRIANGLE usability! Congratulations!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: rerotating math problem
« Reply #3 on: June 26, 2020, 02:28:08 pm »
See Qwerkey, " is the pinnacle of _MAPTRIANGLE usability!", not just me thinks highly of Pi-in-the-sky. :)

From no less than MasterGy! :)
« Last Edit: June 26, 2020, 02:31:21 pm by bplus »

Marked as best answer by MasterGy on June 29, 2020, 02:57:44 am

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: rerotating math problem
« Reply #4 on: June 26, 2020, 02:36:35 pm »
I think im on the right track with this suggestion, check out GDK's rectangle collision detection, it'll tell you if your inside a rectangle of any given rotation.

Code: QB64: [Select]
  1. '\\ Unseen Game Deveopment Kit (GDK) - Version 1.8 - DEVELOPMENT VERSION - NOT FINISHED!!!
  2. '// Updated 30/7/2019
  3. '// Created By John Onyon a.k.a Unseen Machine
  4. '// Optimistation by CodeGuy and DarthWho
  5. '// ScanKeys% function by Cypherium
  6. '// Image rotation function by Galleon
  7. '// Rotated Rectangle Collision Detection By Richard Notley
  8.  
  9. '##########################################################################################################################
  10. '// Typdef's
  11. '##########################################################################################################################
  12.  
  13. SUB GDK_Types
  14.  
  15.  TYPE Sprite
  16.   File AS LONG
  17.   Height AS INTEGER
  18.   Alpha AS _UNSIGNED LONG
  19.   IsVisible AS _BYTE
  20.   XFrameCount AS _BYTE
  21.   YFrameCount AS _BYTE
  22.   TotalFrameCount AS INTEGER
  23.   RotationX AS SINGLE
  24.   RotationY AS SINGLE
  25.   Scale AS SINGLE
  26.   BitMask AS _MEM '// For pixel perfect collisions
  27.  
  28.  TYPE Vector
  29.   X AS SINGLE
  30.   Y AS SINGLE
  31.   Speed AS SINGLE
  32.   Rotation AS DOUBLE
  33.   Accel AS SINGLE
  34.   Decel AS SINGLE
  35.  
  36.  TYPE BoundingCircle
  37.   X AS INTEGER
  38.   Y AS INTEGER
  39.   Radius AS INTEGER
  40.  
  41.  TYPE MouseState
  42.   X AS INTEGER
  43.   Y AS INTEGER
  44.   LB AS _BYTE
  45.   RB AS _BYTE
  46.   MB AS _BYTE
  47.   MW AS _BYTE
  48.  
  49.  TYPE KeyBoardState
  50.   Left AS LONG
  51.   Right AS LONG
  52.   Down AS LONG
  53.   Up AS LONG
  54.   CTRL AS LONG
  55.   SHIFT AS LONG
  56.   ALT AS LONG
  57.   SPACE AS LONG
  58.   ENTER AS LONG
  59.   ESC AS LONG
  60.   Num1 AS LONG
  61.   Num2 AS LONG
  62.   Num3 AS LONG
  63.   Num4 AS LONG
  64.   Num5 AS LONG
  65.   Num6 AS LONG
  66.   Num7 AS LONG
  67.   Num8 AS LONG
  68.   Num9 AS LONG
  69.   Num0 AS LONG
  70.   PLUS AS LONG
  71.   MINUS AS LONG
  72.   BACKSPACE AS LONG
  73.   A AS LONG
  74.   B AS LONG
  75.   C AS LONG
  76.   D AS LONG
  77.   E AS LONG
  78.   F AS LONG
  79.   G AS LONG
  80.   H AS LONG
  81.   I AS LONG
  82.   J AS LONG
  83.   K AS LONG
  84.   L AS LONG
  85.   M AS LONG
  86.   N AS LONG
  87.   O AS LONG
  88.   P AS LONG
  89.   Q AS LONG
  90.   R AS LONG
  91.   S AS LONG
  92.   T AS LONG
  93.   U AS LONG
  94.   V AS LONG
  95.   W AS LONG
  96.   X AS LONG
  97.   Y AS LONG
  98.   Z AS LONG
  99.  
  100.  
  101.  TYPE ANIMATION
  102.   Frame AS INTEGER
  103.   StartFrame AS INTEGER
  104.   ResetFrame AS INTEGER
  105.   Time AS DOUBLE
  106.   Dir AS _BYTE
  107.  
  108.  TYPE Emitter
  109.   X AS INTEGER
  110.   Y AS INTEGER
  111.   SpawnRate AS INTEGER
  112.   SpawnAngleMin AS SINGLE
  113.   SpawnAngleMax AS SINGLE
  114.   SpawnMaxVelocity AS SINGLE
  115.   SpawnMinVelocity AS SINGLE
  116.   MaxLifeTime AS DOUBLE
  117.   MinLifeTime AS DOUBLE
  118.   AccelMax AS SINGLE
  119.   DecelMax AS SINGLE
  120.   AccelMin AS SINGLE
  121.   DecelMIn AS SINGLE
  122.   Gravity AS SINGLE
  123.  
  124.  TYPE Particle
  125.   InitialCLR AS _UNSIGNED LONG
  126.   CurrentCLR AS _UNSIGNED LONG
  127.   ClrChange AS _UNSIGNED LONG
  128.   ClrChangeMode AS INTEGER
  129.   Vector AS Vector
  130.   BirthTime AS DOUBLE
  131.   LifeTime AS DOUBLE
  132.   Exists AS _BYTE
  133.   Accel AS SINGLE
  134.   Decel AS SINGLE
  135.   Gravity AS SINGLE
  136.  
  137.  TYPE Tileset
  138.   Sheet AS Sprite
  139.   THeight AS INTEGER
  140.   TWidth AS INTEGER
  141.  
  142.  TYPE XY
  143.   X AS INTEGER
  144.   Y AS INTEGER
  145.  
  146.  TYPE Rectangle
  147.   XY AS XY
  148.   WH AS XY
  149.   Rotation AS SINGLE
  150.   RotationPoint AS XY
  151.   C1 AS XY
  152.   C2 AS XY
  153.   C3 AS XY
  154.   C4 AS XY
  155.  
  156.  TYPE GameObject
  157.   Sprite AS Sprite
  158.   Vector AS Vector
  159.   Rect AS Rectangle
  160.  
  161.  TYPE Tile
  162.   RECT AS Rectangle
  163.   Tile AS INTEGER
  164.  
  165.  TYPE Path
  166.   Vector AS Vector
  167.   LastVector AS Vector
  168.   TargetVector AS Vector
  169.   NumPoints AS INTEGER
  170.   CurrentPoint AS INTEGER
  171.   HitTargetX AS INTEGER
  172.   HitTargetY AS INTEGER
  173.   Repeat AS INTEGER
  174.   Relative AS INTEGER
  175.   Reverse AS INTEGER
  176.   IsReversing AS INTEGER
  177.  
  178.  TYPE PathPoint
  179.   X AS INTEGER
  180.   Y AS INTEGER
  181.   Speed AS INTEGER
  182.  
  183.  
  184.  
  185. '##########################################################################################################################
  186. '// Collision detection
  187. '##########################################################################################################################
  188.  
  189. SUB GDK_Rectangle_New (RectRef AS Rectangle, x%, y%, Width%, Height%)
  190.  RectRef.XY.X = x%
  191.  RectRef.XY.Y = y%
  192.  RectRef.WH.X = Width%
  193.  RectRef.WH.Y = Height%
  194.  
  195. SUB GDK_Rectangle_Autosize (Sprite AS Sprite, Vector AS Vector, Rect AS Rectangle)
  196.  Rect.XY.X = Vector.X - (Sprite.RotationX * Sprite.Scale)
  197.  Rect.XY.Y = Vector.Y - (Sprite.RotationY * Sprite.Scale)
  198.  Rect.WH.X = (Sprite.Width / Sprite.XFrameCount) * Sprite.Scale
  199.  Rect.WH.Y = (Sprite.Height / Sprite.YFrameCount) * Sprite.Scale
  200.  Rect.Rotation = Vector.Rotation
  201.  Rect.RotationPoint.X = Sprite.RotationX * Sprite.Scale
  202.  Rect.RotationPoint.Y = Sprite.RotationY * Sprite.Scale
  203.  DIM pX(3) AS SINGLE, pY(3) AS SINGLE, W AS LONG, H AS LONG, I AS LONG, X AS LONG, Y AS LONG, X2 AS LONG, Y2 AS LONG, PointX AS LONG, PointY AS LONG
  204.  X = Vector.X
  205.  Y = Vector.Y
  206.  W = (Sprite.Width / Sprite.XFrameCount)
  207.  H = (Sprite.Height / Sprite.YFrameCount)
  208.  PointX = Sprite.RotationX
  209.  PointY = Sprite.RotationY
  210.  pX(0) = -PointX
  211.  pY(0) = -PointY
  212.  pX(1) = -PointX
  213.  pY(1) = -PointY + H - 1
  214.  pX(2) = -PointX + W - 1
  215.  pY(2) = -PointY + H - 1
  216.  pX(3) = -PointX + W - 1
  217.  pY(3) = -PointY 'Set dest screen points
  218.  SINr = SIN(Vector.Rotation)
  219.  COSr = COS(Vector.Rotation) 'Precalculate SIN & COS of angle
  220.  FOR I = 0 TO 3
  221.   pX(I) = pX(I) * Sprite.Scale
  222.   pY(I) = pY(I) * Sprite.Scale 'Scale
  223.   X2 = pX(I) * COSr + SINr * pY(I)
  224.   pY(I) = pY(I) * COSr - pX(I) * SINr
  225.   pX(I) = X2 'Rotate Dest Points
  226.   pX(I) = pX(I) + X
  227.   pY(I) = pY(I) + Y 'Translate Dest Points
  228.    CASE 0
  229.     Rect.C1.X = pX(I)
  230.     Rect.C1.Y = pY(I)
  231.    CASE 1
  232.     Rect.C2.X = pX(I)
  233.     Rect.C2.Y = pY(I)
  234.    CASE 2
  235.     Rect.C3.X = pX(I)
  236.     Rect.C3.Y = pY(I)
  237.    CASE 3
  238.     Rect.C4.X = pX(I)
  239.     Rect.C4.Y = pY(I)
  240.  
  241.  
  242. FUNCTION GDK_Rectangle_Intersect (Rect1 AS Rectangle, Rect2 AS Rectangle)
  243.  'IF Rect1.Rotation = 0 AND Rect2.Rotation = 0 THEN '// No rotation do standard collision check'''
  244.  '
  245.  '    IF Rect1.XY.X <= Rect2.XY.X + Rect2.WH.X THEN
  246.  '      IF Rect1.XY.X + Rect1.WH.X >= Rect2.XY.X THEN
  247.  '        IF Rect1.XY.Y <= Rect2.XY.Y + Rect2.WH.Y THEN
  248.  '          IF Rect1.XY.Y + Rect1.WH.Y >= Rect2.XY.Y THEN
  249.  '            GDK_Rectangle_Intersect = -1
  250.  '            EXIT FUNCTION
  251.  '          END IF
  252.  '        END IF
  253.  '      END IF
  254.  '    END IF'
  255.  
  256.  '  ELSE '// Rotated rectangles
  257.  
  258.  '// Adapted from code created by Richard Notley
  259.  '// http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=12564.0
  260.  REDIM sngCorners1!(3, 1), sngCorners2!(3, 1), sngCorners2A!(3, 1), sngCentre!(1, 1)
  261.  
  262.  '// Put rect data into arrays
  263.  sngCorners1!(0, 0) = Rect1.C1.X
  264.  sngCorners1!(0, 1) = Rect1.C1.Y
  265.  sngCorners1!(1, 0) = Rect1.C2.X
  266.  sngCorners1!(1, 1) = Rect1.C2.Y
  267.  sngCorners1!(2, 0) = Rect1.C3.X
  268.  sngCorners1!(2, 1) = Rect1.C3.Y
  269.  sngCorners1!(3, 0) = Rect1.C4.X
  270.  sngCorners1!(3, 1) = Rect1.C4.Y
  271.  
  272.  sngCorners2!(0, 0) = Rect2.C1.X
  273.  sngCorners2!(0, 1) = Rect2.C1.Y
  274.  sngCorners2!(1, 0) = Rect2.C2.X
  275.  sngCorners2!(1, 1) = Rect2.C2.Y
  276.  sngCorners2!(2, 0) = Rect2.C3.X
  277.  sngCorners2!(2, 1) = Rect2.C3.Y
  278.  sngCorners2!(3, 0) = Rect2.C4.X
  279.  sngCorners2!(3, 1) = Rect2.C4.Y
  280.  
  281.  'Extra copy of sngCorners2! used for second poke-through condition check
  282.  FOR bytN%% = 0 TO 3
  283.   FOR bytM%% = 0 TO 1
  284.    sngCorners2A!(bytN%%, bytM%%) = sngCorners2!(bytN%%, bytM%%)
  285.   NEXT bytM%%
  286.  NEXT bytN%%
  287.  
  288.  'Find Centres of Rectangles
  289.  sngCentre!(0, 0) = (sngCorners1!(0, 0) + sngCorners1!(1, 0) + sngCorners1!(2, 0) + sngCorners1!(3, 0)) / 4
  290.  sngCentre!(0, 1) = (sngCorners1!(0, 1) + sngCorners1!(1, 1) + sngCorners1!(2, 1) + sngCorners1!(3, 1)) / 4
  291.  sngCentre!(1, 0) = (sngCorners2!(0, 0) + sngCorners2!(1, 0) + sngCorners2!(2, 0) + sngCorners2!(3, 0)) / 4
  292.  sngCentre!(1, 1) = (sngCorners2!(0, 1) + sngCorners2!(1, 1) + sngCorners2!(2, 1) + sngCorners2!(3, 1)) / 4
  293.  
  294.  'Find lengths of rectangle diagonals
  295.  sngDiag1! = (SQR((sngCorners1!(2, 0) - sngCorners1!(0, 0)) * (sngCorners1!(2, 0) - sngCorners1!(0, 0)) + (sngCorners1!(2, 1) - sngCorners1!(0, 1)) * (sngCorners1!(2, 1) - sngCorners1!(0, 1)))) / 2
  296.  sngDiag2! = (SQR((sngCorners2!(2, 0) - sngCorners2!(0, 0)) * (sngCorners2!(2, 0) - sngCorners2!(0, 0)) + (sngCorners2!(2, 1) - sngCorners2!(0, 1)) * (sngCorners2!(2, 1) - sngCorners2!(0, 1)))) / 2
  297.  sngSepn! = SQR((sngCentre!(1, 0) - sngCentre!(0, 0)) * (sngCentre!(1, 0) - sngCentre!(0, 0)) + (sngCentre!(1, 1) - sngCentre!(0, 1)) * (sngCentre!(1, 1) - sngCentre!(0, 1)))
  298.  
  299.  IF sngSepn! <= sngDiag1! + sngDiag2! THEN
  300.   'Only need to do collision check if rectangles are closer than sum of half-diagonals
  301.  
  302.   'Check for intersect of diagonals
  303.   IF HF_CrossOver%%(sngCorners1!(0, 1), sngCorners1!(0, 0), sngCorners1!(2, 1), sngCorners1!(2, 0), sngCorners2!(0, 1), sngCorners2!(0, 0), sngCorners2!(2, 1), sngCorners2!(2, 0)) = -1 THEN
  304.    GDK_Rectangle_Intersect = -1
  305.   ELSEIF HF_CrossOver%%(sngCorners1!(0, 1), sngCorners1!(0, 0), sngCorners1!(2, 1), sngCorners1!(2, 0), sngCorners2!(1, 1), sngCorners2!(1, 0), sngCorners2!(3, 1), sngCorners2!(3, 0)) = -1 THEN
  306.    GDK_Rectangle_Intersect = -1
  307.   ELSEIF HF_CrossOver%%(sngCorners1!(1, 1), sngCorners1!(1, 0), sngCorners1!(3, 1), sngCorners1!(3, 0), sngCorners2!(0, 1), sngCorners2!(0, 0), sngCorners2!(2, 1), sngCorners2!(2, 0)) = -1 THEN
  308.    GDK_Rectangle_Intersect = -1
  309.   ELSEIF HF_CrossOver%%(sngCorners1!(1, 1), sngCorners1!(1, 0), sngCorners1!(3, 1), sngCorners1!(3, 0), sngCorners2!(1, 1), sngCorners2!(1, 0), sngCorners2!(3, 1), sngCorners2!(3, 0)) = -1 THEN
  310.    GDK_Rectangle_Intersect = -1
  311.   ELSE
  312.    'Check for poke-throughs
  313.  
  314.    'adjust sngCorners2! relative to sngArr1! centre
  315.  
  316.    FOR bytN%% = 0 TO 3
  317.     FOR bytM%% = 0 TO 1
  318.      sngCorners2!(bytN%%, bytM%%) = sngCorners2!(bytN%%, bytM%%) - sngCentre!(0, bytM%%)
  319.     NEXT bytM%%
  320.    NEXT bytN%%
  321.  
  322.    'rotate to sngArr1!
  323.  
  324.    'find Angle of sngCorners1!
  325.    sngAngRot! = HF_Angle!(sngCorners1!(3, 1) - sngCorners1!(0, 1), sngCorners1!(3, 0) - sngCorners1!(0, 0))
  326.  
  327.    FOR bytN%% = 0 TO 3
  328.     sngR! = SQR(sngCorners2!(bytN%%, 0) * sngCorners2!(bytN%%, 0) + sngCorners2!(bytN%%, 1) * sngCorners2!(bytN%%, 1)): sngPhi! = HF_Angle!(sngCorners2!(bytN%%, 1), sngCorners2!(bytN%%, 0))
  329.     sngCorners2!(bytN%%, 1) = sngR! * COS(sngPhi! - sngAngRot!)
  330.     sngCorners2!(bytN%%, 0) = sngR! * SIN(sngPhi! - sngAngRot!)
  331.    NEXT bytN%%
  332.  
  333.    'Find height and width of sngCorners1!
  334.    sngRWidth! = SQR((sngCorners1!(0, 0) - sngCorners1!(1, 0)) * (sngCorners1!(0, 0) - sngCorners1!(1, 0)) + (sngCorners1!(0, 1) - sngCorners1!(1, 1)) * (sngCorners1!(0, 1) - sngCorners1!(1, 1)))
  335.    sngRHeight! = SQR((sngCorners1!(0, 0) - sngCorners1!(3, 0)) * (sngCorners1!(0, 0) - sngCorners1!(3, 0)) + (sngCorners1!(0, 1) - sngCorners1!(3, 1)) * (sngCorners1!(0, 1) - sngCorners1!(3, 1)))
  336.  
  337.    FOR bytN%% = 0 TO 3
  338.     IF sngCorners2!(bytN%%, 1) <= sngRHeight! / 2 THEN
  339.      IF sngCorners2!(bytN%%, 1) >= -sngRHeight! / 2 THEN
  340.       IF sngCorners2!(bytN%%, 0) <= sngRWidth! / 2 THEN
  341.        IF sngCorners2!(bytN%%, 0) >= -sngRWidth! / 2 THEN
  342.         GDK_Rectangle_Intersect = -1
  343.         EXIT FUNCTION
  344.        END IF
  345.       END IF
  346.      END IF
  347.     END IF
  348.    NEXT
  349.  
  350.    'adjust sngCorners1! relative to sngArr2! centre
  351.  
  352.    FOR bytN%% = 0 TO 3
  353.     FOR bytM%% = 0 TO 1
  354.      sngCorners1!(bytN%%, bytM%%) = sngCorners1!(bytN%%, bytM%%) - sngCentre!(1, bytM%%)
  355.     NEXT bytM%%
  356.    NEXT bytN%%
  357.  
  358.    'rotate to sngArr2!
  359.  
  360.    'find Angle of sngCorners2A!
  361.    sngAngRot! = HF_Angle!(sngCorners2A!(3, 1) - sngCorners2A!(0, 1), sngCorners2A!(3, 0) - sngCorners2A!(0, 0))
  362.  
  363.    FOR bytN%% = 0 TO 3
  364.     sngR! = SQR(sngCorners1!(bytN%%, 0) * sngCorners1!(bytN%%, 0) + sngCorners1!(bytN%%, 1) * sngCorners1!(bytN%%, 1)): sngPhi! = HF_Angle!(sngCorners1!(bytN%%, 1), sngCorners1!(bytN%%, 0))
  365.     sngCorners1!(bytN%%, 1) = sngR! * COS(sngPhi! - sngAngRot!)
  366.     sngCorners1!(bytN%%, 0) = sngR! * SIN(sngPhi! - sngAngRot!)
  367.    NEXT bytN%%
  368.  
  369.    'Find height and width of sngCorners2!
  370.    sngRWidth! = SQR((sngCorners2A!(0, 0) - sngCorners2A!(1, 0)) * (sngCorners2A!(0, 0) - sngCorners2A!(1, 0)) + (sngCorners2A!(0, 1) - sngCorners2A!(1, 1)) * (sngCorners2A!(0, 1) - sngCorners2A!(1, 1)))
  371.    sngRHeight! = SQR((sngCorners2A!(0, 0) - sngCorners2A!(3, 0)) * (sngCorners2A!(0, 0) - sngCorners2A!(3, 0)) + (sngCorners2A!(0, 1) - sngCorners2A!(3, 1)) * (sngCorners2A!(0, 1) - sngCorners2A!(3, 1)))
  372.  
  373.    FOR bytN%% = 0 TO 3
  374.     IF sngCorners1!(bytN%%, 1) <= sngRHeight! / 2 THEN
  375.      IF sngCorners1!(bytN%%, 1) >= -sngRHeight! / 2 THEN
  376.       IF sngCorners1!(bytN%%, 0) <= sngRWidth! / 2 THEN
  377.        IF sngCorners1!(bytN%%, 0) >= -sngRWidth! / 2 THEN
  378.         GDK_Rectangle_Intersect = -1
  379.         EXIT FUNCTION
  380.        END IF
  381.       END IF
  382.      END IF
  383.     END IF
  384.    NEXT
  385.  
  386.   END IF
  387.  '  END IF
  388.  
  389. FUNCTION HF_Angle! (X!, Y!) '// Helper function for collisions
  390.  IF X! = 0 THEN
  391.   IF Y! < 0 THEN
  392.    HF_Angle! = -_PI / 2
  393.   ELSE
  394.    HF_Angle! = _PI / 2
  395.   END IF
  396.   HF_Angle! = ATN(Y! / X!)
  397.  IF X! < 0 THEN
  398.   HF_Angle! = HF_Angle! - _PI
  399.   IF HF_Angle! < -_PI THEN HF_Angle! = HF_Angle! + 2 * _PI
  400.  
  401. FUNCTION HF_CrossOver%% (sngXT1!, sngYT1!, sngXS1!, sngYS1!, sngXT2!, sngYT2!, sngXS2!, sngYS2!) '// Helper function
  402.  sngM1! = (sngYT1! - sngYS1!) / (sngXT1! - sngXS1!)
  403.  sngC1! = ((sngXT1! * sngYS1!) - (sngXS1! * sngYT1!)) / (sngXT1! - sngXS1!)
  404.  sngM2! = (sngYT2! - sngYS2!) / (sngXT2! - sngXS2!)
  405.  sngC2! = ((sngXT2! * sngYS2!) - (sngXS2! * sngYT2!)) / (sngXT2! - sngXS2!)
  406.  sngXCross! = (sngC1! - sngC2!) / (sngM2! - sngM1!) '!!! <- Possible Divide by zero
  407.  sngYCross! = (sngM1! * sngXCross!) + sngC1!
  408.  sngX1H! = sngXT1!: sngY1H! = sngYT1!
  409.  sngX1L! = sngXS1!: sngY1L! = sngYS1!
  410.  sngX2H! = sngXT2!: sngY2H! = sngYT2!
  411.  sngX2L! = sngXS2!: sngY2L! = sngYS2!
  412.  IF sngX1L! > sngX1H! THEN SWAP sngX1L!, sngX1H!
  413.  IF sngY1L! > sngY1H! THEN SWAP sngY1L!, sngY1H!
  414.  IF sngX2L! > sngX2H! THEN SWAP sngX2L!, sngX2H!
  415.  IF sngY2L! > sngY2H! THEN SWAP sngY2L!, sngY2H!
  416.  IF sngXCross! >= sngX1L! THEN
  417.   IF sngXCross! <= sngX1H! THEN
  418.    IF sngYCross! >= sngY1L! THEN
  419.     IF sngYCross! <= sngY1H! THEN
  420.      IF sngXCross! >= sngX2L! THEN
  421.       IF sngXCross! <= sngX2H! THEN
  422.        IF sngYCross! >= sngY2L! THEN
  423.         IF sngYCross! <= sngY2H! THEN
  424.          HF_CrossOver%% = -1
  425.         END IF
  426.        END IF
  427.       END IF
  428.      END IF
  429.     END IF
  430.    END IF
  431.   END IF
  432.  
  433.  
  434.  
  435. FUNCTION GDK_BoundingCircle_Intersect (Circ1 AS BoundingCircle, Circ2 AS BoundingCircle)
  436.  LRAD% = Circ1.Radius + Circ2.Radius
  437.  CDist! = GDK_Distance(Circ1.X, Circ1.Y, Circ2.X, Circ2.Y)
  438.  IF CDist! > LRAD% THEN
  439.   GDK_BoundingCircle_Intersect = 0
  440.   GDK_BoundingCircle_Intersect = -1
  441.  
  442. SUB GDK_BoundingCircle_New (Circ1 AS BoundingCircle, X%, Y%, Radius%)
  443.  Circ1.X = X%
  444.  Circ1.Y = Y%
  445.  Circ1.Radius = Radius%
  446.  
  447.  
  448. '##########################################################################################################################
  449. '//Vector stuff
  450. '##########################################################################################################################
  451.  
  452. SUB GDK_Vector_New (Vector AS Vector, X%, Y%, Speed!, Rotation#)
  453.  Vector.X = X%
  454.  Vector.Y = Y%
  455.  Vector.Speed = Speed!
  456.  Vector.Rotation = Rotation#
  457.  
  458. SUB GDK_Vector_SetPosition (Vector AS Vector, X%, Y%)
  459.  Vector.X = X%
  460.  Vector.Y = Y%
  461.  
  462. SUB GDK_Vector_SetRotation (Vector AS Vector, Rotation#)
  463.  Vector.Rotation = Rotation#
  464.  
  465. SUB GDK_Vector_SetSpeed (Vector AS Vector, Speed!)
  466.  Vector.Speed = Speed!
  467.  
  468. SUB GDK_Vector_SetAccelDecel (Vector AS Vector, Accel!, Decel!)
  469.  Vector.Accel = Accel!
  470.  Vector.Decel = Decel!
  471.  
  472. SUB GDK_Vector_Update (Vector AS Vector)
  473.  IF Vector.Decel > 0 THEN
  474.   IF Vector.Accel > 0 THEN
  475.    Vector.Accel = Vector.Accel - Vector.Decel
  476.   ELSE
  477.    IF Vector.Speed > (Vector.Decel) THEN Vector.Speed = Vector.Speed - Vector.Decel ELSE Vector.Speed = 0
  478.   END IF
  479.  IF Vector.Accel > 0 THEN Vector.Speed = Vector.Speed + Vector.Accel
  480.  GDK_Vector_Move Vector
  481.  
  482. SUB GDK_Vector_Move (Vector AS Vector)
  483.  Vector.X = Vector.X - SIN(Vector.Rotation) * Vector.Speed
  484.  Vector.Y = Vector.Y - COS(Vector.Rotation) * Vector.Speed
  485.  
  486. '##########################################################################################################################
  487. '// Sprite stuff
  488. '##########################################################################################################################
  489.  
  490. SUB GDK_Sprite_New (Sprite AS Sprite, FileSource$, XFrameCount%, YFrameCount%, TotalFrameCount%, Alpha&)
  491.  Sprite.File = _LOADIMAGE(FileSource$, 32)
  492.  Sprite.Width = _WIDTH(Sprite.File)
  493.  Sprite.Height = _HEIGHT(Sprite.File)
  494.  Sprite.XFrameCount = XFrameCount%
  495.  Sprite.YFrameCount = YFrameCount%
  496.  Sprite.TotalFrameCount = TotalFrameCount%
  497.  Sprite.Scale = 1
  498.  Sprite.IsVisible = -1
  499.  Sprite.Alpha = Alpha&
  500.  
  501. SUB GDK_Sprite_SetRotationPoint (Sprite AS Sprite, X!, Y!)
  502.  Sprite.RotationX = X!
  503.  Sprite.RotationY = Y!
  504.  
  505. SUB GDK_Sprite_SetVisibility (Sprite AS Sprite, OnOff AS _BYTE)
  506.  Sprite.IsVisible = OnOff
  507.  
  508. SUB GDK_Sprite_SetAlpha (Sprite AS Sprite, Alpha&)
  509.  Sprite.Alpha = Alpha&
  510.  
  511. SUB GDK_Sprite_DrawXY (Sprite AS Sprite, X%, Y%, Rotation!, AnimationFrame%)
  512.  DIM tempvect AS Vector
  513.  GDK_Vector_New tempvect, X%, Y%, 0, Rotation!
  514.  GDK_Sprite_Draw Sprite, tempvect, AnimationFrame%
  515.  
  516. SUB GDK_Sprite_Hide (Handle AS Sprite)
  517.  Handle.IsVisible = 0
  518.  
  519. SUB GDK_Sprite_Show (Handle AS Sprite)
  520.  Handle.IsVisible = -1
  521.  
  522. SUB GDK_Sprite_Free (Sprite AS Sprite)
  523.  _FREEIMAGE (Sprite.File)
  524.  Sprite.IsVisible = 0
  525.  
  526. SUB GDK_Sprite_Clone (SourceSprite AS Sprite, DestSprite AS Sprite)
  527.  DestSprite = SourceSprite
  528.  
  529. SUB GDK_Sprite_Clone_X (SourceSprite AS Sprite, DestSprite() AS Sprite, FirstClone%, NumberOfClones%)
  530.  FOR CloneCount% = FirstClone% TO FirstClone% + NumberOfClones% - 1
  531.   DestSprite(CloneCount%) = SourceSprite
  532.  
  533. SUB GDK_Sprite_SetRotationAsCenter (Sprite AS Sprite)
  534.  GDK_Sprite_SetRotationPoint Sprite, Sprite.Width / (Sprite.XFrameCount * 2), Sprite.Height / (Sprite.YFrameCount * 2)
  535.  
  536. '// UPDATED VERSION!!
  537. SUB GDK_Sprite_Draw (Sprite AS Sprite, DestVector AS Vector, Frame%)
  538.  IF Frame% = 0 THEN Frame% = 1
  539.  _CLEARCOLOR Sprite.Alpha, Sprite.File
  540.  IF Sprite.IsVisible THEN
  541.   FrameXSize% = Sprite.Width / Sprite.XFrameCount
  542.   FrameYSize% = Sprite.Height / Sprite.YFrameCount
  543.   FrameXStart% = ((INT((Frame% - 1) MOD Sprite.XFrameCount)) * FrameXSize%)
  544.   FrameYStart% = ((INT((Frame% - 1) / Sprite.XFrameCount)) * FrameYSize%)
  545.   TmpImage& = _NEWIMAGE(FrameXSize%, FrameYSize%, 32)
  546.   _PUTIMAGE (0, 0), Sprite.File, TmpImage&, (FrameXStart%, FrameYStart%)-(FrameXStart% + FrameXSize%, FrameYStart% + FrameYSize%)
  547.   Rotate_Scale_AroundPoint DestVector.X, DestVector.Y, TmpImage&, -GDK_RadianToDegree(DestVector.Rotation), Sprite.Scale, Sprite.Scale, Sprite.RotationX, Sprite.RotationY
  548.   _FREEIMAGE TmpImage&
  549.  
  550.  
  551. '##########################################################################################################################
  552. '// SCREEN Stuff!
  553. '##########################################################################################################################
  554.  
  555. SUB GDK_Screen_SetRes (ScreenHandle&, width%, height%)
  556.  ScreenHandle& = _NEWIMAGE(width%, height%, 32)
  557.  SCREEN ScreenHandle&
  558.  
  559.  
  560. '##########################################################################################################################
  561. '// User input subs and functions.
  562. '##########################################################################################################################
  563.  
  564. SUB GDK_Keyboard_GetState (KeyboardRef AS KeyBoardState)
  565.  FOR x% = 1 TO 88 'read each key scancode from array
  566.   IF x% = 1 THEN KeyboardRef.ESC = ScanKey%(x%)
  567.   IF x% = 2 THEN KeyboardRef.Num1 = ScanKey%(x%)
  568.   IF x% = 3 THEN KeyboardRef.Num2 = ScanKey%(x%)
  569.   IF x% = 4 THEN KeyboardRef.Num3 = ScanKey%(x%)
  570.   IF x% = 5 THEN KeyboardRef.Num4 = ScanKey%(x%)
  571.   IF x% = 6 THEN KeyboardRef.Num5 = ScanKey%(x%)
  572.   IF x% = 7 THEN KeyboardRef.Num6 = ScanKey%(x%)
  573.   IF x% = 8 THEN KeyboardRef.Num7 = ScanKey%(x%)
  574.   IF x% = 9 THEN KeyboardRef.Num8 = ScanKey%(x%)
  575.   IF x% = 10 THEN KeyboardRef.Num9 = ScanKey%(x%)
  576.   IF x% = 11 THEN KeyboardRef.Num0 = ScanKey%(x%)
  577.   IF x% = 12 THEN KeyboardRef.MINUS = ScanKey%(x%)
  578.   IF x% = 13 THEN KeyboardRef.PLUS = ScanKey%(x%)
  579.   IF x% = 14 THEN KeyboardRef.BACKSPACE = ScanKey%(x%)
  580.   IF x% = 15 THEN KeyboardRef.TAB = ScanKey%(x%)
  581.   IF x% = 30 THEN KeyboardRef.A = ScanKey%(x%)
  582.   IF x% = 48 THEN KeyboardRef.B = ScanKey%(x%)
  583.   IF x% = 46 THEN KeyboardRef.C = ScanKey%(x%)
  584.   IF x% = 32 THEN KeyboardRef.D = ScanKey%(x%)
  585.   IF x% = 18 THEN KeyboardRef.E = ScanKey%(x%)
  586.   IF x% = 33 THEN KeyboardRef.F = ScanKey%(x%)
  587.   IF x% = 34 THEN KeyboardRef.G = ScanKey%(x%)
  588.   IF x% = 35 THEN KeyboardRef.H = ScanKey%(x%)
  589.   IF x% = 23 THEN KeyboardRef.I = ScanKey%(x%)
  590.   IF x% = 36 THEN KeyboardRef.J = ScanKey%(x%)
  591.   IF x% = 37 THEN KeyboardRef.K = ScanKey%(x%)
  592.   IF x% = 38 THEN KeyboardRef.L = ScanKey%(x%)
  593.   IF x% = 50 THEN KeyboardRef.M = ScanKey%(x%)
  594.   IF x% = 49 THEN KeyboardRef.N = ScanKey%(x%)
  595.   IF x% = 24 THEN KeyboardRef.O = ScanKey%(x%)
  596.   IF x% = 25 THEN KeyboardRef.P = ScanKey%(x%)
  597.   IF x% = 16 THEN KeyboardRef.Q = ScanKey%(x%)
  598.   IF x% = 19 THEN KeyboardRef.R = ScanKey%(x%)
  599.   IF x% = 31 THEN KeyboardRef.S = ScanKey%(x%)
  600.   IF x% = 20 THEN KeyboardRef.T = ScanKey%(x%)
  601.   IF x% = 22 THEN KeyboardRef.U = ScanKey%(x%)
  602.   IF x% = 47 THEN KeyboardRef.V = ScanKey%(x%)
  603.   IF x% = 17 THEN KeyboardRef.W = ScanKey%(x%)
  604.   IF x% = 45 THEN KeyboardRef.X = ScanKey%(x%)
  605.   IF x% = 21 THEN KeyboardRef.Y = ScanKey%(x%)
  606.   IF x% = 44 THEN KeyboardRef.Z = ScanKey%(x%)
  607.   IF x% = 72 THEN KeyboardRef.Up = ScanKey%(x%)
  608.   IF x% = 75 THEN KeyboardRef.Left = ScanKey%(x%)
  609.   IF x% = 77 THEN KeyboardRef.Right = ScanKey%(x%)
  610.   IF x% = 80 THEN KeyboardRef.Down = ScanKey%(x%)
  611.   IF x% = 28 THEN KeyboardRef.ENTER = ScanKey%(x%)
  612.   IF x% = 57 THEN KeyboardRef.SPACE = ScanKey%(x%)
  613.   IF x% = 29 THEN KeyboardRef.CTRL = ScanKey%(x%)
  614.   IF x% = 56 THEN KeyboardRef.ALT = ScanKey%(x%)
  615.   IF x% = 42 THEN KeyboardRef.SHIFT = ScanKey%(x%)
  616.  
  617. FUNCTION ScanKey% (scancode%)
  618.  STATIC Ready%, keyflags%() 'retain values on procedure exit
  619.  IF NOT Ready% THEN REDIM keyflags%(0 TO 127): Ready% = -1 'create array on first use
  620.  i% = INP(&H60) 'read keyboard states
  621.  IF (i% AND 128) THEN keyflags%(i% XOR 128) = 0
  622.  IF (i% AND 128) = 0 THEN keyflags%(i%) = -1
  623.  K$ = INKEY$ 'clears key buffer to prevent beeps
  624.  ScanKey% = keyflags%(scancode%)
  625.  IF scancode% = 0 THEN Ready% = 0 'allows program to reset all values to 0 with a REDIM
  626.  
  627. SUB GDK_Mouse_GetState (MouseRef AS MouseState)
  628.  MouseRef.X = _MOUSEX
  629.  MouseRef.Y = _MOUSEY
  630.  MouseRef.LB = _MOUSEBUTTON(1)
  631.  MouseRef.RB = _MOUSEBUTTON(2)
  632.  MouseRef.MB = _MOUSEBUTTON(3)
  633.  MouseRef.MW = _MOUSEWHEEL
  634. '##########################################################################################################################
  635. '//Particle engine v.03
  636. '##########################################################################################################################
  637.  
  638. SUB GDK_Emitter_New (EmitRef AS Emitter, x%, y%, SpawnRate%, AngleMin!, AngleMax!, VelMin!, VelMax!, MinLifeTime#, MaxLifeTime#)
  639.  EmitRef.X = x%
  640.  EmitRef.Y = y%
  641.  EmitRef.SpawnRate = SpawnRate%
  642.  EmitRef.SpawnAngleMin = AngleMin!
  643.  EmitRef.SpawnAngleMax = AngleMax!
  644.  EmitRef.SpawnMaxVelocity = VelMax!
  645.  EmitRef.SpawnMinVelocity = VelMin!
  646.  EmitRef.MaxLifeTime = MaxLifeTime#
  647.  EmitRef.MinLifeTime = MinLifeTime#
  648.  
  649. SUB GDK_Emitter_SetGravity (EmitRef AS Emitter, Gravity!)
  650.  EmitRef.Gravity = Gravity!
  651.  
  652. SUB GDK_Emitter_SetAccelDecel (EmitRef AS Emitter, AccelMin!, AccelMax!, DecelMin!, DecelMax!)
  653.  EmitRef.AccelMin = AccelMin!
  654.  EmitRef.AccelMax = AccelMax!
  655.  EmitRef.DecelMIn = DecelMin!
  656.  EmitRef.DecelMax! = DecelMax!
  657.  
  658. SUB GDK_Particles_Spawn (EmitRef AS Emitter, PartRef() AS Particle, ParticleMax&, InitialColor&, ColorChange&, ChangeMode%)
  659.  PBTime# = TIMER(.001)
  660.  FOR i& = 0 TO ParticleMax&
  661.   IF NOT PartRef(i&).Exists THEN
  662.    PartRef(i&).Vector.X = EmitRef.X
  663.    PartRef(i&).Vector.Y = EmitRef.Y
  664.    PartRef(i&).Exists = -1
  665.    PartRef(i&).Vector.Rotation = (RND * EmitRef.SpawnAngleMax) + EmitRef.SpawnAngleMin
  666.    PartRef(i&).Vector.Speed = (RND * EmitRef.SpawnMaxVelocity) + EmitRef.SpawnMinVelocity
  667.    PartRef(i&).LifeTime = (RND * EmitRef.MaxLifeTime) + EmitRef.MinLifeTime
  668.    PartRef(i&).InitialCLR = InitialColor&
  669.    PartRef(i&).CurrentCLR = InitialColor&
  670.    PartRef(i&).ClrChange = ColorChange&
  671.    PartRef(i&).BirthTime = PBTime#
  672.    PartRef(i&).ClrChangeMode = ChangeMode%
  673.    IF EmitRef.AccelMax > 0 THEN
  674.     PartRef(i&).Accel = (RND * EmitRef.AccelMax) + EmitRef.AccelMin
  675.    END IF
  676.    IF EmitRef.DecelMax > 0 THEN
  677.     PartRef(i&).Decel = (RND * EmitRef.DecelMax) + EmitRef.DecelMIn
  678.    END IF
  679.    IF SuccessfulSpawns& = EmitRef.SpawnRate THEN EXIT FOR ELSE SuccessfulSpawns& = SuccessfulSpawns& + 1
  680.   END IF
  681.  
  682. SUB GDK_Particles_Update (PartRef() AS Particle, ParticleMax&)
  683.  FOR i& = 0 TO ParticleMax&
  684.   IF PartRef(i&).Exists THEN
  685.    IF TIMER(.001) - PartRef(i&).BirthTime >= PartRef(i&).LifeTime THEN
  686.     PartRef(i&).Exists = 0
  687.    ELSE
  688.     IF PartRef(i&).Vector.Speed > 0 THEN
  689.      IF PartRef(i&).Decel > 0 THEN
  690.       IF PartRef(i&).Accel > 0 THEN
  691.        PartRef(i&).Accel = PartRef(i&).Accel - PartRef(i&).Decel
  692.       ELSE
  693.        PartRef(i&).Vector.Speed = PartRef(i&).Vector.Speed - PartRef(i&).Decel
  694.       END IF
  695.      END IF
  696.      IF PartRef(i&).Accel > 0 THEN PartRef(i&).Vector.Speed = PartRef(i&).Vector.Speed + PartRef(i&).Accel
  697.      IF PartRef(i&).ClrChangeMode = 1 THEN
  698.       PartRef(i&).CurrentCLR = _RGB32(_RED(PartRef(i&).CurrentCLR) - _RED(PartRef(i&).ClrChange), _GREEN(PartRef(i&).CurrentCLR) - _GREEN(PartRef(i&).ClrChange), _BLUE(PartRef(i&).CurrentCLR) - _BLUE(PartRef(i&).ClrChange))
  699.      ELSE
  700.       PartRef(i&).CurrentCLR = _RGB32(_RED(PartRef(i&).CurrentCLR) + _RED(PartRef(i&).ClrChange), _GREEN(PartRef(i&).CurrentCLR) + _GREEN(PartRef(i&).ClrChange), _BLUE(PartRef(i&).CurrentCLR) + _BLUE(PartRef(i&).ClrChange))
  701.      END IF
  702.      GDK_Vector_Move PartRef(i&).Vector
  703.     ELSE
  704.      PartRef(i&).Exists = 0
  705.     END IF
  706.    END IF
  707.   END IF
  708.  
  709. SUB GDK_Particles_Draw (PartRef() AS Particle, ParticleMax&)
  710.  FOR i& = 0 TO ParticleMax&
  711.   IF PartRef(i&).Exists THEN
  712.    PSET (PartRef(i&).Vector.X, PartRef(i&).Vector.Y), PartRef(i&).CurrentCLR
  713.   END IF
  714.  
  715. '##########################################################################################################################
  716. '// MATH FUNCTIONS
  717. '##########################################################################################################################
  718.  
  719. FUNCTION GDK_Distance! (X%, Y%, XX%, YY%)
  720.  xd% = XX% - X%
  721.  yd% = YY% - Y%
  722.  GDK_Distance! = SQR((xd% * xd%) + (yd% * yd%))
  723.  
  724. FUNCTION GDK_RadianToDegree! (Radians!)
  725.  GDK_RadianToDegree! = Radians! * (180 / (4 * ATN(1)))
  726.  
  727. FUNCTION GDK_DegreeToRadian! (Degrees!)
  728.  GDK_DegreeToRadian! = Degrees! * ((4 * ATN(1)) / 180)
  729.  
  730. SUB GDK_MathX
  731.   FUNCTION atan2# (BYVAL y#, BYVAL x#)
  732.   FUNCTION acos# (BYVAL x#)
  733.   FUNCTION asin# (BYVAL x#)
  734.   FUNCTION cosh# (BYVAL x#)
  735.   FUNCTION sinh# (BYVAL x#)
  736.   FUNCTION tanh# (BYVAL x#)
  737.   FUNCTION pow# (BYVAL base#, BYVAL exponent#)
  738.  
  739. '##########################################################################################################################
  740. '// Tile engine
  741. '##########################################################################################################################
  742.  
  743. SUB GDK_TileSet_New (TileRef AS Tileset, File$, XTiles%, YTiles%, Alpha&)
  744.  GDK_Sprite_New TileRef.Sheet, File$, XTiles%, YTiles%, XTiles% * YTiles%, Alpha&
  745.  TileRef.TWidth = (TileRef.Sheet.Width / XTiles%)
  746.  TileRef.THeight = (TileRef.Sheet.Height / YTiles%)
  747.  
  748. SUB GDK_TileMap_Load (Level() AS Tile, XTiles%, YTiles%)
  749.  FOR j% = 0 TO YTiles% - 1
  750.   FOR i% = 0 TO XTiles% - 1
  751.    READ tile%
  752.    Level(i%, j%).Tile = tile%
  753.   NEXT
  754.  
  755. SUB GDK_TileMap_Draw (TileRef AS Tileset, Level() AS Tile, X%, Y%, XCnt%, YCnt%, XMax%, YMax%)
  756.  Tx% = X%
  757.  Ty% = Y%
  758.  sx% = _WIDTH(_DEST)
  759.  sy% = _HEIGHT(_DEST)
  760.  FOR j% = YCnt% TO YMax% - 1
  761.   FOR i% = XCnt% TO XMax% - 1
  762.    IF Tx% < sx% THEN
  763.     IF Level(i%, j%).Tile > 0 THEN
  764.      GDK_Sprite_DrawXY TileRef.Sheet, Tx%, Ty%, 0, Level(i%, j%).Tile
  765.     END IF
  766.     Tx% = Tx% + (TileRef.TWidth * TileRef.Sheet.Scale)
  767.    ELSE
  768.     EXIT FOR
  769.    END IF
  770.   NEXT
  771.   Tx% = X%
  772.   IF Ty% < sy% THEN Ty% = Ty% + (TileRef.THeight * TileRef.Sheet.Scale) ELSE EXIT FOR
  773.  
  774.  
  775. SUB GDK_TileMap_Load_FromFile (GameFile$, Level() AS Tile, YTiles%)
  776.  X& = FREEFILE
  777.  OPEN GameFile$ FOR INPUT AS #X&
  778.  FOR i% = 0 TO YTiles% - 1
  779.   LINE INPUT #X&, DataLine$
  780.   Cnt% = 0
  781.   FOR j% = 0 TO LEN(DataLine$)
  782.    IF INSTR(j%, DataLine$, ",") > 0 THEN
  783.     Level(Cnt%, i%).Tile = VAL(MID$(DataLine$, j%, INSTR(j%, DataLine$, ",") - j%))
  784.     j% = INSTR(j%, DataLine$, ",")
  785.     Cnt% = Cnt% + 1
  786.    ELSE
  787.     Level(Cnt%, i%).Tile = VAL(MID$(DataLine$, j%))
  788.    END IF
  789.   NEXT
  790.  CLOSE #X&
  791.  
  792. SUB GDK_Tileset_SetScale (TileRef AS Tileset, Scale!)
  793.  TileRef.Sheet.Scale = Scale!
  794.  
  795. 'SUB GDK_Tiles_Draw_ISO (TileRef AS Tileset, XYRef() AS XY, Level() AS Tile, X%, Y%, XCnt%, YCnt%, XMax%, YMax%)
  796. '  Tx% = X%
  797. '  Ty% = Y%
  798. '  YCntr% = 0
  799. '  FOR j% = YCnt% TO YMax% - 1
  800. '    FOR i% = XCnt% TO XMax% - 1
  801. '            IF Level(i%, j%).Tile > 0 THEN GDK_Tile_Draw TileRef, Level(i%, j%).Tile, XYRef(), Tx%, Ty%
  802. '            Tx% = Tx% + (TileRef.TWidth / 2)
  803. '            Ty% = Ty% + (TileRef.THeight / 4)
  804. '        NEXT
  805. '        YCntr% = YCntr% + 1
  806. '        Ty% = Y% + YCntr% * (TileRef.THeight / 4)
  807. '        Tx% = X% - (YCntr% * (TileRef.TWidth / 2))
  808. '    NEXT
  809. 'END SUB
  810.  
  811.  
  812. '##########################################################################################################################
  813. '// GameObject Subs and Functions - SUper fast prototyping commands for games
  814. '##########################################################################################################################
  815.  
  816. SUB GDK_GameObject_New (Handle AS GameObject, File$, XframeCount%, YFrameCount%, X%, Y%, Speed!, Rotation!)
  817.  GDK_Sprite_New Handle.Sprite, File$, XframeCount%, YFrameCount%, XframeCount% * YFrameCount%, 1
  818.  GDK_Vector_New Handle.Vector, X%, Y%, Speed!, Rotation!
  819.  GDK_Sprite_SetVisibility Handle.Sprite, -1
  820.  GDK_Sprite_SetAlpha Handle.Sprite, _RGB(255, 0, 255)
  821.  
  822. SUB GDK_GameObject_Draw (GameObject AS GameObject, AnimationFrame%)
  823.  GDK_Sprite_Draw GameObject.Sprite, GameObject.Vector, AnimationFrame%
  824.  
  825. SUB GDK_GameObject_Update (Handle AS GameObject)
  826.  GDK_Vector_Update Handle.Vector
  827.  GDK_Rectangle_Autosize Handle.Sprite, Handle.Vector, Handle.Rect
  828.  
  829. SUB GDK_GameObject_Rotate (Handle AS GameObject, Rot!)
  830.  Handle.Vector.Rotation = Handle.Vector.Rotation + Rot!
  831.  
  832. SUB GDK_GameObject_Hide (Handle AS GameObject)
  833.  Handle.Sprite.IsVisible = 0
  834.  
  835. SUB GDK_GameObject_Show (Handle AS GameObject)
  836.  Handle.Sprite.IsVisible = -1
  837.  
  838. FUNCTION GDK_GameObject_Intersect (Handle AS GameObject, Handle2 AS GameObject)
  839.  IF GDK_Rectangle_Intersect(Handle.Rect, Handle2.Rect) THEN
  840.   GDK_GameObject_Intersect = -1
  841.   GDK_GameObject_Intersect = 0
  842.  
  843. '##########################################################################################################################
  844. '// Animation routines - Taken from GDK_GL
  845. '##########################################################################################################################
  846.  
  847. SUB GDK_ANIMATION_NEW (Anim AS ANIMATION, Frame%, StartFrame%, ResetFrame%, AnimTime#, AnimTimer#)
  848.  Anim.Frame = Frame%
  849.  Anim.StartFrame = StartFrame%
  850.  Anim.ResetFrame = ResetFrame%
  851.  Anim.Time = AnimTime#
  852.  Anim.Timer = AnimTimer#
  853.  IF ResetFrame% < StartFrame% THEN Anim.Dir = -1 ELSE Anim.Dir = 0
  854.  
  855. SUB GDK_ANIMATION_UPDATE (Anim AS ANIMATION)
  856.  IF Anim.Dir = -1 THEN
  857.   IF Anim.Frame > Anim.StartFrame OR Anim.Frame < Anim.ResetFrame THEN
  858.    Anim.Frame = Anim.StartFrame
  859.    Anim.Timer = TIMER(.001)
  860.   ELSE
  861.    IF TIMER(.001) - Anim.Timer >= Anim.Time THEN
  862.     IF Anim.Frame = Anim.ResetFrame THEN
  863.      Anim.Frame = Anim.StartFrame
  864.     ELSE
  865.      Anim.Frame = Anim.Frame - 1
  866.     END IF
  867.     Anim.Timer = TIMER(.001)
  868.    END IF
  869.   END IF
  870.   IF Anim.Frame < Anim.StartFrame OR Anim.Frame > Anim.ResetFrame THEN
  871.    Anim.Frame = Anim.StartFrame
  872.    Anim.Timer = TIMER(.001)
  873.   ELSE
  874.    IF TIMER(.001) - Anim.Timer >= Anim.Time THEN
  875.     IF Anim.Frame = Anim.ResetFrame THEN
  876.      Anim.Frame = Anim.StartFrame
  877.     ELSE
  878.      Anim.Frame = Anim.Frame + 1
  879.     END IF
  880.     Anim.Timer = TIMER(.001)
  881.    END IF
  882.   END IF
  883.  
  884. '##########################################################################################################################
  885. '// Image ROTATION/ZOOM FUNCTION BY GALLEON
  886. '##########################################################################################################################
  887.  
  888. SUB Rotate_Scale_AroundPoint (X AS LONG, Y AS LONG, Image AS LONG, Rotation AS SINGLE, ScaleX AS SINGLE, ScaleY AS SINGLE, PointX AS LONG, PointY AS LONG)
  889.  DEFSNG A-Z
  890.  DIM pX(3) AS SINGLE: DIM pY(3) AS SINGLE
  891.  DIM W AS LONG, H AS LONG, I AS LONG, X2 AS LONG, Y2 AS LONG
  892.  W = _WIDTH(Image): H = _HEIGHT(Image)
  893.  pX(0) = -PointX: pY(0) = -PointY: pX(1) = -PointX: pY(1) = -PointY + H - 1: pX(2) = -PointX + W - 1: pY(2) = -PointY + H - 1: pX(3) = -PointX + W - 1: pY(3) = -PointY 'Set dest screen points
  894.  Radians = -Rotation / 57.29578: SINr = SIN(Radians): COSr = COS(Radians) 'Precalculate SIN & COS of angle
  895.  FOR I = 0 TO 3
  896.   pX(I) = pX(I) * ScaleX: pY(I) = pY(I) * ScaleY 'Scale
  897.   X2 = pX(I) * COSr + SINr * pY(I): pY(I) = pY(I) * COSr - pX(I) * SINr: pX(I) = X2 'Rotate Dest Points
  898.   pX(I) = pX(I) + X: pY(I) = pY(I) + Y 'Translate Dest Points
  899.  _MAPTRIANGLE (0, 0)-(0, H - 1)-(W - 1, H - 1), Image TO(pX(0), pY(0))-(pX(1), pY(1))-(pX(2), pY(2))
  900.  _MAPTRIANGLE (0, 0)-(W - 1, 0)-(W - 1, H - 1), Image TO(pX(0), pY(0))-(pX(3), pY(3))-(pX(2), pY(2))
  901.  
  902. '##########################################################################################################################
  903. '// Path based movement v.02
  904. '##########################################################################################################################
  905.  
  906. SUB GDK_Path_New (Path AS Path, PathPoint() AS PathPoint, NumPoints%, Reverse%, Repeat%, Relative%)
  907.  IF Relative% THEN READ Path.Vector.X, Path.Vector.Y, Path.Vector.Speed
  908.  FOR i% = 0 TO NumPoints% - 1
  909.   READ PathPoint(i%).X, PathPoint(i%).Y, PathPoint(i%).Speed
  910.  IF Relative% THEN
  911.   Path.TargetVector.X = Path.Vector.X + PathPoint(0).X
  912.   Path.TargetVector.Y = Path.Vector.Y + PathPoint(0).Y
  913.   Path.Vector.Rotation = -atan2(Path.Vector.Y - Path.TargetVector.Y, Path.Vector.X - Path.TargetVector.X) + (2 * ATN(1))
  914.   Path.Vector.X = PathPoint(0).X
  915.   Path.Vector.Y = PathPoint(0).Y
  916.   Path.Vector.Speed = PathPoint(0).Speed
  917.   Path.Vector.Rotation = -atan2(PathPoint(0).Y - PathPoint(1).Y, PathPoint(0).X - PathPoint(1).X) + (2 * ATN(1))
  918.   Path.TargetVector.X = PathPoint(1).X
  919.   Path.TargetVector.Y = PathPoint(1).Y
  920.  Path.LastVector = Path.Vector
  921.  Path.NumPoints = NumPoints%
  922.  Path.Reverse = Reverse%
  923.  Path.Repeat = Repeat%
  924.  Path.Relative = Relative%
  925.  
  926.  
  927. SUB GDK_Path_Update (Path AS Path, PathPoint() AS PathPoint)
  928.  IF Path.Relative THEN '// Relative movement
  929.   IF NOT Path.HitTargetX THEN IF IsWithinRange(Path.TargetVector.X, Path.LastVector.X, Path.Vector.X) THEN Path.HitTargetX = -1
  930.   IF NOT Path.HitTargetY THEN IF IsWithinRange(Path.TargetVector.Y, Path.LastVector.Y, Path.Vector.Y) THEN Path.HitTargetY = -1
  931.   IF Path.HitTargetX AND Path.HitTargetY THEN
  932.    IF Path.CurrentPoint < Path.NumPoints - 1 THEN
  933.     Path.TargetVector.X = Path.Vector.X + PathPoint(Path.CurrentPoint + 1).X
  934.     Path.TargetVector.Y = Path.Vector.Y + PathPoint(Path.CurrentPoint + 1).Y
  935.     Path.Vector.Rotation = -atan2(Path.Vector.Y - Path.TargetVector.Y, Path.Vector.X - Path.TargetVector.X) + (2 * ATN(1))
  936.     Path.Vector.Speed = PathPoint(Path.CurrentPoint).Speed
  937.     Path.CurrentPoint = Path.CurrentPoint + 1
  938.    ELSE '// Last point
  939.     IF Path.Repeat THEN
  940.      Path.CurrentPoint = 0
  941.      Path.TargetVector.X = Path.Vector.X + PathPoint(0).X
  942.      Path.TargetVector.Y = Path.Vector.Y + PathPoint(0).Y
  943.      Path.Vector.Rotation = -atan2(Path.Vector.Y - Path.TargetVector.Y, Path.Vector.X - Path.TargetVector.X) + (2 * ATN(1))
  944.      Path.Vector.Speed = PathPoint(0).Speed
  945.     ELSE
  946.      Path.Vector.Speed = 0
  947.     END IF
  948.    END IF
  949.    Path.HitTargetX = 0
  950.    Path.HitTargetY = 0
  951.   END IF
  952.  ELSE '// Co-ordinate based movement
  953.   IF Path.IsReversing THEN
  954.    IF Path.CurrentPoint > 0 THEN
  955.     IF NOT Path.HitTargetX THEN IF IsWithinRange(PathPoint(Path.CurrentPoint - 1).X, Path.LastVector.X, Path.Vector.X) THEN Path.HitTargetX = -1
  956.     IF NOT Path.HitTargetY THEN IF IsWithinRange(PathPoint(Path.CurrentPoint - 1).Y, Path.LastVector.Y, Path.Vector.Y) THEN Path.HitTargetY = -1
  957.     IF Path.HitTargetX AND Path.HitTargetY THEN
  958.      IF Path.CurrentPoint > 1 THEN
  959.       Path.CurrentPoint = Path.CurrentPoint - 1
  960.       Path.Vector.Rotation = -atan2(Path.Vector.Y - PathPoint(Path.CurrentPoint - 1).Y, Path.Vector.X - PathPoint(Path.CurrentPoint - 1).X) + (2 * ATN(1))
  961.      ELSE '// First point
  962.       Path.CurrentPoint = 0
  963.       IF Path.Reverse THEN
  964.        Path.IsReversing = 0
  965.        Path.Vector.Rotation = -atan2(Path.Vector.Y - PathPoint(Path.CurrentPoint + 1).Y, Path.Vector.X - PathPoint(Path.CurrentPoint + 1).X) + (2 * ATN(1))
  966.       END IF
  967.      END IF
  968.      Path.HitTargetX = 0
  969.      Path.HitTargetY = 0
  970.      Path.Vector.Speed = PathPoint(Path.CurrentPoint).Speed
  971.     END IF
  972.    END IF
  973.   ELSE
  974.    IF Path.CurrentPoint <= Path.NumPoints - 1 THEN
  975.     IF NOT Path.HitTargetX THEN IF IsWithinRange(PathPoint(Path.CurrentPoint + 1).X, Path.LastVector.X, Path.Vector.X) THEN Path.HitTargetX = -1
  976.     IF NOT Path.HitTargetY THEN IF IsWithinRange(PathPoint(Path.CurrentPoint + 1).Y, Path.LastVector.Y, Path.Vector.Y) THEN Path.HitTargetY = -1
  977.     IF Path.HitTargetX AND Path.HitTargetY THEN
  978.      IF Path.CurrentPoint < Path.NumPoints - 2 THEN
  979.       Path.CurrentPoint = Path.CurrentPoint + 1
  980.       Path.Vector.Rotation = -atan2(Path.Vector.Y - PathPoint(Path.CurrentPoint + 1).Y, Path.Vector.X - PathPoint(Path.CurrentPoint + 1).X) + (2 * ATN(1))
  981.      ELSE '// Last point
  982.       Path.CurrentPoint = Path.NumPoints - 1
  983.       IF Path.Reverse THEN
  984.        Path.IsReversing = -1
  985.        Path.Vector.Rotation = -atan2(Path.Vector.Y - PathPoint(Path.CurrentPoint - 1).Y, Path.Vector.X - PathPoint(Path.CurrentPoint - 1).X) + (2 * ATN(1))
  986.       ELSEIF Path.Repeat THEN
  987.        Path.CurrentPoint = 0
  988.        IF Path.Repeat THEN
  989.         FOR i% = 1 TO Path.NumPoints - 1
  990.          XDif% = PathPoint(i%).X - PathPoint(i% - 1).X
  991.          YDif% = PathPoint(i%).Y - PathPoint(i% - 1).Y
  992.          IF i% = 1 THEN
  993.           PathPoint(0).X = Path.Vector.X
  994.           PathPoint(0).Y = Path.Vector.Y
  995.          END IF
  996.          PathPoint(i%).X = PathPoint(i% - 1).X + XDif%
  997.          PathPoint(i%).Y = PathPoint(i% - 1).Y + YDif%
  998.         NEXT
  999.        END IF
  1000.        Path.Vector.Rotation = -atan2(Path.Vector.Y - PathPoint(Path.CurrentPoint + 1).Y, Path.Vector.X - PathPoint(Path.CurrentPoint + 1).X) + (2 * ATN(1))
  1001.       ELSE '// Stop at end
  1002.        PathPoint(Path.CurrentPoint).Speed = 0
  1003.       END IF
  1004.      END IF
  1005.      Path.Vector.Speed = PathPoint(Path.CurrentPoint).Speed
  1006.      Path.HitTargetX = 0
  1007.      Path.HitTargetY = 0
  1008.     END IF
  1009.    END IF
  1010.   END IF
  1011.  Path.LastVector = Path.Vector
  1012.  GDK_Vector_Update Path.Vector
  1013.  
  1014. '// GDK_Path_Update helper function
  1015. FUNCTION IsWithinRange% (Target%, MinRange%, MaxRange%)
  1016.  IF Target% >= MinRange% AND Target% <= MaxRange% THEN
  1017.   IsWithinRange% = -1
  1018.  ELSEIF Target% <= MinRange% AND Target% >= MaxRange% THEN
  1019.   IsWithinRange% = -1
  1020.   IsWithinRange% = 0
  1021.  
  1022.  
  1023. '##########################################################################################################################
  1024. '// END OF LIBRARY!!!
  1025. '##########################################################################################################################
  1026.  

Unseen

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: rerotating math problem
« Reply #5 on: June 28, 2020, 04:31:16 pm »
Hi !
I managed to solve the rotation. Thanks for all the help! What helped was a paper by a UNSEEN colleague. Well, that's very no nothing! There are valuable treasures in it that are needed for all this!
The problem there was that it didn’t matter in what order we rotated the shafts and back.
I finally understood, so far I’ve just slipped over it, I didn’t understand the sin-cos rotation, I just used it. I understand pretty much now.
I got to the point where wherever the rectangle can be rotated, it senses properly.
And I redesigned the maze generator to see how many towers as many secondary mazes. Several secondary mazes in one big. each area has a tower from which you can go to another tower.
Key and gate are missing. if you will, you can go it linearly, so in one way. Different areas can be made with different visual characteristics.
If you try it out, have “output EXE to source folder” enabled in your qb64 editor.
In the track_creator folder, the program generates a track. you can decide if it is good or not. if you like, the M button, é went down during the 3d display.
In the game folder, the program is much smaller and only deals with display. If you have saved tracks, everything here will load quickly and start.
It would be really good magazines, ideas, low-polik, companion to a good little duke-nukem clone.



  [ You are not allowed to view this attachment ]  

download:
https://drive.google.com/file/d/1fZXnaLL2FPjQ-GatvRwRw46_9rfusNHk/view?usp=sharing
« Last Edit: June 28, 2020, 04:37:38 pm by MasterGy »