Klein Bottle example
Posted: Tue Mar 12, 2013 8:40 am
2 examples for klein bottle ; the first is using textured triangles. using this parametric equations in this article http://paulbourke.net/geometry/klein/
it has two orbits the inner circles (orbits) which in turn going in another orbit which forms the klein bottle

to see it in wireframe uncomment line 47
the second klein bottle are easier to implement, using point plotting for the same equations
it has two orbits the inner circles (orbits) which in turn going in another orbit which forms the klein bottle


to see it in wireframe uncomment line 47
Code: Select all
Enumeration
#MESH
#LIGHT
#CAMERA_ONE
#BUTTON
#mainwin
EndEnumeration
Quit.b = #False
rot.l=1 :stopFlag = 1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
rotx.f:roty.f=0.5:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 1.8: depth.f=0
ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD scale mesh..Arrows for rotation, space: stop/rotate, QA far/near, key_pad R/L/U/D", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(#BUTTON, 0, DesktopHeight(0)-60, 60, 30, "rotate/stop")
;Initialize environment
InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-60, 0, 0, 0)
;WorldShadows(#PB_Shadow_Additive)
InitKeyboard()
SetFrameRate(60)
Add3DArchive("/", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/Sources\Data", #PB_3DArchive_FileSystem)
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(#CAMERA_ONE, 0, 0, 400, 400)
MoveCamera(#CAMERA_ONE, 0, 4, 9)
CameraLookAt(#CAMERA_ONE, 0, 2, 0)
RotateCamera(#CAMERA_ONE, -15, 0, 0)
EndIf
SetActiveGadget(#BUTTON)
SkyDome("clouds.jpg", 100) ;for blue color background
; material for the plot
CreateMaterial(0, LoadTexture(0, "terrain_texture.jpg"))
;MaterialShadingMode(0, #PB_Material_Wireframe)
MaterialCullingMode(0, #PB_Material_NoCulling)
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_TriangleList , #PB_Mesh_Static )
SetMeshMaterial(1, MaterialID(0))
u.f: v.f: r.f
majorOrbit.l = 30 : minorOrbit.l = 30
majorStep.f = 2 * #PI / majorOrbit
minorStep.f = 2 * #PI / minorOrbit
i.l: j.l :txu.f : txv.f
For i = 0 To majorOrbit
u = i * majorStep
For j = 0 To minorOrbit
v = j * minorStep
r = 4 * (1 - (Cos(u)/2))
If u <= #PI
x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(u) * Cos (v)
y = 16 * Sin(u) + r * Sin(u) * Cos(v)
ElseIf u > #PI And u <=2*#PI
x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(v+#PI)
y = 16 * Sin(u)
EndIf
z = r * Sin(v)
MeshVertexPosition(x, y, z);
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
; texture the whole bottle with one picture stretched
txv = txv + 1/minorOrbit ; texture coordinates
Next
txv = 0
txu = txu + 1/majorOrbit ; texture coordinates
Next
; making Faces
For i = 0 To majorOrbit-1
For j = 0 To minorOrbit
MeshFace(t,t+1,t + minorOrbit+1)
MeshFace(t + minorOrbit+1,t + minorOrbit+2,t+1 )
If i=majorOrbit-1 And j=minorOrbit-1 ;bypass the last triangle
minorOrbit-1
EndIf
t + 1
Next
Next
NormalizeMesh(1)
FinishMesh(#True)
CreateEntity(1, MeshID(1), MaterialID(0))
ScaleEntity(1,0.2, 0.2, 0.2)
;Main loop
MoveEntity(1,0,up,depth,#PB_Absolute)
x = 180: y=0: z=0 : h.f
Repeat
Event = WindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case #BUTTON
If rot = 0
rot = 1
rotx= rotx0:roty=roty0:rotz=rotz0 ; restore rotation status
stopFlag = 1
Else
rot = 0
rotx0= rotx:roty0=roty:rotz0=rotz ;back up rotation status
rotx=0:roty=0:rotz=0
stopFlag = 0
EndIf
EndSelect
EndIf
If stopFlag=1
x + rotx
y + roty
z + rotz
EndIf
RotateEntity(1, x, y, z)
RenderWorld()
FlipBuffers()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up) ; rotate left
rotx=1:roty=0:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Down) ; rotate right
rotx=-1:roty=0:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Right) ; rotate up
rotx=0:roty=1:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Left) ; rotate down
rotx=0:roty=-1:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
EndIf
If KeyboardPushed(#PB_Key_PageUp) ; scale up model
xs.f = 1.1:ys.f = 1.1:zs.f = 1.1
ScaleEntity(1,xs,ys,zs)
ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
xs = 0.9:ys = 0.9:zs= 0.9
ScaleEntity(1,xs,ys,zs)
EndIf
If KeyboardPushed(#PB_Key_Pad8) ; up move
up + 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad2) ; down move
up - 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad6)
h + 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad4)
h - 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Q) ; forward move
depth - 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_A) ; inward move
depth + 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
EndIf
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow

Code: Select all
Enumeration
#MESH
#LIGHT
#CAMERA_ONE
#BUTTON
#mainwin
EndEnumeration
Quit.b = #False
rot.l=1 :stopFlag = 1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
rotx.f:roty.f=0.5:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 1.8: depth.f=0
ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD scale mesh..Arrows for rotation, space: stop/rotate, QA far/near, key_pad R/L/U/D", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(#BUTTON, 0, DesktopHeight(0)-60, 60, 30, "rotate/stop")
;Initialize environment
InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-70, 0, 0, 0)
;WorldShadows(#PB_Shadow_Additive)
InitKeyboard()
SetFrameRate(60)
Add3DArchive("/", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(#CAMERA_ONE, 0, 0, 400, 400)
MoveCamera(#CAMERA_ONE, 0, 4, 9)
CameraLookAt(#CAMERA_ONE, 0, 2, 0)
RotateCamera(#CAMERA_ONE, -15, 0, 0)
EndIf
SetActiveGadget(#BUTTON)
;SkyDome("clouds.jpg", 100) ;for blue color background
;- Mesh
CreateTexture(0,32,32)
StartDrawing(TextureOutput(0))
Box(0,0,32,32,RGB(255,255,255))
StopDrawing()
CreateMaterial(0,TextureID(0))
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static)
DisableMaterialLighting(0, #True)
SetMeshMaterial(1, MaterialID(0))
x.f: y.f :z.f : u.f: v.f: r.f
majorOrbit.l = 100 : minorOrbit.l = 100
majorStep.f = 2 * #PI / majorOrbit
minorStep.f = 2 * #PI / minorOrbit
i.l: j.l
For i = 0 To majorOrbit
u = i * majorStep
For j = 0 To minorOrbit
v = j * minorStep
r = 4 * (1 - (Cos(u)/2))
If u <= #PI
x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(u) * Cos (v)
y = 16 * Sin(u) + r * Sin(u) * Cos(v)
ElseIf u > #PI And u <=2*#PI
x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(v+#PI)
y = 16 * Sin(u)
EndIf
z = r * Sin(v)
MeshVertexPosition(x, y, z);
MeshVertexColor(RGB(0,255,0))
Next
Next
NormalizeMesh(1)
FinishMesh(#True)
CreateEntity(1, MeshID(1), MaterialID(0))
ScaleEntity(1,0.2, 0.2, 0.2)
;Main loop
MoveEntity(1,0,up,depth,#PB_Absolute)
x = 180: y=0: z=0 : h.f
Repeat
Event = WindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case #BUTTON
If rot = 0
rot = 1
rotx= rotx0:roty=roty0:rotz=rotz0 ; restore rotation status
stopFlag = 1
Else
rot = 0
rotx0= rotx:roty0=roty:rotz0=rotz ;back up rotation status
rotx=0:roty=0:rotz=0
stopFlag = 0
EndIf
EndSelect
EndIf
If stopFlag=1
x + rotx
y + roty
z + rotz
EndIf
RotateEntity(1, x, y, z)
RenderWorld()
FlipBuffers()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up) ; rotate left
rotx=1:roty=0:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Down) ; rotate right
rotx=-1:roty=0:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Right) ; rotate up
rotx=0:roty=1:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Left) ; rotate down
rotx=0:roty=-1:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
EndIf
If KeyboardPushed(#PB_Key_PageUp) ; scale up model
xs.f = 1.1:ys.f = 1.1:zs.f = 1.1
ScaleEntity(1,xs,ys,zs)
ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
xs = 0.9:ys = 0.9:zs= 0.9
ScaleEntity(1,xs,ys,zs)
EndIf
If KeyboardPushed(#PB_Key_Pad8) ; up move
up + 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad2) ; down move
up - 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad6)
h + 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad4)
h - 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Q) ; forward move
depth - 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_A) ; inward move
depth + 0.1
MoveEntity(1,h,up,depth,#PB_Absolute)
EndIf
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow