# PureBasic Forum

 It is currently Tue May 21, 2013 8:29 am

 All times are UTC + 1 hour

 Page 1 of 1 [ 3 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: function to plot 'A' letterPosted: Tue Jun 05, 2012 5:35 pm
 Enthusiast

Joined: Sun Jun 25, 2006 7:28 pm
Posts: 225
i want to show you the function to produce the 'A' letter in 3D space, it is:
yy=((1-Sign(-xx-0.9+Abs(zz*2)))/3*(Sign(0.9-xx)+1)/3)*(Sign(xx+0.65)+1)/2 -((1-Sign(-xx-0.39+Abs(zz*2)))/3*(Sign(0.9-xx)+1)/3) + ((1-Sign(-xx-0.39+Abs(zz*2)))/3*(Sign(0.6-xx)+1)/3)*(Sign(xx-0.35)+1)/2

i will use the example posted in the PB german forum by STARGÅTE called (ger to eng) "Drawing3D - unfinished code for drawing commands in 3D space"
http://forums.purebasic.com/german/viewtopic.php?f=10&t=22128
the function of A available on a site now closed but see it in web.archive.org here with other functions
http://web.archive.org/web/20110704054207/http://www.benjoffe.com/code/tools/functions3d/examples
in opengl i think we can texture it.
the benefits of the STARGÅTE example is that is has several 3D functions with an addon: the ability to move the camera viewpoint, rotation, and zoom in_out.
i want to use only the PLOT3D so i take it only from his big example, to plot the 'A' function, just use the (arrow keys and m,n) to rotate the graphics around the graphics own local coordinates and not the global coordinates, if someone provide a way to rotate it in the world coordinates will be great. i admit i'm poor in the 3D math envolved.
the image for the A function is this

to compare your PLOT3D with the PLOT3D of the mathematica wolfram alpha click here to plot the mathematica function Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}]
http://www.wolframalpha.com/input/?i=Plot3D%5BSin%5Bx+%2B+y%5E2%5D%2C+%7Bx%2C+-3%2C+3%7D%2C+%7By%2C+-2%2C+2%7D%5D

to plot it in the attached code comment the 'A' function and uncomment the "yy=Sin(xx+Pow(zz,2))" your Graphics should be like this:

the example uses a computaional heavy calculations, and it will slow down the pc if we choose the steps for xx,zz less than 0.05, so surely there are possible improvements, what about copying the results of the first calc to memory then after that the rotation, zooming, moving etc will apply to the matrix in the memory and not to calc again and again, just a suggestion.
note:use the mouse to move the Graphics, arrows +(m+n) to rotate, z+x to zoom
below is the STARGATE code, i have just plugged in the functions, and changing the arrow keys to rotate the Graphics in its place
Code:
Structure Drawing3D_Vector
x.f : y.f : z.f
EndStructure

Structure Drawing3D_Matrix
a.f[9]
EndStructure

Structure Drawing3D_Camera
FieldOfVision.f
Position.Drawing3D_Vector
Rotation.Drawing3D_Vector
View.Drawing3D_Matrix
EndStructure

Structure Drawing3D
Camera.Drawing3D_Camera
Rotation.Drawing3D_Vector
View.Drawing3D_Matrix
Distance.f
EndStructure

Macro Drawing3D_UpdateMatrix(Matrix, Rotation)
Matrix\a[0] = Cos(Rotation\y)*Cos(Rotation\z)
Matrix\a[1] = Cos(Rotation\y)*Sin(Rotation\z)
Matrix\a[2] = -Sin(Rotation\y)
Matrix\a[3] = Cos(Rotation\z)*Sin(Rotation\x)*Sin(Rotation\y)-Cos(Rotation\x)*Sin(Rotation\z)
Matrix\a[4] = Cos(Rotation\x)*Cos(Rotation\z)+Sin(Rotation\x)*Sin(Rotation\y)*Sin(Rotation\z)
Matrix\a[5] = Cos(Rotation\y)*Sin(Rotation\x)
Matrix\a[6] = Cos(Rotation\x)*Cos(Rotation\z)*Sin(Rotation\y)+Sin(Rotation\x)*Sin(Rotation\z)
Matrix\a[7] = -Cos(Rotation\z)*Sin(Rotation\x)+Cos(Rotation\x)*Sin(Rotation\y)*Sin(Rotation\z)
Matrix\a[8] = Cos(Rotation\x)*Cos(Rotation\y)
EndMacro

Macro Drawing3D_MatrixTimesVector(Result, Matrix, Vector)
Result\x = Vector\x * Matrix\a[0] + Vector\y * Matrix\a[1] + Vector\z * Matrix\a[2]
Result\y = Vector\x * Matrix\a[3] + Vector\y * Matrix\a[4] + Vector\z * Matrix\a[5]
Result\z = Vector\x * Matrix\a[6] + Vector\y * Matrix\a[7] + Vector\z * Matrix\a[8]
EndMacro

Macro Drawing3D_MoveVector(Vector, Move)
Vector\x + Move\x
Vector\y + Move\y
Vector\z + Move\z
EndMacro

Global Drawing3D.Drawing3D
With Drawing3D
Drawing3D_UpdateMatrix(\Camera\View, \Camera\Rotation)
Drawing3D_UpdateMatrix(\View, \Rotation)
\Camera\FieldOfVision = #PI/3
EndWith

Procedure StartDrawing3D(OutputID)
If StartDrawing(OutputID)
Drawing3D_UpdateMatrix(Drawing3D\Camera\View, Drawing3D\Camera\Rotation)
Drawing3D_UpdateMatrix(Drawing3D\View, Drawing3D\Rotation)
Drawing3D\Distance = Sqr(OutputWidth()*OutputWidth()+OutputHeight()*OutputHeight())/Tan(Drawing3D\Camera\FieldOfVision/2)/2
ProcedureReturn #True
EndIf
EndProcedure

Procedure StopDrawing3D()
StopDrawing()
EndProcedure

Procedure Drawing3DFieldOfVision(Angle)
Drawing3D\Camera\FieldOfVision = Angle*#PI/180
EndProcedure

Procedure Drawing3DCameraPosition(x.f, y.f, z.f, Mode=#PB_Absolute)
With Drawing3D\Camera\Position
If Mode = #PB_Absolute
\x = x : \y = y : \z = z
Else
\x + x : \y + y : \z + z
EndIf
EndWith
EndProcedure

Procedure Drawing3DRotation(x.f, y.f, z.f, Mode=#PB_Absolute)
With Drawing3D\Rotation
If Mode = #PB_Absolute
\x = x : \y = y : \z = z
Else
\x = x : \y = y : \z = z
EndIf
EndWith
Drawing3D_UpdateMatrix(Drawing3D\View, Drawing3D\Rotation)
EndProcedure

Procedure Drawing3DCameraRotation(x.f, y.f, z.f, Mode=#PB_Absolute)
With Drawing3D\Camera\Rotation
If Mode = #PB_Absolute
\x = x : \y = y : \z = z
Else
\x + x : \y + y : \z + z
EndIf
EndWith
Drawing3D_UpdateMatrix(Drawing3D\Camera\View, Drawing3D\Camera\Rotation)
EndProcedure

Procedure Plot3D(x.f, y.f, z.f, Color=#PB_Default)
Protected.Drawing3D_Vector Position, NewPosition, ViewPosition, Distance
Position\x = x : Position\y = y : Position\z = z
Drawing3D_MatrixTimesVector(Distance, Drawing3D\View, Position)
Drawing3D_MoveVector(Distance, -Drawing3D\Camera\Position)
Drawing3D_MatrixTimesVector(NewPosition, Drawing3D\Camera\View, Distance)
ViewPosition\x = NewPosition\x * Drawing3D\Distance / NewPosition\z + OutputWidth()*0.5
ViewPosition\y = NewPosition\y * Drawing3D\Distance / NewPosition\z + OutputHeight()*0.5
If NewPosition\z > 0
If ViewPosition\x >= 0 And ViewPosition\x < OutputWidth()-1 And ViewPosition\y >= 0 And ViewPosition\y < OutputHeight()-1
If Color=#PB_Default
Plot(ViewPosition\x, ViewPosition\y)
Else
Plot(ViewPosition\x, ViewPosition\y, Color)
EndIf
EndIf
EndIf
EndProcedure

InitSprite()
InitKeyboard()
InitMouse()

xP = 800
yP = 800
xP2 = xP/2
yP2 = yP/2

OpenWindow(0, 0, 0, xP, yP, "use mouse to move the plot, arrows +(m+n) to rotate, z+x to zoom", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, xP, yP, 0, 0, 0)

#Size = 15
PosZ.f = -#Size*4
rotX.f=0
rotY.f=0
rotZ.f=0

Procedure.f Tropfen(x.f, y.f, Phase.f)
ProcedureReturn Sin(Sqr(x*x+y*y)*0.5+Phase)*Sqr(1-x*x/#Size/#Size)*Sqr(1-y*y/#Size/#Size)*#Size/5
EndProcedure

Repeat

Delay(5)
WindowEvent()

ClearScreen(0)

Phase.f + 0.1

StartDrawing3D(ScreenOutput())
DrawingMode(1)
Drawing3DFieldOfVision(75)
Drawing3DCameraPosition(PosX, 0, PosZ)
Drawing3DRotation(rotX, rotY, rotZ, #PB_Relative)
; Punkte
xx.f=-3:zz.f=-2:yy.f=0
While zz<=2
While xx <=3
xx=xx+0.05
;yy=Sin(xx+Pow(zz,2))
;function of 'A':
yy=((1-Sign(-xx-0.9+Abs(zz*2)))/3*(Sign(0.9-xx)+1)/3)*(Sign(xx+0.65)+1)/2 -((1-Sign(-xx-0.39+Abs(zz*2)))/3*(Sign(0.9-xx)+1)/3) + ((1-Sign(-xx-0.39+Abs(zz*2)))/3*(Sign(0.6-xx)+1)/3)*(Sign(xx-0.35)+1)/2
Plot3D(xx*5, yy*5, zz*5, \$50F0A0)
Wend
xx=-3:zz=zz+0.05
Wend

Drawing3DCameraRotation(-MouseDeltaY()/100, MouseDeltaX()/100, 0, #PB_Relative)
StopDrawing3D()

FlipBuffers()

ExamineMouse()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape) : End : EndIf

If KeyboardPushed(#PB_Key_Z) : PosZ + 1 : EndIf
If KeyboardPushed(#PB_Key_X) : PosZ - 1 : EndIf
If KeyboardPushed(#PB_Key_Up) : rotX + 0.05 : EndIf
If KeyboardPushed(#PB_Key_Down) : rotX - 0.05 : EndIf
If KeyboardPushed(#PB_Key_Left) : rotY - 0.05 : EndIf
If KeyboardPushed(#PB_Key_Right) : rotY + 0.05 : EndIf
If KeyboardPushed(#PB_Key_M) : rotZ + 0.05 : EndIf
If KeyboardPushed(#PB_Key_N) : rotZ - 0.05 : EndIf

ForEver

Top

 Post subject: Re: function to plot 'A' letterPosted: Tue Jun 05, 2012 10:31 pm
 Enthusiast

Joined: Thu Jan 10, 2008 1:30 pm
Posts: 711
Location: Germany, Glienicke
Nice to see that my code will reuse.

I also have an update for my functions, here is the improved code.
Rotation of the scene is now with the mouse (press and hold to move):
(i have cut it for your example and use the canvas gadget):

Compile without debugger (so its faster)
Code:
Structure Drawing3D_Vector
x.f
y.f
z.f
EndStructure

Structure Drawing3D_Rotation Extends Drawing3D_Vector
EndStructure

Structure Drawing3D_Trigonometry
CosX.f : SinX.f
CosY.f : SinY.f
CosZ.f : SinZ.f
EndStructure

Structure Drawing3D_Matrix
a11.f : a12.f : a13.f
a21.f : a22.f : a23.f
a31.f : a32.f : a33.f
EndStructure

Structure Drawing3D_Camera
FieldOfVision.f
Position.Drawing3D_Vector
Trigonometry.Drawing3D_Trigonometry
Rotation.Drawing3D_Rotation
View.Drawing3D_Matrix
EndStructure

Structure Drawing3D
Camera.Drawing3D_Camera
Trigonometry.Drawing3D_Trigonometry
Rotation.Drawing3D_Rotation
View.Drawing3D_Matrix
Distance.f
EndStructure

Global Drawing3D.Drawing3D

Procedure Drawing3D_UpdateTrigonometry(*Trigonometry.Drawing3D_Trigonometry, *Rotation.Drawing3D_Rotation)
With *Trigonometry
\CosX = Cos(*Rotation\x) : \SinX = Sin(*Rotation\x)
\CosY = Cos(*Rotation\y) : \SinY = Sin(*Rotation\y)
\CosZ = Cos(*Rotation\z) : \SinZ = Sin(*Rotation\z)
EndWith
EndProcedure

Procedure Drawing3D_UpdateRotationMatrix(*Matrix.Drawing3D_Matrix, *Trigonometry.Drawing3D_Trigonometry)
With *Trigonometry
*Matrix\a11 =  \CosY*\CosZ
*Matrix\a12 =  \CosY*\SinZ
*Matrix\a13 = -\SinY
*Matrix\a21 =  \CosZ*\SinX*\SinY-\CosX*\SinZ
*Matrix\a22 =  \CosX*\CosZ+\SinX*\SinY*\SinZ
*Matrix\a23 =  \CosY*\SinX
*Matrix\a31 =  \CosX*\CosZ*\SinY+\SinX*\SinZ
*Matrix\a32 = -\CosZ*\SinX+\CosX*\SinY*\SinZ
*Matrix\a33 =  \CosX*\CosY
EndWith
EndProcedure

Procedure Drawing3D_MatrixTimesMatrix(*Result.Drawing3D_Matrix, *MatrixL.Drawing3D_Matrix, *MatrixR.Drawing3D_Matrix)
Protected Matrix.Drawing3D_Matrix
If *Result = *MatrixL
CopyMemory(*MatrixL, Matrix, SizeOf(Drawing3D_Matrix))
*MatrixL = @Matrix
ElseIf *Result = *MatrixR
CopyMemory(*MatrixR, Matrix, SizeOf(Drawing3D_Matrix))
*MatrixR = @Matrix
EndIf
With *Result
\a11 = *MatrixL\a11**MatrixR\a11 + *MatrixL\a12**MatrixR\a21 + *MatrixL\a13**MatrixR\a31
\a12 = *MatrixL\a11**MatrixR\a12 + *MatrixL\a12**MatrixR\a22 + *MatrixL\a13**MatrixR\a32
\a13 = *MatrixL\a11**MatrixR\a13 + *MatrixL\a12**MatrixR\a23 + *MatrixL\a13**MatrixR\a33
\a21 = *MatrixL\a21**MatrixR\a11 + *MatrixL\a22**MatrixR\a21 + *MatrixL\a23**MatrixR\a31
\a22 = *MatrixL\a21**MatrixR\a12 + *MatrixL\a22**MatrixR\a22 + *MatrixL\a23**MatrixR\a32
\a23 = *MatrixL\a21**MatrixR\a13 + *MatrixL\a22**MatrixR\a23 + *MatrixL\a23**MatrixR\a33
\a31 = *MatrixL\a31**MatrixR\a11 + *MatrixL\a32**MatrixR\a21 + *MatrixL\a33**MatrixR\a31
\a32 = *MatrixL\a31**MatrixR\a12 + *MatrixL\a32**MatrixR\a22 + *MatrixL\a33**MatrixR\a32
\a33 = *MatrixL\a31**MatrixR\a13 + *MatrixL\a32**MatrixR\a23 + *MatrixL\a33**MatrixR\a33
EndWith
EndProcedure

Procedure Drawing3D_MatrixTimesVector(*Result.Drawing3D_Vector, *Matrix.Drawing3D_Matrix, *Vector.Drawing3D_Vector)
Protected Vector.Drawing3D_Vector
If *Result = *Vector
CopyMemory(*Vector, Vector, SizeOf(Drawing3D_Vector))
*Vector = @Vector
EndIf
With *Rotation
*Result\x = *Matrix\a11**Vector\x + *Matrix\a12**Vector\y + *Matrix\a13**Vector\z
*Result\y = *Matrix\a21**Vector\x + *Matrix\a22**Vector\y + *Matrix\a23**Vector\z
*Result\z = *Matrix\a31**Vector\x + *Matrix\a32**Vector\y + *Matrix\a33**Vector\z
EndWith
EndProcedure

Macro Drawing3D_MoveVector(Vector, Move)
Vector\x + Move\x
Vector\y + Move\y
Vector\z + Move\z
EndMacro

Procedure StartDrawing3D(OutputID)
If StartDrawing(OutputID)
Drawing3D\Distance = Sqr(OutputWidth()*OutputWidth()+OutputHeight()*OutputHeight())/Tan(Drawing3D\Camera\FieldOfVision/2)/2
ProcedureReturn #True
EndIf
EndProcedure

Procedure StopDrawing3D()
StopDrawing()
EndProcedure

Procedure Drawing3DFieldOfVision(Angle.f)
EndProcedure

Procedure Drawing3DCameraPosition(x.f, y.f, z.f, Mode=#PB_Absolute)
With Drawing3D\Camera\Position
If Mode = #PB_Absolute
\x = x : \y = y : \z = z
Else
\x + x : \y + y : \z + z
EndIf
EndWith
EndProcedure

Procedure Drawing3DRotation(x.f, y.f, z.f, Mode=#PB_Absolute)
With Drawing3D\Rotation
If Mode = #PB_Absolute
Else
EndIf
EndWith
Drawing3D_UpdateTrigonometry(Drawing3D\Trigonometry, Drawing3D\Rotation)
Drawing3D_UpdateRotationMatrix(Drawing3D\View, Drawing3D\Trigonometry)
EndProcedure

Procedure Drawing3DViewRotation(x.f, y.f, z.f)
Protected Rotation.Drawing3D_Rotation
Protected Trigonometry.Drawing3D_Trigonometry
Protected Matrix.Drawing3D_Matrix
Drawing3D_UpdateTrigonometry(Trigonometry, Rotation)
Drawing3D_UpdateRotationMatrix(Matrix, Trigonometry)
Drawing3D_MatrixTimesMatrix(Drawing3D\View, Matrix, Drawing3D\View)
EndProcedure

Procedure Drawing3DCameraRotation(x.f, y.f, z.f, Mode=#PB_Absolute)
With Drawing3D\Camera\Rotation
If Mode = #PB_Absolute
Else
EndIf
EndWith
Drawing3D_UpdateTrigonometry(Drawing3D\Camera\Trigonometry, Drawing3D\Camera\Rotation)
Drawing3D_UpdateRotationMatrix(Drawing3D\Camera\View, Drawing3D\Camera\Trigonometry)
EndProcedure

Procedure Plot3D(x.f, y.f, z.f, Color=#PB_Default)
Protected.Drawing3D_Vector Position, NewPosition, ViewPosition, Distance
Position\x = x : Position\y = y : Position\z = z
Drawing3D_MatrixTimesVector(Distance, Drawing3D\View, Position)
Drawing3D_MoveVector(Distance, -Drawing3D\Camera\Position)
Drawing3D_MatrixTimesVector(NewPosition, Drawing3D\Camera\View, Distance)
ViewPosition\x = NewPosition\x * Drawing3D\Distance / NewPosition\z + OutputWidth()*0.5
ViewPosition\y = NewPosition\y * Drawing3D\Distance / NewPosition\z + OutputHeight()*0.5
If NewPosition\z > 0
If ViewPosition\x >= 0 And ViewPosition\x < OutputWidth()-1 And ViewPosition\y >= 0 And ViewPosition\y < OutputHeight()-1
If Color=#PB_Default
Plot(ViewPosition\x, ViewPosition\y)
Else
Plot(ViewPosition\x, ViewPosition\y, Color)
EndIf
EndIf
EndIf
EndProcedure

With Drawing3D
Drawing3D_UpdateTrigonometry(\Camera\Trigonometry, \Camera\Rotation)
Drawing3D_UpdateRotationMatrix(\Camera\View, \Camera\Trigonometry)
Drawing3D_UpdateTrigonometry(\Trigonometry, \Rotation)
Drawing3D_UpdateRotationMatrix(\View, \Trigonometry)
Drawing3DFieldOfVision(75)
EndWith

; Example

Enumeration
#Window
EndEnumeration

Structure Point2D
X.i
Y.i
EndStructure

Define SaveMouse.Point2D
Define Mouse.Point2D

Procedure Update()
Box(0, 0, OutputWidth(), OutputHeight(), \$000000)
Drawing3DCameraPosition(0, 0, -40)
Drawing3DFieldOfVision(75)
xx.f=-3:zz.f=-2:yy.f=0
While zz<=2
While xx <=3
xx=xx+0.05
;yy=Sin(xx+Pow(zz,2))
;function of 'A':
yy=((1-Sign(-xx-0.9+Abs(zz*2)))/3*(Sign(0.9-xx)+1)/3)*(Sign(xx+0.65)+1)/2 -((1-Sign(-xx-0.39+Abs(zz*2)))/3*(Sign(0.9-xx)+1)/3) + ((1-Sign(-xx-0.39+Abs(zz*2)))/3*(Sign(0.6-xx)+1)/3)*(Sign(xx-0.35)+1)/2
Plot3D(xx*5, yy*5, zz*5, \$50F0A0)
Wend
xx=-3:zz=zz+0.05
Wend
StopDrawing3D()
EndIf
EndProcedure

OpenWindow(#Window, 0, 0, 800, 600, "Drawing3D", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
Drawing3DViewRotation(130, 90, 0)
Drawing3DViewRotation(0, 20, 0)
Update()

Repeat

Select WaitWindowEvent(10)
Select EventType()
Case #PB_EventType_LeftButtonDown
Case #PB_EventType_MouseMove
Drawing3DViewRotation(-(Mouse\Y-SaveMouse\Y)/3, (Mouse\X-SaveMouse\X)/3, 0)
Update()
EndIf
EndSelect
EndSelect
Case #PB_Event_CloseWindow
End
EndSelect

ForEver

Edit: if i have more time, i will make a new update of my include for Drawing3D

_________________

Top

 Post subject: Re: function to plot 'A' letterPosted: Wed Jun 06, 2012 6:49 am
 Enthusiast

Joined: Sun Jun 25, 2006 7:28 pm
Posts: 225
thank you STARGÅTE for the update, yes i think it is more accurate.
your dynamic 3D functions are usefull especially with the ability to move, rotate, and zoom in-out. and it is good that we don't need to study the inside mathematics to use the functions. i will use the Plot3D function (or may be Line3D) to plot a 3D terrain from a flat grey picture, i am studying how to extract the pixels values.
thanks

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 3 posts ]

 All times are UTC + 1 hour

#### Who is online

Users browsing this forum: No registered users and 3 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forum

Search for:
 Jump to:  Select a forum ------------------ PureBasic    Coding Questions    Game Programming    3D Programming    Assembly Programming    The PureBasic Editor    The PureBasic Form Designer    General Discussion    Feature Requests and Wishlists    Tricks 'n' Tips Bug Reports    Bugs - Windows    Bugs - Linux    Bugs - Mac OSX    Bugs - Documentation OS Specific    AmigaOS    Linux    Windows    Mac OSX Miscellaneous    Announcement    Off Topic Showcase    Applications - Feedback and Discussion    PureFORM & JaPBe    TailBite