November 28, 2020, 01:47:40 AM

Author Topic: [bb] 2D math functions by Jasu [ 1+ years ago ]  (Read 458 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] 2D math functions by Jasu [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : 2D math functions
Author : Jasu
Posted : 1+ years ago

Description : Gathered from the net and translated to Blitz.
Except for function NearestPointInLine, which is my doing.


Code :
Code: BlitzBasic
  1. Global IntersectX#, IntersectY#
  2.  
  3.  
  4. Function Intersect%(x1#, y1#, x2#, y2#, x3#, y3#, x4#, y4#)
  5.         ; This function returns True if lines x1,y1,x2,y2 and x3,y3,x4,y4 intersect at some point.
  6.         Return (Orientation(x1, y1, x2, y2, x3, y3) <> Orientation(x1, y1, x2, y2, x4, y4)) And (Orientation(x3, y3, x4, y4, x1, y1) <> Orientation(x3, y3, x4, y4, x2, y2))
  7.  
  8. End Function
  9.  
  10.  
  11. Function Orientation% ( x1#,y1#, x2#,y2#, Px#,Py# )
  12.         ; Linear determinant of the 3 points.
  13.         ; This function returns the orientation of px,py on line x1,y1,x2,y2.
  14.         ; Look from x2,y2 to the direction of x1,y1.
  15.         ; If px,py is on the right, function returns +1
  16.         ; If px,py is on the left, function returns -1
  17.         ; If px,py is directly ahead or behind, function returns 0
  18.         Return Sgn((x2 - x1) * (Py - y1) - (Px - x1) * (y2 - y1))
  19. End Function
  20.  
  21.  
  22. Function IntersectPoint ( x1#,y1#, x2#,y2#, x3#,y3#, x4#,y4# )
  23.         ;Function returns the X,Y position of the two intersecting lines.
  24.         ;IntersectX and IntersectY are global variables of the main program.
  25.         ;The lines are infinite, is line1 goes through x1,y1,x2,y2 and line2 goes through x3,y3,x4,y4.
  26.         ;For line segments you must check if the lines truly intersect with the function Intersect% before you use this.
  27.        
  28.         Local dx1# = x2 - x1
  29.         Local dx2# = x4 - x3
  30.         Local dx3# = x1 - x3
  31.        
  32.         Local dy1# = y2 - y1
  33.         Local dy2# = y1 - y3
  34.         Local dy3# = y4 - y3
  35.        
  36.         Local R# = dx1 * dy3 - dy1 * dx2
  37.        
  38.         If R <> 0 Then
  39.                 R  = (dy2 * (x4 - x3) - dx3 * dy3) / R
  40.                 IntersectX = x1 + R * dx1
  41.                 IntersectY = y1 + R * dy1
  42.         Else
  43.                 If (((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) = 0) Then
  44.                         IntersectX = x3
  45.                         IntersectY = y3
  46.                 Else
  47.                         IntersectX = x4
  48.                         IntersectY = y4
  49.                 EndIf
  50.         EndIf
  51.        
  52. End Function
  53.  
  54. Function NormalDistance# ( lx1#,ly1#, lx2#,ly2#, x#,y# )
  55.         ; This function calculates the lenght of the normal from point to line.
  56.         ; The line is infinite, so the points lx1,ly1 and lx2,ly2 only determine that the line passes through them.
  57.         ; So the 'line' does not start from lx1,ly1 and end to lx2,ly2.
  58.         ; For a line segment, use function DistanceToLineSegment#
  59.  
  60.         Local dx#=lx2-lx1
  61.         Local dy#=ly2-ly1
  62.        
  63.         Local d#=Sqr(dx*dx+dy*dy)
  64.        
  65.         ;px#=(lx1-x)
  66.         ;py#=(ly1-y)
  67.        
  68.         ;dist#=(dx*py-px*dy) / d
  69.        
  70.         Return Abs((dx*(ly1-y)-(lx1-x)*dy) / d)
  71.        
  72. End Function
  73.  
  74.  
  75. Function DistanceToLineSegment# ( x1#,y1#, x2#,y2#, Px#,Py# )
  76.         ; This function calculates the distance between a line segment and a point.
  77.         ; So this function is useful to determine if line intersects a circle.
  78.         ; To also determine the point on the line x1,y1,x2,y2 which is the closest to px,py , use function NearestPointInLine#
  79.        
  80.         Local Dx#, Dy#, Ratio#
  81.        
  82.         If (x1 = x2) And (y1 = y2) Then
  83.                 Return Sqr( (Px-x1)*(Px-x1)+(Py-y1)*(Py-y1) )
  84.         Else
  85.                
  86.                 Dx#    = x2 - x1
  87.                 Dy#    = y2 - y1
  88.                 Ratio# = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy)
  89.                
  90.                 If Ratio < 0 Then
  91.                         Return Sqr( (Px-x1)*(Px-x1)+(Py-y1)*(Py-y1) )
  92.                 ElseIf Ratio > 1 Then
  93.                         Return Sqr( (Px-x2)*(Px-x2)+(Py-y2)*(Py-y2) )
  94.                 Else
  95.                         Return Sqr ((Px - ((1 - Ratio) * x1 + Ratio * x2))*(Px - ((1 - Ratio) * x1 + Ratio * x2))+(Py - ((1 - Ratio) * y1 + Ratio * y2))*(Py - ((1 - Ratio) * y1 + Ratio * y2)))
  96.                 EndIf
  97.                
  98.         EndIf
  99.        
  100. End Function
  101.  
  102.  
  103. Function NearestPointInLine# ( lx1#,ly1#, lx2#,ly2#, x#,y# )
  104.         ; This function calculates the point between lx1,ly1 and lx2,ly2 which is the nearest to x,y.
  105.         ; Result is put in global variables IntersectX,IntersectY
  106.         ; Function also returns the distance between x,y and the calculated point.
  107.                
  108.         Local dx#=lx2-lx1
  109.         Local dy#=ly2-ly1
  110.         ;d# = Sqr(dx*dx+dy*dy)
  111.         ;ux# = dx/d
  112.         ;uy# = dy/d
  113.         Local Ori1% = Orientation(lx1,ly1, (lx1+dy),(ly1-dx), x,y)
  114.         Local Ori2% = Orientation(lx2,ly2, (lx2+dy),(ly2-dx), x,y)
  115.         If (Ori1 = 1 And Ori2 = 1) Or Ori2 = 0 Then
  116.                 IntersectX = lx2
  117.                 IntersectY = ly2
  118.         ElseIf (Ori1 = -1 And Ori2 = -1) Or Ori1 = 0 Then
  119.                 IntersectX = lx1
  120.                 IntersectY = ly1
  121.         Else
  122.                 IntersectPoint( lx1,ly1, lx2,ly2, x,y, x+dy,y-dx )
  123.         EndIf
  124.         Return Sqr((x-IntersectX)*(x-IntersectX)+(y-IntersectY)*(y-IntersectY))
  125.        
  126. End Function
  127.  
  128. Function TwoLineDistance#( x1#,y1#, x2#,y2#, x3#,y3#, x4#,y4# )
  129.         ; This function returns the distance between two line segments
  130.        
  131.         Local Dt#
  132.         Local sc#
  133.         Local sN#
  134.         Local sD#
  135.         Local tc#
  136.         Local tN#
  137.         Local tD#
  138.         Local dx#
  139.         Local dy#
  140.        
  141.         Local ux# = x2 - x1
  142.         Local uy# = y2 - y1
  143.         Local vx# = x4 - x3
  144.         Local vy# = y4 - y3
  145.         Local wx# = x1 - x3
  146.         Local wy# = y1 - y3
  147.        
  148.         Local a# = (ux * ux + uy * uy)
  149.         Local b# = (ux * vx + uy * vy)
  150.         Local c# = (vx * vx + vy * vy)
  151.         Local d# = (ux * wx + uy * wy)
  152.         Local e# = (vx * wx + vy * wy)
  153.        
  154.         Dt = a * c - b * b
  155.         sD = Dt
  156.         tD = Dt
  157.        
  158.         If Abs(Dt)<0.0001 Then
  159.                 sN = 0.0
  160.                 sD = 1.0
  161.                 tN = e
  162.                 tD = c
  163.         Else
  164.                 sN = (b * e - c * d)
  165.                 tN = (a * e - b * d)
  166.                 If sN < 0.0 Then
  167.                         sN = 0.0
  168.                         tN = e
  169.                         tD = c
  170.                 ElseIf sN > sD Then
  171.                         sN = sD
  172.                         tN = e + b
  173.                         tD = c
  174.                 EndIf
  175.         EndIf
  176.        
  177.         If tN < 0.0 Then
  178.                 tN = 0.0
  179.                 If -d < 0.0 Then
  180.                         sN = 0.0
  181.                 ElseIf -d > a Then
  182.                         sN = sD
  183.                 Else
  184.                         sN = -d
  185.                         sD = a
  186.                 EndIf
  187.         ElseIf tN > tD Then
  188.                 tN = tD
  189.                 If (-d + b) < 0.0 Then
  190.                         sN = 0
  191.                 Else If (-d + b) > a Then
  192.                         sN = sD
  193.                 Else
  194.                         sN = (-d + b)
  195.                         sD = a
  196.                 EndIf
  197.         EndIf
  198.        
  199.         If Abs(sN) < 0.0001 Then sc = 0.0 Else sc = sN / sD
  200.         If Abs(tN) < 0.0001 Then tc = 0.0 Else tc = tN / tD
  201.        
  202.         dx = wx + (sc * ux) - (tc * vx)
  203.         dy = wy + (sc * uy) - (tc * vy)
  204.        
  205.         Return Sqr(dx * dx + dy * dy)
  206.        
  207. End Function


Comments :


puki(Posted 1+ years ago)

 This looks good.Shame it is 2D - nobody does 2D anymore.


altitudems(Posted 1+ years ago)

 I think puki means "I'm stealing this" ;)


Jasu(Posted 1+ years ago)

 Nobody does 2D? I hope you're not serious. 3D graphics maybe rule over 2D, but these are not graphic functions. Games with 2D logic aren't going anywhere.


Ross C(Posted 1+ years ago)

 Thank you very much for this! Works a charm. Much appreciated, for my 3D project!


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal