Does exist a lib to simulate magnet ?

Blitz3D Forums/Blitz3D Userlibs/Does exist a lib to simulate magnet ?

patmaba(Posted 2007) [#1]
Hi,

Where can i found a blitz3d lib to simulate physic magnet into b3d application ?

Thanks

Patmaba


CodeGit(Posted 2007) [#2]
http://rubux.net


patmaba(Posted 2007) [#3]
thanks


patmaba(Posted 2007) [#4]
Someone have an example to simulate 2 coin of neadym magnet in blitz3d ?

Thanks


mike950(Posted 2007) [#5]
Hi,
I just came up with a quick magnet demo using my Box2d Wrapper..
AppTitle "box 2d wrapper (magnet demo)"
;
; Box 2d Wrapper for Blitz3d Magnet Demo
; Copyright 2007 Mid Atlantic Engineering
; https://order.kagi.com/cgi-bin/store.cgi?storeID=6XD
;
; download:
; http://skillroll.com/b2dwrapper/box2dwrapper.zip
;



Graphics3D 800,600,0,2
Color 34,206,54

Global bodies[10]
Global world = b2d_create_world (-1000,-1000,1000,1000,0,0,0)

Const wall_rx 		= 800
Const wall_lx 		= 0
Const wall_rl_y		= 300
Const wall_by 		= 600
Const wall_ty 		= 0
Const wall_bt_x		= 400
Const wall_w		= 400
Const wall_h		= 20

Const num_objs		= 10
Const obj_radius	= 25

Const mag_radius	= 10
Const mag_strength#	= 10
Const mag_size#		= 5

mag_x# = GraphicsWidth ()/2
mag_y# = GraphicsHeight ()/2

sd = b2d_create_box_shape_def (wall_w, wall_h)
b2d_shape_def_set_density sd,0.0
bd = b2d_create_body_def ()
b2d_add_shape bd,sd
b2d_free_shape_def sd

b2d_body_def_set_position bd, wall_bt_x, wall_by
b2d_create_body world, bd
b2d_body_def_set_position bd, wall_bt_x, wall_ty
b2d_create_body world, bd

b2d_body_def_set_rotation bd, Pi/2
b2d_body_def_set_position bd, wall_lx, wall_rl_y
b2d_create_body world, bd
b2d_body_def_set_position bd, wall_rx, wall_rl_y
b2d_create_body world, bd
b2d_free_body_def bd


sd = b2d_create_circle_shape_def (obj_radius)
b2d_shape_def_set_density sd,1.0

bd = b2d_create_body_def ()
b2d_add_shape bd,sd
b2d_free_shape_def sd
For i = 0 To num_objs-1
	b2d_body_def_set_position bd, Rand (wall_lx+200,wall_rx-200), Rand (wall_ty+100,wall_by-100)
	b = b2d_create_body (world, bd)
	b2d_set_linear_vel b,Rand(-10,10),Rand (-10,10)
	bodies[i] = b
Next 
b2d_free_body_def bd


sd = b2d_create_circle_shape_def (mag_radius)
b2d_shape_def_set_density sd, .5

bd = b2d_create_body_def ()
b2d_body_def_set_position bd, mag_x, mag_y
b2d_add_shape bd,sd
b2d_free_shape_def sd
magnet = b2d_create_body (world, bd)



While Not KeyHit (1)

	If MouseHit (1)
		mx = MouseX ()
		my = MouseY ()
		b2d_mouse_down (world,mx,my)
	End If 

	If MouseDown (1)
		mx = MouseX ()
		my = MouseY ()
		b2d_mouse_move mx,my
		mouse_pressed_flag = True
	Else If mouse_pressed_flag
		b2d_mouse_up world
		mouse_pressed_flag 	= False
	End If

	Cls

	For i=0 To num_objs-1
		mag_x   = b2d_get_body_x (magnet)
		mag_y   = b2d_get_body_y (magnet)
		x# 		= b2d_get_body_x (bodies[i])
		y# 		= b2d_get_body_y (bodies[i])
		vx#		= b2d_get_body_linear_velocity_x (bodies[i])
		vy#		= b2d_get_body_linear_velocity_y (bodies[i])
		dx# 	= x - mag_x
		dy#		= y - mag_y
		dist# 	= Sqr((x-mag_x)*(x-mag_x)+(y-mag_y)*(y-mag_y))
		ratio#  = dist/(1.5*mag_size)
		force#	= mag_strength*Exp(-0.2/ratio)/(ratio*ratio*56) * 100
		vx		= (vx - dx * force/dist)
		vy		= (vy - dy * force/dist)

		b2d_set_linear_vel bodies[i],vx,vy
	Next 

	b2d_step world, .5, 10

	DrawBodies()

	;
	; draw magnet
	;
	Color 255,0,0
	x# = b2d_get_body_x (magnet) 
	y# = b2d_get_body_y (magnet) 
	Oval x-mag_radius,y-mag_radius, mag_radius*2, mag_radius*2, 1

	Flip 
Wend 


b2d_delete_world world
world = 0

EndGraphics


Function DrawBodies()
	Color 34,206,54
	For i=0 To num_objs-1
		x# 		= b2d_get_body_x (bodies[i]) 
		y# 		= b2d_get_body_y (bodies[i]) 
		Oval x-obj_radius, y-obj_radius, obj_radius*2, obj_radius*2, 0
	Next
End Function 



Mike
http://skillroll.com/b2dwrapper/


patmaba(Posted 2007) [#6]
thanks,

But with physics i have done the folliwing code but without success.

Graphics3D 640,400,16,2
SetBuffer BackBuffer()

Global camera=CreateCamera()

Global plane=CreatePlane()
EntityColor plane,50,50,200

Global light=CreateLight()
RotateEntity light,90,0,0

Global pivot=CreatePivot()
PositionEntity pivot ,0,0,0

;=======PhysX=====================
pxCreateWorld(0,"key")					
pxSetGravity(0,-9.81,0)
;=================================

; Create cube
n=0
For l = 1 To 3
	For a# = 1 To 360 Step 20	
		CreateNeoDym( Cos(a#)*10, n, Sin(a#)*10, 0 )
		n = n +1	
	Next 	
Next 

PositionEntity camera, 0,10,-120

While Not KeyDown( 1 )
	UpdateNeoDym()
	RenderWorld
    pxRenderPhysic(30,0)
	Flip
Wend

pxDestroyWorld()
End

Type TNeoDym_Magnet
	Field Px
	Field mesh%
End Type 

Function CreateNeoDym( pX, pY, pZ, pPivot=0 )
	Local l.TNeoDym_Magnet = New TNeoDym_Magnet
	If pPivot > 0 Then 
		l\mesh = CreateSphere(8,pPivot)
	Else
		l\mesh = CreateSphere(8)
	EndIf
 
    l\pX=pxCreateMagnet(1, 50, 100)
    pxMagnetSetMaxRadius( l\pX, 200)
    pxMagnetSetMinRadius( l\pX, 205)
	pxMagnetSetPosition(l\pX,pX, pY, pZ)       
    pxMagnetActivate(l\pX, 1, 1)
	PositionEntity l\mesh, pX, pY, pZ	
	Return Handle( l )
End Function 


Function UpdateNeoDym( )
	For l.TNeoDym_Magnet = Each TNeoDym_Magnet
		PositionEntity l\mesh, pxMagnetGetPositionX( l\pX),pxMagnetGetPositionY( l\pX),pxMagnetGetPositionZ( l\pX)
	Next
End Function 



mike950(Posted 2007) [#7]
The physx wrapper is excellent!
I don't think magnets are included in
the demo version?
Mike


patmaba(Posted 2007) [#8]
oh


Tab(Posted 2007) [#9]
@patmaba

Try something like...

Type TNeoDym_Magnet
	Field Px, Body
	Field mesh%
End Type 

Function CreateNeoDym( pX, pY, pZ, pPivot=0 )
	Local l.TNeoDym_Magnet = New TNeoDym_Magnet
	If pPivot > 0 Then 
		l\mesh = CreateSphere(8,pPivot)
	Else
		l\mesh = CreateSphere(8)
	EndIf
 
	l\Body=pxBodyCreateCube(.1,.1,.1,10)
 	pxBodySetPosition(l\Body,pX, pY, pZ)       
 
 
    l\Px=pxCreateMagnet(1, 50, 100)
    pxMagnetSetMaxRadius( l\Px, 200)
    pxMagnetSetMinRadius( l\Px, 205)
	pxMagnetSetPosition(l\Px,pX, pY, pZ)       
 
	
	PositionEntity l\mesh, pX, pY, pZ	
	Return Handle( l )
End Function 


Function UpdateNeoDym( )
	For l.TNeoDym_Magnet = Each TNeoDym_Magnet
		pxBodySetEntity l\mesh,l\Body
		pxMagnetSetPosition l\pX, pxBodyGetPositionX( l\Body),pxBodyGetPositionY( l\Body),pxBodyGetPositionZ( l\Body)
		pxMagnetActivate(l\Px, 1, 1)
	Next
End Function 



patmaba(Posted 2007) [#10]
Thansk , it's moving now


Barbapapa(Posted 2007) [#11]
may I please ask a few questions regarding this wrapper and especially the magnets.

I tried this wrapper with BMax/MiniB3D and it seems to work really fast. Now I would like to know how many magnets I can maximum use. Let me explain or maybe you have already read about it here


Imagine having a big sphere. In this sphere you have many small spheres flying around.

The big outer sphere should attract the small inner spheres towards its hull, now the funny behavior, spheres in the middle should move faster than those at the hull of the big sphere, some kind of inverse attraction.

The smaller spheres should get attracted or repulsed by each other.

So I have two forces or movements, one attracting all little spheres towards the hull of the big surrounding sphere - getting slower towards the hull - and then I have the forces between the small spheres?

Can I use magnets for this?
Can I have ~1000 little spheres without needing 5 min/frame


Stevie G(Posted 2007) [#12]
You don't need a physics engine to re-create magnets in the way you need, besides - most engines assume that a magnet is a point in space.

For example, B3d code, which doesn't work off the bat but you get the idea.

Const BSx# = 0
Const BSy# = 0
Const BSradius# = 500
Const BSmagneticforce# = 10
Const Pmagneticforce# = 1
Const TIMESTEP# = .05

Type Particle
	Field x#, y#
	Field vx#, vy#
	Field fx#, fy#
End Type

.
.
.


For p.particle = Each particle

	;BIG OUTER SPHERE

	;normalise direction to big sphere ( BS ) outer radius
	Nx# = p\x - BSx
	Ny# = p\y - BSy
	D# = Sqr( Nx * Nx + Ny * Ny )
	Nx = Nx / D
	Ny = Ny / D
	;get distance to outer radius
	DistanceToBS# = BSradius - D
	;calculate inverse magnetic force
	Force# = BSmagneticforce / ( DistanceBS * DistanceBS ) 
	;accumulate force	
	p\fx = p\fx + Nx * Force
	p\fy = p\fy + Ny * Force
	
	;PARTICLES
	For q.particle = Each particle
		If q <> p
			;normalise direction to other particle
			Nx = q\x - p\x
			Ny = q\y - p\y
			D# = Sqr( Nx * Nx + Ny * Ny )
			Nx = Nx / D
			Ny = Ny / D
			Force# = Pmagneticforce / ( DistanceBS * DistanceBS ) 
			p\fx = p\fx + Nx * Force		
			p\fy = p\fy + Ny * Force		
			q\fx = q\fx - Nx * Force		
			q\fy = q\fy - Ny * Force		
		EndIf
	Next
	
	;add force to velocity
	p\vx = p\vx + p\Fx * TIMESTEP
	p\vy = p\vy + p\Fy * TIMESTEP
	
	;add velocity to position
	p\x = p\x + p\vx
	p\y = p\y + p\vy
	
	;reset forces
	p\fx = 0
	p\fy = 0
	
Next



Barbapapa(Posted 2007) [#13]
Hey cool, I thought the wrapper could be faster, more optimized than pure BlitzMax Code.

In my algorithms I didn't normalize the vectors like you did, is it important to do it?


Stevie G(Posted 2007) [#14]
Depends what your doing but in most cases yes.


Barbapapa(Posted 2007) [#15]
Yes I think I understand why, thanks!