More angle help required

Blitz3D Forums/Blitz3D Beginners Area/More angle help required

CyberHeater(Posted 2004) [#1]
I still can't believe I can't get this.

I'm trying to write a 3d track designer app and I'm stuck on this really simple thing. I can't see the wood for the trees.

Imagine your looking at a 2d grid where you can define anchor points. I've got a routine that will take the anchor points and create a spline line with calculated intermediate points to create a smooth curved track line.

The anchor points and intermediate co-ordinates are stored in a array draw_point(1000,2).

Here is a stripped down code bit for defining the anchor points.

Graphics3D 800,600,16,2

SetBuffer BackBuffer()
	
camPiv = CreatePivot()
camera = CreateCamera(camPiv)
PositionEntity(camera, 0,0,-1000)

CameraRange camera,1,9000

light=CreateLight()
RotateEntity light,100,100,1000



;set up a non visible cursor entity 
test_sphere=CreateSphere ()
ScaleMesh test_sphere,20,20,20
EntityColor test_sphere, 255,100,100
EntityAlpha test_sphere, 0.4 ;*** Transparece

CreateCube()

Global pivot=CreatePivot()
Global pivot2=CreatePivot()
Global campitch#,camyaw#,timer 
 
cam_z= -1000

;make_grid()

Dim pos(100,2) ;storage for the hand drawn lines.
Dim angles(100,2)


;Make_grid()

V_Pos = 0; the first start to array

; Mainloop
While Not KeyDown(1) 
   	Cls ; Clear screen

	;half of screen dimensions needed
	w=GraphicsWidth() :	h=GraphicsHeight()

	;Mouse Related bits;positions	
	x#=MouseX() : y#=MouseY()
	xs=MouseXSpeed() :	ys=MouseYSpeed() ; see how far the mouse has been moved 

	
	If MouseHit (1) Then
		PositionEntity test_sphere,(x-w)/w*2,-(y-h)/w*2,2
		PositionEntityFrom2D (camera, test_sphere, x, y, 0, 1)
		pos(V_Pos, 0) = EntityX (test_sphere)
		pos(V_Pos, 1) = EntityY (test_sphere)
		pos(V_Pos, 2) = EntityZ (test_sphere)
		V_Pos=V_Pos + 1
	EndIf

	;move the screen If mouse down
	If MouseDown (3) Then 
		xview = xview + xs * cam_z/300
		yview = yview - ys * cam_z/200

	End If
	
	cam_z = cam_z+MouseZSpeed()*80; move the depth and ramp with distance
		

	PositionEntity camera,xview,yview,cam_z

	RenderWorld

	If V_Pos > 1 Then
		For loop = 1 To V_Pos-1
			Line3d(pos(loop-1, 0),pos(loop-1, 1),0,pos(loop, 0),pos(loop, 1),0, camera)
		Next
	EndIf
	

	For loop = 1 To V_Pos-1
		PositionEntity pivot, pos(loop-1, 0),pos(loop-1, 1),0
		PositionEntity pivot2,pos(loop, 0),pos(loop, 1),0
		x1 = EntityX (pivot)
		y1 = EntityY (pivot)
	
		PointEntity pivot,pivot2,0
		
		TFormPoint 0,-30,0,pivot,0
		x1 = TFormedX() 
		y1 = TFormedY() 
		z1 = TFormedZ()
		TFormPoint 0,30,0,pivot,0
		x2 = TFormedX() 
		y2 = TFormedY() 
		z2 = TFormedZ()
		Line3d(x1,y1,z1,x2,y2,z2, camera)
	Next

   	Flip ; Flip backbuffer to frontbuffer 
Wend 
End

Function PositionEntityFrom2D (usecam, entity, x2d#, y2d#, positionGlobal = 0, camZoom# = 1)
	gw = GraphicsWidth ()
	gh = GraphicsHeight ()
	x# = -((gw / 2) - x2d)
	y# = (gh / 2) - y2d
	parent = GetParent (entity)
	EntityParent entity, usecam
	z3d# = Abs (EntityZ (entity))
	div# = (gw / (2 / camzoom)) / z3d
	PositionEntity entity, x / div, y / div, z3d, positionGlobal
	EntityParent entity, parent
End Function

Function Line3d(x0#,y0#,z0#,x1#,y1#,z1#, camera)
	CameraProject (camera,x0,y0,z0)
	px0#=ProjectedX# ( ) 
	py0#=ProjectedY# ( ) 
	pz0#=ProjectedZ# ( ) 

	CameraProject (camera,x1,y1,z1)
	If ProjectedZ#( ) >0 And pz0>0 Then Line px0,py0,ProjectedX# ( ) ,ProjectedY# ( ) 
End Function



;=================================================================================
;Point Entity at x,y,z
;=================================================================================
Function Point_Entity(entity,x,y,z)
	
	xdiff = EntityX(entity)-x
	ydiff = EntityY(entity)-y
	zdiff = EntityZ(entity)-z
	dist=Sqr((xdiff*xdiff)+(zdiff*zdiff))
	pitch = ATan2(ydiff,dist)
	yaw   = ATan2(xdiff,-zdiff)
	RotateEntity entity,pitch,yaw,0

End Function



If the first point is drawn a the centre of the screen. The second point a few inches directly above it and the third point directly to the right of it you should see a right angled shape but the little line formed at point 2 is pointing directly at point 3 and rotated thru 90 degrees.
Ideally, I would like this small line to be rotated to form a angle exactly half of the diffence between the two lines so I can attach vertex information to the end points and create a track.

How do I go about doing this. I'm really stuck.

What I get is this:-

|-----
|
|
|

When I really what this

\----
|
|
|


Jeppe Nielsen(Posted 2004) [#2]
I think this does, what you want:

Graphics3D 800,600,16,2

SetBuffer BackBuffer()
	
camPiv = CreatePivot()
camera = CreateCamera(camPiv)
PositionEntity(camera, 0,0,-1000)

CameraRange camera,1,9000

light=CreateLight()
RotateEntity light,100,100,1000



;set up a non visible cursor entity 
test_sphere=CreateSphere ()
ScaleMesh test_sphere,20,20,20
EntityColor test_sphere, 255,100,100
EntityAlpha test_sphere, 0.4 ;*** Transparece

CreateCube()

Global pivot=CreatePivot()
Global pivot2=CreatePivot()
Global campitch#,camyaw#,timer 
 
cam_z= -1000

;make_grid()

Dim pos(100,2) ;storage for the hand drawn lines.
Dim angles(100,2)


;Make_grid()

V_Pos = 0; the first start to array

; Mainloop
While Not KeyDown(1) 
   	Cls ; Clear screen

	;half of screen dimensions needed
	w=GraphicsWidth() :	h=GraphicsHeight()

	;Mouse Related bits;positions	
	x#=MouseX() : y#=MouseY()
	xs=MouseXSpeed() :	ys=MouseYSpeed() ; see how far the mouse has been moved 

	
	If MouseHit (1) Then
		PositionEntity test_sphere,(x-w)/w*2,-(y-h)/w*2,2
		PositionEntityFrom2D (camera, test_sphere, x, y, 0, 1)
		pos(V_Pos, 0) = EntityX (test_sphere)
		pos(V_Pos, 1) = EntityY (test_sphere)
		pos(V_Pos, 2) = EntityZ (test_sphere)
		V_Pos=V_Pos + 1
	EndIf

	;move the screen If mouse down
	If MouseDown (3) Then 
		xview = xview + xs * cam_z/300
		yview = yview - ys * cam_z/200

	End If
	
	cam_z = cam_z+MouseZSpeed()*80; move the depth and ramp with distance
		

	PositionEntity camera,xview,yview,cam_z

	RenderWorld

	If V_Pos > 1 Then
		For loop = 1 To V_Pos-1
			Line3d(pos(loop-1, 0),pos(loop-1, 1),0,pos(loop, 0),pos(loop, 1),0, camera)
		Next
	EndIf
	

	For loop = 2 To V_Pos-1
	
		dx#=(pos(loop, 0)-pos(loop-1, 0))
		dy#=(pos(loop, 1)-pos(loop-1, 1))
		angle1#=ATan2(dy,dx)
					
		dx#=(pos(loop-2, 0)-pos(loop-1, 0))
		dy#=(pos(loop-2, 1)-pos(loop-1, 1))
		angle2#=ATan2(dy,dx)
		
		PositionEntity pivot, pos(loop-1, 0),pos(loop-1, 1),0
		RotateEntity pivot,0,0,90+(angle1+angle2)/2.0
				
		TFormPoint 0,-30,0,pivot,0
		x1 = TFormedX() 
		y1 = TFormedY() 
		z1 = TFormedZ()
		TFormPoint 0,30,0,pivot,0
		x2 = TFormedX() 
		y2 = TFormedY() 
		z2 = TFormedZ()
		Line3d(x1,y1,z1,x2,y2,z2, camera)
	Next

   	Flip ; Flip backbuffer to frontbuffer 
Wend 
End

Function PositionEntityFrom2D (usecam, entity, x2d#, y2d#, positionGlobal = 0, camZoom# = 1)
	gw = GraphicsWidth ()
	gh = GraphicsHeight ()
	x# = -((gw / 2) - x2d)
	y# = (gh / 2) - y2d
	parent = GetParent (entity)
	EntityParent entity, usecam
	z3d# = Abs (EntityZ (entity))
	div# = (gw / (2 / camzoom)) / z3d
	PositionEntity entity, x / div, y / div, z3d, positionGlobal
	EntityParent entity, parent
End Function

Function Line3d(x0#,y0#,z0#,x1#,y1#,z1#, camera)
	CameraProject (camera,x0,y0,z0)
	px0#=ProjectedX# ( ) 
	py0#=ProjectedY# ( ) 
	pz0#=ProjectedZ# ( ) 

	CameraProject (camera,x1,y1,z1)
	If ProjectedZ#( ) >0 And pz0>0 Then Line px0,py0,ProjectedX# ( ) ,ProjectedY# ( ) 
End Function



;=================================================================================
;Point Entity at x,y,z
;=================================================================================
Function Point_Entity(entity,x,y,z)
	
	xdiff = EntityX(entity)-x
	ydiff = EntityY(entity)-y
	zdiff = EntityZ(entity)-z
	dist=Sqr((xdiff*xdiff)+(zdiff*zdiff))
	pitch = ATan2(ydiff,dist)
	yaw   = ATan2(xdiff,-zdiff)
	RotateEntity entity,pitch,yaw,0

End Function



CyberHeater(Posted 2004) [#3]
Jeppe. I cannot thank you enough.

THANK YOU... :)