'3D Sierpinski Triangle or Tetrix
'21 Feb, 2019 Ashish
'The number of pyramid formed are at nth iterations = 4^(n-1). sss
'You must enter number of iterations value between 2-8 or you can enter higher value at your own risk.
_TITLE "3D Sierpinski Triangle"
IF INPUTBOX
("Enter the number of iterations", "Recommended range 2-8, or you can go higher at your own risk. ", "4", v$
, -1) = 1 THEN totalIterations
= VAL(v$
)
generateFractalData totalIterations
modes = 0
glAllow = -1
glInit = -1
_glClear _GL_DEPTH_BUFFER_BIT
OR _GL_COLOR_BUFFER_BIT
_glLightfv _GL_LIGHT0
, _GL_POSITION
, glVec4
(0, 0, 25, 0) _glLightfv _GL_LIGHT0
, _GL_AMBIENT
, glVec3
(0.4, 0.4, 0.4) _glLightfv _GL_LIGHT0
, _GL_DIFFUSE
, glVec3
(1, 1, 1) _glLightfv _GL_LIGHT0
, _GL_SPECULAR
, glVec3
(0.6, 0.6, 0.6)
gluLookAt 0, 0, 4, 0, 0, 0, 0, 1, 0
_glMaterialfv _GL_FRONT_AND_BACK
, _GL_AMBIENT
, glVec3
(0.1745, 0.01175, 0.01175) _glMaterialfv _GL_FRONT_AND_BACK
, _GL_DIFFUSE
, glVec3
(0.61424, 0.04136, 0.04136) _glMaterialfv _GL_FRONT_AND_BACK
, _GL_SPECULAR
, glVec3
(0.727811, 0.626959, 0.626959) _glMaterialfv _GL_FRONT_AND_BACK
, _GL_SHININESS
, glVec3
(128 * 0.6, 0, 0)
FOR i
= 0 TO totalFaces
- 1
_glNormal3f triangles
(i
).n.x
, triangles
(i
).n.y
, triangles
(i
).n.z
_glVertex3f triangles
(i
).v1.x
, triangles
(i
).v1.y
, triangles
(i
).v1.z
_glVertex3f triangles
(i
).v2.x
, triangles
(i
).v2.y
, triangles
(i
).v2.z
_glVertex3f triangles
(i
).v3.x
, triangles
(i
).v3.y
, triangles
(i
).v3.z
FOR i
= 0 TO totalFaces
- 1
_glVertex3f triangles
(i
).v1.x
, triangles
(i
).v1.y
, triangles
(i
).v1.z
_glVertex3f triangles
(i
).v2.x
, triangles
(i
).v2.y
, triangles
(i
).v2.z
_glVertex3f triangles
(i
).v3.x
, triangles
(i
).v3.y
, triangles
(i
).v3.z
FOR i
= 0 TO totalFaces
- 1 _glVertex3f triangles
(i
).v1.x
, triangles
(i
).v1.y
, triangles
(i
).v1.z
_glVertex3f triangles
(i
).v2.x
, triangles
(i
).v2.y
, triangles
(i
).v2.z
_glVertex3f triangles
(i
).v3.x
, triangles
(i
).v3.y
, triangles
(i
).v3.z
_glVertex3f triangles
(i
).v2.x
, triangles
(i
).v2.y
, triangles
(i
).v2.z
_glVertex3f triangles
(i
).v3.x
, triangles
(i
).v3.y
, triangles
(i
).v3.z
_glVertex3f triangles
(i
).v1.x
, triangles
(i
).v1.y
, triangles
(i
).v1.z
FOR i
= 0 TO totalFaces
- 1
_glVertex3f triangles
(i
).v1.x
, triangles
(i
).v1.y
, triangles
(i
).v1.z
_glVertex3f triangles
(i
).v2.x
, triangles
(i
).v2.y
, triangles
(i
).v2.z
_glVertex3f triangles
(i
).v3.x
, triangles
(i
).v3.y
, triangles
(i
).v3.z
_glVertex3f triangles
(i
).v2.x
, triangles
(i
).v2.y
, triangles
(i
).v2.z
_glVertex3f triangles
(i
).v3.x
, triangles
(i
).v3.y
, triangles
(i
).v3.z
_glVertex3f triangles
(i
).v1.x
, triangles
(i
).v1.y
, triangles
(i
).v1.z
SUB generateFractalData
(num_of_iterations
) createFaces num_of_iterations, 0, 1, 1 / 3, -1, -1, 1, 1, -1, 1, 0, -1, -1, 1
SUB createFaces
(i
, x1
, y1
, z1
, x2
, y2
, z2
, x3
, y3
, z3
, x4
, y4
, z4
, i_c
) triangles(Fc).v1.x = x1: triangles(Fc).v1.y = y1: triangles(Fc).v1.z = z1
triangles(Fc).v2.x = x2: triangles(Fc).v2.y = y2: triangles(Fc).v2.z = z2
triangles(Fc).v3.x = x3: triangles(Fc).v3.y = y3: triangles(Fc).v3.z = z3
OBJ_CalculateNormal triangles(Fc).v1, triangles(Fc).v2, triangles(Fc).v3, normalVec
triangles(Fc).n.x = normalVec.x: triangles(Fc).n.y = normalVec.y: triangles(Fc).n.z = normalVec.z
Fc = Fc + 1
triangles(Fc).v1.x = x2: triangles(Fc).v1.y = y2: triangles(Fc).v1.z = z2
triangles(Fc).v2.x = x3: triangles(Fc).v2.y = y3: triangles(Fc).v2.z = z3
triangles(Fc).v3.x = x4: triangles(Fc).v3.y = y4: triangles(Fc).v3.z = z4
OBJ_CalculateNormal triangles(Fc).v1, triangles(Fc).v2, triangles(Fc).v3, normalVec
triangles(Fc).n.x = normalVec.x: triangles(Fc).n.y = normalVec.y: triangles(Fc).n.z = normalVec.z
Fc = Fc + 1
triangles(Fc).v1.x = x3: triangles(Fc).v1.y = y3: triangles(Fc).v1.z = z3
triangles(Fc).v2.x = x4: triangles(Fc).v2.y = y4: triangles(Fc).v2.z = z4
triangles(Fc).v3.x = x1: triangles(Fc).v3.y = y1: triangles(Fc).v3.z = z1
OBJ_CalculateNormal triangles(Fc).v1, triangles(Fc).v2, triangles(Fc).v3, normalVec
triangles(Fc).n.x = normalVec.x: triangles(Fc).n.y = normalVec.y: triangles(Fc).n.z = normalVec.z
Fc = Fc + 1
triangles(Fc).v1.x = x4: triangles(Fc).v1.y = y4: triangles(Fc).v1.z = z4
triangles(Fc).v2.x = x1: triangles(Fc).v2.y = y1: triangles(Fc).v2.z = z1
triangles(Fc).v3.x = x2: triangles(Fc).v3.y = y2: triangles(Fc).v3.z = z2
OBJ_CalculateNormal triangles(Fc).v1, triangles(Fc).v2, triangles(Fc).v3, normalVec
triangles(Fc).n.x = normalVec.x: triangles(Fc).n.y = normalVec.y: triangles(Fc).n.z = normalVec.z
Fc = Fc + 1
totalFaces = totalFaces + 4
'creating 4 pyramid from single pyramid and then dividing them further
createFaces i, (x4 + x1) / 2, (y4 + y1) / 2, (z4 + z1) / 2, (x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2, (x1 + x3) / 2, (y1 + y3) / 2, (z1 + z3) / 2, x1, y1, z1, i_c + 1
createFaces i, x4, y4, z4, (x2 + x4) / 2, (y2 + y4) / 2, (z2 + z4) / 2, (x3 + x4) / 2, (y3 + y4) / 2, (z3 + z4) / 2, (x1 + x4) / 2, (y1 + y4) / 2, (z1 + z4) / 2, i_c + 1
createFaces i, (x2 + x4) / 2, (y2 + y4) / 2, (z2 + z4) / 2, x2, y2, z2, (x2 + x3) / 2, (y2 + y3) / 2, (z2 + z3) / 2, (x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2, i_c + 1
createFaces i, (x3 + x4) / 2, (y3 + y4) / 2, (z3 + z4) / 2, (x2 + x3) / 2, (y2 + y3) / 2, (z2 + z3) / 2, x3, y3, z3, (x1 + x3) / 2, (y1 + y3) / 2, (z1 + z3) / 2, i_c + 1
SUB OBJ_CalculateNormal
(p1
AS vec3
, p2
AS vec3
, p3
AS vec3
, N
AS vec3
)
U.x = p2.x - p1.x
U.y = p2.y - p1.y
U.z = p2.z - p1.z
V.x = p3.x - p1.x
V.y = p3.y - p1.y
V.z = p3.z - p1.z
N.x = (U.y * V.z) - (U.z * V.y)
N.y = (U.z * V.x) - (U.x * V.z)
N.z = (U.x * V.y) - (U.y * V.x)
OBJ_Normalize N
SUB OBJ_Normalize
(V
AS vec3
) mag!
= SQR(V.x
* V.x
+ V.y
* V.y
+ V.z
* V.z
) V.x = V.x / mag!
V.y = V.y / mag!
V.z = V.z / mag!
internal_vec4(0) = x
internal_vec4(1) = y
internal_vec4(2) = z
internal_vec4(3) = w
glVec4%&
= _OFFSET(internal_vec4
())
internal_vec3(0) = x
internal_vec3(1) = y
internal_vec3(2) = z
glVec3%&
= _OFFSET(internal_vec3
())
'By Fellipe Heitor
'INPUTBOX ---------------------------------------------------------------------
'Show a dialog and allow user input. Returns 1 = OK or 2 = Cancel. '
' '
'- tTitle$ is the desired dialog title. If not provided, it'll be "Input" '
' '
'- tMessage$ is the prompt that'll be shown to the user. You can show '
' a multiline message by adding line breaks with CHR$(10). '
' '
' - InitialValue can be passed both as a string literal or as a variable. '
' '
'- Actual user input is returned by altering NewValue, so it must be '
' passed as a variable. '
' '
'- Selected indicates wheter the initial value will be preselected when the '
' dialog is first shown. -1 preselects the whole text; positive values '
' select only part of the initial value (from the character position passed '
' to the end of the initial value). '
' '
'Intended for use with 32-bit screen modes. '
'------------------------------------------------------------------------------
'Variable declaration:
'Data type used for the dialog buttons:
'Color constants. You can customize colors by changing these:
'Initial variable setup:
Message$ = tMessage$
IF Title$
= "" THEN Title$
= "Input" DefaultButton = 1
'Save the current drawing page so it can be restored later:
'Figure out the print width of a single character (in case user has a custom font applied)
'Place a color overlay over the old screen image so the focus is on the dialog:
'Message breakdown, in case CHR$(10) was used as line break:
MaxLen = 1
lineBreak
= INSTR(lineBreak
+ 1, Message$
, CHR$(10)) totalLines = 1
MessageLines(1) = Message$
totalLines = totalLines + 1
MessageLines
(totalLines
) = RIGHT$(Message$
, LEN(Message$
) - prevlinebreak
+ 1) IF LEN(MessageLines
(totalLines
)) > MaxLen
THEN MaxLen
= LEN(MessageLines
(totalLines
)) IF totalLines
= 0 THEN prevlinebreak
= 1 totalLines = totalLines + 1
MessageLines
(totalLines
) = MID$(Message$
, prevlinebreak
, lineBreak
- prevlinebreak
) IF LEN(MessageLines
(totalLines
)) > MaxLen
THEN MaxLen
= LEN(MessageLines
(totalLines
)) prevlinebreak = lineBreak + 1
Selection.Start = 0
InputViewStart = 1
FieldArea
= _WIDTH \ CharW
- 4 IF FieldArea
> 62 THEN FieldArea
= 62 IF Selected
> 0 THEN Selection.Start
= Selected: Selected
= -1
'Calculate dialog dimensions and print coordinates:
DialogW = (CharW * FieldArea) + 10
IF DialogW
< MaxLen
* CharW
+ 10 THEN DialogW
= MaxLen
* CharW
+ 10
DialogX
= _WIDTH / 2 - DialogW
/ 2 DialogY
= _HEIGHT / 2 - DialogH
/ 2 InputField.X = (DialogX + (DialogW / 2)) - (((FieldArea * CharW) - 10) / 2) - 4
'Calculate button's print coordinates:
TotalButtons = 2
DIM Buttons
(1 TO TotalButtons
) AS BUTTONSTYPE
B = 1
Buttons(B).ID = 1: Buttons(B).CAPTION = "< OK >": B = B + 1
Buttons(B).ID = 2: Buttons(B).CAPTION = "< Cancel >": B = B + 1
ButtonLine$ = " "
FOR cb
= 1 TO TotalButtons
ButtonLine$
= ButtonLine$
+ RTRIM$(LTRIM$(Buttons
(cb
).CAPTION
)) + " " Buttons
(cb
).Y
= DialogY
+ 5 + _FONTHEIGHT * (5 + totalLines
) FOR cb
= 2 TO TotalButtons
'Main loop:
DIALOGRESULT = 0
'Draw the dialog.
LINE (DialogX
, DialogY
)-STEP(DialogW
- 1, DialogH
- 1), DialogBGColor
, BF
'Draw the input field
COLOR InputFieldTextColor
'Selection highlight:
'Cursor blink:
IF cursorBlink%
= 1 THEN cursorBlink%
= 0 ELSE cursorBlink%
= 1
'Check if buttons have been clicked or are being hovered:
'Draw buttons:
FOR cb
= 1 TO TotalButtons
'Process input:
IF k
= 100303 OR k
= 100304 THEN shiftDown
= -1 IF k
= -100303 OR k
= -100304 THEN shiftDown
= 0 IF k
= 100305 OR k
= 100306 THEN ctrlDown
= -1 IF k
= -100305 OR k
= -100306 THEN ctrlDown
= 0
CASE 13: DIALOGRESULT
= 1 CASE 27: DIALOGRESULT
= 2 CASE 32 TO 126 'Printable ASCII characters NewValue = NewValue + Clip$
NewValue
= LEFT$(NewValue
, Cursor
) + Clip$
+ MID$(NewValue
, Cursor
+ 1) Cursor
= Cursor
+ LEN(Clip$
) s1 = Selection.Start
s2 = Cursor
NewValue
= LEFT$(NewValue
, s1
) + Clip$
+ MID$(NewValue
, s2
+ 1) Selected = 0
k = 0
k = 0
k = 0
Selection.Start = 0
Selected = -1
k = 0
NewValue
= NewValue
+ CHR$(k
) Cursor = Cursor + 1
NewValue
= LEFT$(NewValue
, Cursor
) + CHR$(k
) + MID$(NewValue
, Cursor
+ 1) Cursor = Cursor + 1
IF Cursor
> FieldArea
THEN InputViewStart
= (Cursor
- FieldArea
) + 2 s1 = Selection.Start
s2 = Cursor
NewValue
= LEFT$(NewValue
, s1
) + CHR$(k
) + MID$(NewValue
, s2
+ 1) Selected = 0
Cursor = s1 + 1
NewValue
= LEFT$(NewValue
, LEN(NewValue
) - 1) Cursor = Cursor - 1
NewValue
= LEFT$(NewValue
, Cursor
- 1) + MID$(NewValue
, Cursor
+ 1) Cursor = Cursor - 1
NewValue
= RIGHT$(NewValue
, LEN(NewValue
) - 1) Cursor = Cursor - 1
NewValue
= RIGHT$(NewValue
, LEN(NewValue
) - 1) NewValue
= LEFT$(NewValue
, Cursor
) + MID$(NewValue
, Cursor
+ 2) CASE 19200 'Left arrow key IF Cursor
> 0 THEN Cursor
= Cursor
- 1 CASE 19712 'Right arrow key IF Cursor
< LEN(NewValue
) THEN Cursor
= Cursor
+ 1 Cursor = 0
'Cursor adjustments:
INPUTBOX = DIALOGRESULT
'Restore previous display:
CursorAdjustments:
IF Cursor
- InputViewStart
+ 2 > FieldArea
THEN InputViewStart
= (Cursor
- FieldArea
) + 2 IF Cursor
< InputViewStart
- 1 THEN InputViewStart
= Cursor
prevCursor = Cursor
IF InputViewStart
< 1 THEN InputViewStart
= 1
CheckSelection:
Selected = -1
Selection.Start = Cursor
Selected = 0
DeleteSelection:
NewValue
= LEFT$(NewValue
, s1
) + MID$(NewValue
, s2
+ 1) Selected = 0
Cursor = s1
SelectionHighlight:
s1 = Selection.Start
s2 = Cursor
ss1 = s1 - InputViewStart + 1
ss1 = s1
ss2 = s2 - s1
IF ss1
+ ss2
> FieldArea
THEN ss2
= FieldArea
- ss1
ss1 = s1
ss2 = s2 - s1
IF ss1
< InputViewStart
THEN ss1
= 0: ss2
= s2
- InputViewStart
+ 1 IF ss1
> InputViewStart
THEN ss1
= ss1
- InputViewStart
+ 1: ss2
= s2
- s1
Selection.Value$
= MID$(NewValue
, s1
+ 1, s2
- s1
)
CheckButtons:
'Hover highlight:
FOR cb
= 1 TO TotalButtons
IF (mx
>= Buttons
(cb
).X
) AND (mx
<= Buttons
(cb
).X
+ Buttons
(cb
).W
) THEN
'Clicking inside the text field positions the cursor
Cursor = ((mx - InputField.X) / CharW) + (InputViewStart - 1)
Selected = 0
FOR cb
= 1 TO TotalButtons
IF (mx
>= Buttons
(cb
).X
) AND (mx
<= Buttons
(cb
).X
+ Buttons
(cb
).W
) THEN DefaultButton = cb
IF nmx
= mx
AND nmy
= my
THEN DIALOGRESULT
= cb