LB Booster
« OBB 2D + OBB 2D colision »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 04:05am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: OBB 2D + OBB 2D colision  (Read 271 times)
bluatigro
Full Member
ImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 111
xx OBB 2D + OBB 2D colision
« Thread started on: Nov 6th, 2015, 11:18am »

this is a try at oriented bonding boxes
error :
- no rect shape
- obb.hit1way() error

i think i made a typo somwere

Code:
dim obb( 37 , 12 )
global corner , axes , org , x , y , pi
global true , false
false = 0
true = not( false )
corner = 0
axes = 8
org = 10
x = 0
y = 1
pi = atn( 1 ) * 4
WindowWidth = DisplayWidth
WimdowHeight = DisplayHeight
global winx , winy
winx = WindowWidth
winy = WindowHeight
nomainwin
open "obb 2d" for graphics as #m
  #m "trapclose [quit]"
  #m "size 5"
  for i = 0 to 36
    call obb.fill i , winx / 6 , winy / 2 _
    , 50 , 100 , i * 10
  next i
  call obb.fill 37 , winx - 100 , winy / 2 _
  , 50 , 100 , 30
  timer 100 , [timer]
wait
[timer]
  #m "cls"
  for i = 0 to 36
    if not( obb.hit( i , 37 ) ) then
      call obb.move i , 5 , 0
    end if
    call obb.show i
  next i
  call obb.show 37
wait
[quit]
  close #m
end

end
function dot( a,b , c,d )
  dot = a * c + b * d
end function
sub obb.show no
  cx0 = obb( no , corner + x )
  cy0 = obb( no , corner + y )
  cx1 = obb( no , corner + 2 + x )
  cy1 = obb( no , corner + 2 + y )
  cx2 = obb( no , corner + 4 + x )
  cy2 = obb( no , corner + 4 + y )
  cx3 = obb( no , corner + 6 + x )
  cy3 = obb( no , corner + 6 + y )
  #m "down"
  #m "line ";cx0;" ";cy0;" ";cx1;" ";cy1
  #m "line ";cx1;" ";cy1;" ";cx2;" ";cy2
  #m "line ";cx2;" ";cy2;" ";cx3;" ";cy3
  #m "line ";cx3;" ";cy3;" ";cx0;" ";cy0
  #m "up"
end sub
function obb.hit1way( this , other )
  uit = true
  for a = 0 to 1
    ax = obb( this , axes + a * 2 + x )
    ay = obb( this , axes + a * 2 + y )
    cx = obb( other , corner + x )
    cy = obb( other , corner + y )
    t = dot( ax , ay , cx , cy )
    tmin = t
    tmax = t
    for c = 0 to 3
      ax = obb( this , axes + a * 2 + x )
      ay = obb( this , axes + a * 2 + y )
      cx = obb( other , corner + c * 2 + x )
      cy = obb( other , corner + c * 2 + y )
      if t < tmin then
        tmin = t
      else
        if t > tmax then
          tmax = t
        end if
      end if
    next c
    o = obb( this , org + a )
    if tmin > 1 + o or tmax < o then
      uit = false
    end if
  next a
  obb.hit1way = uit
end function
function obb.hit( a , b )
  obb.hit = obb.hit1way( a , b ) _
  and obb.hit1way( b , a )
end function
sub obb.move no , dx , dy
  for i = 0 to 3
    a = obb( no , corner + i * 2 + x )
    b = obb( no , corner + i * 2 + y )
    a = a + dx
    b = b + dy
    obb( no , corner + i * 2 + x ) = a
    obb( no , corner + i * 2 + y ) = b
  next i
  call calcAxes no
end sub
sub calcAxes no
  cx0 = obb( no , corner + x )
  cy0 = obb( no , corner + y )
  cx1 = obb( no , corner + 2 + x )
  cy1 = obb( no , corner + 2 + y )
  cx3 = obb( no , corner + 6 + x )
  cy3 = obb( no , corner + 6 + y )
  ax0 = cx1 - cx0
  ay0 = cy1 - cy0
  ax1 = cx3 - cx0
  ay1 = cy3 - cy0
  l = dot( ax0 , ay0 , ax0 , ay0 ) + 1e-5
  ax0 = ax0 / l
  ay0 = ay0 / l
  o0 = dot( ax0 , ay0 , cx0 , cy0 )
  l = dot( ax1 , ay1 , ax1 , ay1 ) + 1e-5
  ax1 = ax1 / l
  ay1 = ay1 / l
  o1 = dot( ax1 , ay1 , cx0 , cy0 )
  obb( no , axes + x ) = ax0
  obb( no , axes + y ) = ax0
  obb( no , axes + 2 + x ) = ax1
  obb( no , axes + 2 + y ) = ax1
  obb( no , org ) = o0
  obb( no , org + 1 ) = o1
end sub
sub obb.fill no , cx , cy , w , h , deg
  ax = cos( rad( deg ) )
  ay = sin( rad( deg ) )
  bx = cos( rad( deg ) )
  by = 0-sin( rad( deg ) )
  ax = ax * w / 2
  ay = ay * w / 2
  bx = bx * h / 2
  by = by * h / 2
  obb( no , corner + x ) = cx - ax - bx
  obb( no , corner + y ) = cy - ay - by
  obb( no , corner + 2 + x ) = cx + ax - bx
  obb( no , corner + 2 + y ) = cy + ay - by
  obb( no , corner + 4 + x ) = cx + ax + bx
  obb( no , corner + 4 + y ) = cy + ay + by
  obb( no , corner + 6 + x ) = cx - ax + bx
  obb( no , corner + 6 + y ) = cy - ay + by
  call calcAxes no
end sub
function rad( deg )
  rad = deg * pi / 180
end function
 
User IP Logged

bluatigro
Full Member
ImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 111
xx Re: OBB 2D + OBB 2D colision
« Reply #1 on: Nov 11th, 2015, 09:55am »


update :
- shape error fixed

error :
- no colision detected
Code:
dim obb( 37 , 12 )
global corner , axes , org , x , y , pi
global true , false
false = 0
true = not( false )
corner = 0
axes = 8
org = 10
x = 0
y = 1
pi = atn( 1 ) * 4
WindowWidth = DisplayWidth
WindowHeight = DisplayHeight
global winx , winy
winx = WindowWidth
winy = WindowHeight
nomainwin
open "obb 2d" for graphics as #m
  #m "trapclose [quit]"
  #m "size 5"
  for i = 0 to 36
    call obb.fill i , winx / 6 , winy / 2 _
    , 50 , 100 , i * 10
  next i
  call obb.fill 37 , winx * 5 / 6 , winy / 2 _
  , 50 , 100 , 15
  timer 100 , [timer]
wait
[timer]
  #m "cls"
  for i = 0 to 36
    if not( obb.hit( i , 37 ) ) then
      call obb.move i , 5 , 0
    end if
    call obb.show i
  next i
  call obb.show 37
wait
[quit]
  close #m
end

end
function dot( a,b , c,d )
  dot = a * c + b * d
end function
sub obb.show no
  cx0 = obb( no , corner + x )
  cy0 = obb( no , corner + y )
  cx1 = obb( no , corner + 2 + x )
  cy1 = obb( no , corner + 2 + y )
  cx2 = obb( no , corner + 4 + x )
  cy2 = obb( no , corner + 4 + y )
  cx3 = obb( no , corner + 6 + x )
  cy3 = obb( no , corner + 6 + y )
  #m "down"
  #m "line ";cx0;" ";cy0;" ";cx1;" ";cy1
  #m "line ";cx1;" ";cy1;" ";cx2;" ";cy2
  #m "line ";cx2;" ";cy2;" ";cx3;" ";cy3
  #m "line ";cx3;" ";cy3;" ";cx0;" ";cy0
  #m "up"
end sub
function obb.hit1way( this , other )
  uit = true
  for a = 0 to 1
    ax = obb( this , axes + a * 2 + x )
    ay = obb( this , axes + a * 2 + y )
    cx = obb( other , corner + x )
    cy = obb( other , corner + y )
    t = dot( ax , ay , cx , cy )
    tmin = t
    tmax = t
    for c = 0 to 3
      ax = obb( this , axes + a * 2 + x )
      ay = obb( this , axes + a * 2 + y )
      cx = obb( other , corner + c * 2 + x )
      cy = obb( other , corner + c * 2 + y )
      if t < tmin then
        tmin = t
      else
        if t > tmax then
          tmax = t
        end if
      end if
    next c
    o = obb( this , org + a )
    if tmin > 1 + o or tmax < o then
      uit = false
    end if
  next a
  obb.hit1way = uit
end function
function obb.hit( a , b )
  obb.hit = obb.hit1way( a , b ) _
  and obb.hit1way( b , a )
end function
sub obb.move no , dx , dy
  for i = 0 to 3
    a = obb( no , corner + i * 2 + x )
    b = obb( no , corner + i * 2 + y )
    a = a + dx
    b = b + dy
    obb( no , corner + i * 2 + x ) = a
    obb( no , corner + i * 2 + y ) = b
  next i
  call calcAxes no
end sub
sub calcAxes no
  cx0 = obb( no , corner + x )
  cy0 = obb( no , corner + y )
  cx1 = obb( no , corner + 2 + x )
  cy1 = obb( no , corner + 2 + y )
  cx3 = obb( no , corner + 6 + x )
  cy3 = obb( no , corner + 6 + y )
  ax0 = cx1 - cx0
  ay0 = cy1 - cy0
  ax1 = cx3 - cx0
  ay1 = cy3 - cy0
  l = dot( ax0 , ay0 , ax0 , ay0 ) + 1e-5
  ax0 = ax0 / l
  ay0 = ay0 / l
  o0 = dot( ax0 , ay0 , cx0 , cy0 )
  l = dot( ax1 , ay1 , ax1 , ay1 ) + 1e-5
  ax1 = ax1 / l
  ay1 = ay1 / l
  o1 = dot( ax1 , ay1 , cx0 , cy0 )
  obb( no , axes + x ) = ax0
  obb( no , axes + y ) = ax0
  obb( no , axes + 2 + x ) = ax1
  obb( no , axes + 2 + y ) = ax1
  obb( no , org ) = o0
  obb( no , org + 1 ) = o1
end sub
sub obb.fill no , cx , cy , w , h , angle
  x1 = w / 2
  y1 = h / 2
  x2 = 0 - w / 2
  y2 = h / 2
  x3 = 0 - w / 2
  y3 = 0 - h / 2
  x4 = w / 2
  y4 = 0 - h / 2
  call rotate x1 , y1 , angle
  call rotate x2 , y2 , angle
  call rotate x3 , y3 , angle
  call rotate x4 , y4 , angle
  obb( no , corner + x ) = cx + x1
  obb( no , corner + y ) = cy + y1
  obb( no , corner + 2 + x ) = cx + x2
  obb( no , corner + 2 + y ) = cy + y2
  obb( no , corner + 4 + x ) = cx + x3
  obb( no , corner + 4 + y ) = cy + y3
  obb( no , corner + 6 + x ) = cx + x4
  obb( no , corner + 6 + y ) = cy + y4
  call calcAxes no
end sub
function rad( deg )
  rad = deg * pi / 180
end function
sub rotate byref k , byref l , deg
  s = sin( rad( deg ) )
  c = cos( rad( deg ) )
  hk = k * c - l * s
  hl = k * s + l * c
  k = hk
  l = hl
end sub
 

translated from freebasic
Code:
screen 20 , 32 , 2
type t2d
public :
  dim as double x , y
  declare constructor ( nx as double = 0 , ny as double = 0 )
  declare sub fill( nx as double , ny as double )
  declare function dot( r as t2d ) as double
  declare function squaredLenght() as double
end type

constructor t2d( nx as double , ny as double )
  x = nx
  y = ny
end constructor 

sub t2d.fill( nx as double , ny as double )
  x = nx
  y = ny
end sub

function t2d.dot( r as t2d ) as double
  return  x * r.x + y * r.y 
end function 

function t2d.squaredLenght() as double
  return x ^ 2 + y ^ 2 
end function

operator + ( a as t2d , b as t2d ) as t2d
  return type( a.x + b.x , a.y + b.y )
end operator 

operator - ( a as t2d , b as t2d ) as t2d
  return type( a.x - b.x , a.y - b.y )
end operator 

operator * ( v as t2d , f as double ) as t2d
  return type( v.x * f , v.y * f )
end operator

operator / ( v as t2d , f as double ) as t2d
  return type( v.x / f , v.y / f )
end operator

const as integer false = 0
const as integer true = not false
const as double pi = atn( 1 ) * 4

function rad( gr as double ) as double
  return gr * pi / 180 
end function


type obb2d
private :
  dim as t2d corner( 4 ) , axis( 2 )
  dim as double origin( 2 )
  declare function hit1way( other as obb2d ) as integer 
  declare sub computeAxis()
public :
  declare constructor 
  declare sub fill( cx as double , cy as double _
  , w as double , h as double , angle as double )
  declare function hit( other as obb2d ) as integer 
  declare sub move( dx as double , dy as double ) 
  declare sub drawit( kl as integer )
end type 

constructor obb2d
end constructor

sub obb2d.fill( cx as double , cy as double  _
, w as double , h as double , angle as double )
  dim a as t2d , center as t2d
  a.fill cos( angle ) , sin( angle )
  dim b as t2d
  b.fill -sin( angle ) , cos( angle ) 
  center.fill cx , cy
  a *= w / 2
  b *= h / 2
  corner( 0 ) = center - a - b
  corner( 1 ) = center + a - b
  corner( 2 ) = center + a + b
  corner( 3 ) = center - a + b
  computeAxis
end sub

function obb2d.hit1way( other as obb2d ) as integer
  dim as integer a , c
  dim as double t , tMin , tMax
  for a = 0 to 1
    t = other.corner( 0 ).dot( axis( a ) )
    tMin = t
    tMax = t
    for c = 0 to 3
      t = other.corner( c ).dot( axis( a ) )
      if t < tMin then
        tMin = t
      else
        if t > tMax then
          tMax = t
        end if
      end if
    next c
    if ( tMin > 1 + origin( a ) ) or ( tMax < origin( a ) ) then
      return false
    end if
  next a
  return true
end function

sub obb2d.computeAxis()
  axis( 0 ) = corner( 1 ) - corner( 0 )
  axis( 1 ) = corner( 3 ) - corner( 0 )
  dim i as integer
  for i = 0 to 1
    axis( i ) /= axis( i ).squaredLenght()
    origin( i ) = corner( 0 ).dot( axis( i ) )
  next i
end sub

function obb2d.hit( other as obb2d ) as integer
  return hit1way( other ) and other.hit1way( this )
end function

sub obb2d.move( dx as double , dy as double )
  dim i as integer , m as t2d
  m.fill dx , dy
  for i = 0 to 3
    corner( i ) += m
  next i
  computeAxis
end sub

sub obb2d.drawit( kl as integer )
  line ( corner( 0 ).x , corner( 0 ).y ) _
       -( corner( 1 ).x , corner( 1 ).y ) , kl
  line ( corner( 1 ).x , corner( 1 ).y ) _
       -( corner( 2 ).x , corner( 2 ).y ) , kl
  line ( corner( 2 ).x , corner( 2 ).y ) _
       -( corner( 3 ).x , corner( 3 ).y ) , kl
  line ( corner( 3 ).x , corner( 3 ).y ) _
       -( corner( 0 ).x , corner( 0 ).y ) , kl
end sub


function rainbow( x as double ) as integer
  return rgb( sin( x ) * 127 + 128 _
            , sin( x + pi * 2 / 3 ) * 127 + 128 _
            , sin( x - pi * 2 / 3 ) * 127 + 128 )
end function


dim i as integer
dim a( 20 ) as obb2d
for i = 0 to 20
  a( i ).fill 200 , 350 , 100 , 200 , pi/20*i
next i
dim b as obb2d
b.fill 800 , 350 , 100 , 200 , -1 
dim in as string
screenset 1 , 0
do 
  cls
  for i = 0 to 20
    if not a( i ).hit( b ) then
      a( i ).move 1 , 0
    end if
  next i
  for i = 0 to 20
    a( i ).drawit rainbow( i * pi / 10 )
  next i
  b.drawit rgb( 255 , 255 , 255 )
  sleep 40
  flip
  in = inkey
loop while in = ""
  

User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls