' ################################################################################################################################################################
' #TOP
' Basic 2D plotting functions
' Version 1.00 by madscijr
' with help from various (sources cited below).
' ################################################################################################################################################################
' =============================================================================
' GLOBAL DECLARATIONS
' =============================================================================
' boolean constants
' -----------------------------------------------------------------------------
' USER DEFINED TYPES
' -----------------------------------------------------------------------------
'z as integer
' -----------------------------------------------------------------------------
' GLOBAL VARIABLES
' -----------------------------------------------------------------------------
' =============================================================================
' BEGIN MAIN PROGRAM
' =============================================================================
' ****************************************************************************************************************************************************************
' ACTIVATE DEBUGGING WINDOW
_Echo "Started " + m_ProgramName$
' ****************************************************************************************************************************************************************
' -----------------------------------------------------------------------------
' START THE MENU
main
' -----------------------------------------------------------------------------
' DONE
Print m_ProgramName$
+ " finished." 'Screen 0
Input "Press <ENTER> to continue", in$
' ****************************************************************************************************************************************************************
' DEACTIVATE DEBUGGING WINDOW
' ****************************************************************************************************************************************************************
' -----------------------------------------------------------------------------
' EXIT
System ' return control to the operating system
' =============================================================================
' END MAIN PROGRAM
' =============================================================================
' /////////////////////////////////////////////////////////////////////////////
' MAIN MENU
Print "Some basic 2D plotting" Print " 1. PlotPointTest" Print " 2. PlotSquareTest" Print " 3. PlotCircleTest" Print " 4. CircleFillTest" Print " 6. EllipseFillTest" Print " 8. ShearRotateTest1" Print " 9. ShearRotateTest2 (auto advances 0-360 degrees)" Print "10. ShearRotateTest2 (auto advances 0-360 degrees) (uses Petr's text)" Print "11. ShearRotateTest3 (tries to correct for missing points)" Print "12. ShearRotateTest3 (tries to correct for missing points) (uses Petr's text)" Print "What to do? ('q' to exit)"
PlotPointTest
PlotSquareTest
PlotCircleTest
CircleFillTest
EllipseTest
EllipseFillTest
PlotLineTest
ShearRotateTest1
ShearRotateTest2 TestSprite1$
ShearRotateTest2 PetrText1$
ShearRotateTest3 TestSprite1$
ShearRotateTest3 PetrText1$
' /////////////////////////////////////////////////////////////////////////////
' MyArray(1 To 32, 1 To 32) AS STRING
MyArray(Y, X) = S
MyArray
(Y
, X
) = Left$(S
, 1)
' /////////////////////////////////////////////////////////////////////////////
ClearArray MyArray(), "."
iChar = 64
Print ArrayToStringTest
(MyArray
())
Print "Type x,y (1-32, 1-32) coordinate to plot point at." Input "X,Y OR 0 TO QUIT? "; X
, Y
iChar = iChar + 1
Print "X=" + cstr$
(X
) + ", Y=" + cstr$
(Y
) PlotPoint X
, Y
, Chr$(iChar
), MyArray
()
Print ArrayToStringTest
(MyArray
())
' /////////////////////////////////////////////////////////////////////////////
sChar$ = S
sChar$ = " "
X2 = (X1 + L) - 1
Y2 = (Y1 + L) - 1
PlotPoint X, Y, sChar$, MyArray()
' /////////////////////////////////////////////////////////////////////////////
ClearArray MyArray(), "."
iChar = 64
Print "Enter parameters to draw a square." Print ArrayToStringTest
(MyArray
()) Print "Type top left x,y (1-32, 1-32) coordinate to plot square," Print "and size (1-32) of square." Input "X,Y,L OR 0 TO QUIT? "; X
, Y
, L
iChar = iChar + 1
PlotSquare X
, Y
, L
, Chr$(iChar
), MyArray
()
Print ArrayToStringTest
(MyArray
())
' /////////////////////////////////////////////////////////////////////////////
' Fast circle drawing in pure Atari BASIC#
' https://atariwiki.org/wiki/Wiki.jsp?page=Super%20fast%20circle%20routine
' * Magazine: Moj Mikro, 1989/3
' * Author : Zlatko Bleha
' * Page : 27 - 31
' * Atari BASIC listing on disk (tokenized): M8903282.BAS
' * Atari BASIC listing (listed): M8903282.LST
' Next example is demonstration of implementing mentioned circle algorithm
' in pure Atari BASIC. This program shows how much faster it is compared to
' classic program using sine and cosine functions from Atari BASIC
' (shown in last example).
' Basic Listing M8903282.LST#
'1 REM *******************************
'2 REM PROGRAM : FAST CIRCLE DRAWING
'3 REM AUTHOR : ZLATKO BLEHA
'4 REM PUBLISHER: MOJ MIKRO MAGAZINE
'5 REM ISSUE NO.: 1989, NO.3, PAGE 29
'6 REM *******************************
'7 REM
'10 GRAPHICS 8:SETCOLOR 2,0,0:COLOR 3
'20 PRINT "ENTER X, Y AND R"
'30 INPUT X,Y,R
'40 IF R=0 THEN PLOT X,Y:END
'50 B=R:C=0:A=R-1
'60 PLOT X+C,Y+B
'70 PLOT X+C,Y-B
'80 PLOT X-C,Y-B
'90 PLOT X-C,Y+B
'100 PLOT X+B,Y+C
'110 PLOT X+B,Y-C
'120 PLOT X-B,Y-C
'130 PLOT X-B,Y+C
'140 C=C+1
'150 A=A+1-C-C
'160 IF A>=0 THEN 190
'170 B=B-1
'180 A=A+B+B
'190 IF B>=C THEN 60
' Use some valid values for coordinates and radius, for example:
' X=40, Y=40, R=30
' X=130, Y=90, R=60
' Slow circle drawing in Atari BASIC#
' * Magazine: Moj Mikro, 1989/3
' * Author : Zlatko Bleha
' * Page : 27 - 31
' * Atari BASIC listing on disk (tokenized): M8903281.BAS
' * Atari BASIC listing (listed): M8903281.LST
' This is classic example for drawing circles from Atari BASIC
' using sine and cosine functions. Unfortunatelly, this is very slow
' way of doing it and not recommended.
' Just use routine shown above and everybody will be happy
' Basic Listing M8903281.LST#
'1 REM *******************************
'2 REM PROGRAM : SLOW CIRCLE DRAWING
'3 REM AUTHOR : ZLATKO BLEHA
'4 REM PUBLISHER: MOJ MIKRO MAGAZINE
'5 REM ISSUE NO.: 1989, NO.3, PAGE 29
'6 REM *******************************
'7 REM
'10 GRAPHICS 8:SETCOLOR 2,0,0:COLOR 3
'20 FOR A=0 TO 6.28 STEP 0.02
'30 X=SIN(A)*50+150
'40 Y=COS(A)*50+80
'50 PLOT X,Y
'60 NEXT A
' Conclusion#
' Returning back to first program with the fastest way of drawing circles...
' There is one more thing to note. In case you want to use PLOT subroutine,
' which is part of the main circle routine, then read following explanation.
' PLOT routine is written so it can be used easily from Atari BASIC program
' independently from main circle routine, by using like this:
' A=USR(30179,POK,X,Y)
'
' POK 1 (drawing a pixel), 0 (erasing a pixel)
' X X coordinate of the pixel
' Y Y coordinate of the pixel
'
' The routine alone is not any faster than normal PLOT command
' from Atari BASIC, because USR command takes approximately 75%
' of whole execution. But, used as part of the main circle routine
' it does not matter anymore, because it is integrated in one larger
' entity. There the execution is very fast, with no overhead.
' PLOT routine is here for you to examine anyway.
' You never know if you will maybe need it in the future.
' More on plotting circles:
' Drawing a circle in BASIC - fast
' https://www.cpcwiki.eu/forum/programming/drawing-a-circle-in-basic-fast/
' X,Y = center point of circle
' R = radius
' S = char to draw
' MyArray = 2D string array to plot circle in
S2 = S
S2 = " "
B = R
C = 0
A = R - 1
PlotPoint X + C, Y + B, S2, MyArray()
PlotPoint X + C, Y - B, S2, MyArray()
PlotPoint X - C, Y - B, S2, MyArray()
PlotPoint X - C, Y + B, S2, MyArray()
PlotPoint X + B, Y + C, S2, MyArray()
PlotPoint X + B, Y - C, S2, MyArray()
PlotPoint X - B, Y - C, S2, MyArray()
PlotPoint X - B, Y + C, S2, MyArray()
C = C + 1
A = A + 1 - C - C
If A
< 0 Then ' IF A>=0 THEN 190 B = B - 1
A = A + B + B
' /////////////////////////////////////////////////////////////////////////////
ClearArray MyArray(), "."
iChar = 64
Print "Plot a raster circle" Print "Based on Fast circle drawing in pure Atari BASIC by Zlatko Bleha." Print "Enter parameters to draw a circle." Print ArrayToStringTest
(MyArray
())
Print "Type center point x,y (1-32, 1-32) coordinate to plot circle," Print "and radius (1-32) of circle." Input "X,Y,R OR 0 TO QUIT: "; X
, Y
, R
iChar = iChar + 1
PlotCircle X
, Y
, R
, Chr$(iChar
), MyArray
()
Print ArrayToStringTest
(MyArray
())
' /////////////////////////////////////////////////////////////////////////////
' Re: Is this fast enough as general circle fill?
' https://qb64forum.alephc.xyz/index.php?topic=298.msg1913#msg1913
' From: SMcNeill
' Date: « Reply #30 on: June 26, 2018, 03:34:18 pm »
'
' Sometimes, computers do things that are completely counter-intuitive to us, and
' we find ourselves having to step back as programmers and simply say, "WOW!!"
' Here's a perfect example of that:
' Here we look at two different circle fill routines -- one, which I'd assume to
' be faster, which precalculates the offset needed to find the endpoints for each
' line which composes a circle, and another, which is the same old CircleFill
' program which I've shared countless times over the years with people on various
' QB64 forums.
'
' When all is said and done though, CircleFill is STILL even faster than
' CircleFillFast, which pregenerates those end-points for us!
RadiusError = -Radius
X = Radius
Y = 0
'PSET (CX, CY), C
PlotPoint CX, CY, S, MyArray()
' Draw the middle span here so we don't draw it twice in the main loop,
' which would be a problem with blending turned on.
'LINE (CX - X, CY)-(CX + X, CY), C, BF
For iLoopX
= CX
- X
To CX
+ X
PlotPoint iLoopX, CY, S, MyArray()
RadiusError = RadiusError + Y * 2 + 1
'LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
iLoopY = CY - X
For iLoopX
= CX
- Y
To CX
+ Y
PlotPoint iLoopX, iLoopY, S, MyArray()
'LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
iLoopY = CY + X
For iLoopX
= CX
- Y
To CX
+ Y
PlotPoint iLoopX, iLoopY, S, MyArray()
X = X - 1
RadiusError = RadiusError - X * 2
Y = Y + 1
'LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
iLoopY = CY - Y
For iLoopX
= CX
- X
To CX
+ X
PlotPoint iLoopX, iLoopY, S, MyArray()
'LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
iLoopY = CY + Y
For iLoopX
= CX
- X
To CX
+ X
PlotPoint iLoopX, iLoopY, S, MyArray()
' /////////////////////////////////////////////////////////////////////////////
ClearArray MyArray(), "."
iChar = 64
Print "Plot a filled circle" Print "Based on CircleFill by SMcNeill." Print "Enter parameters to draw a circle." Print ArrayToStringTest
(MyArray
())
Print "Type center point x,y (1-32, 1-32) coordinate to plot circle," Print "and radius (1-32) of circle." Input "X,Y,R OR 0 TO QUIT: "; X
, Y
, R
iChar = iChar + 1
'PlotCircle X, Y, R, Chr$(iChar), MyArray()
CircleFill X
, Y
, R
, Chr$(iChar
), MyArray
()
Print ArrayToStringTest
(MyArray
())
' /////////////////////////////////////////////////////////////////////////////
' Re: Is this fast enough as general circle fill?
' https://qb64forum.alephc.xyz/index.php?topic=298.msg3588#msg3588
' From: bplus
' Date: « Reply #59 on: August 30, 2018, 09:18:34 am »
scale = yRadius / xRadius
xs = xRadius * xRadius
'PSET (CX, CY - yRadius)
PlotPoint CX, CY - yRadius, S, MyArray()
'PSET (CX, CY + yRadius)
PlotPoint CX, CY + yRadius, S, MyArray()
lastx = 0: lasty = yRadius
y
= scale
* Sqr(xs
- x
* x
) 'LINE (CX + lastx, CY - lasty)-(CX + x, CY - y)
PlotLine CX + lastx, CY - lasty, CX + x, CY - y, S, MyArray()
'LINE (CX + lastx, CY + lasty)-(CX + x, CY + y)
PlotLine CX + lastx, CY + lasty, CX + x, CY + y, S, MyArray()
'LINE (CX - lastx, CY - lasty)-(CX - x, CY - y)
PlotLine CX - lastx, CY - lasty, CX - x, CY - y, S, MyArray()
'LINE (CX - lastx, CY + lasty)-(CX - x, CY + y)
PlotLine CX - lastx, CY + lasty, CX - x, CY + y, S, MyArray()
lastx = x
lasty = y
' /////////////////////////////////////////////////////////////////////////////
ClearArray MyArray(), "."
iChar = 64
Print "Based on ellipse by bplus." Print "Enter parameters to draw an ellipse." Print ArrayToStringTest
(MyArray
())
Print "Type center point x,y (1-32, 1-32) coordinate to plot ellipse," Print "and x radius (1-32) and y radius (1-32) of ellipse." Input "X,Y,RX,RY OR 0 TO QUIT: "; X
, Y
, RX
, RY
iChar = iChar + 1
Ellipse X
, Y
, RX
, RY
, Chr$(iChar
), MyArray
()
Print ArrayToStringTest
(MyArray
())
' /////////////////////////////////////////////////////////////////////////////
' Re: Is this fast enough as general circle fill?
' https://qb64forum.alephc.xyz/index.php?topic=298.msg3588#msg3588
' From: bplus
' Date: « Reply #59 on: August 30, 2018, 09:18:34 am »
'
' Here is my ellipse and filled ellipse routines, no where near
' Steve's level of performance. The speed is cut in half at
' least because you probably have to do a whole quadrants worth
' of calculations (ellipse not as symmetric as circle).
'
' But I am sure this code can be optimized more than it is:
scale = yRadius / xRadius
'LINE (CX, CY - yRadius)-(CX, CY + yRadius), , BF
For iLoopY
= CY
- yRadius
To CY
+ yRadius
PlotPoint CX, iLoopY, S, MyArray()
y
= scale
* Sqr(xRadius
* xRadius
- x
* x
)
'LINE (CX + x, CY - y)-(CX + x, CY + y), , BF
iLoopX = CX + x
For iLoopY
= CY
- y
To CY
+ y
PlotPoint iLoopX, iLoopY, S, MyArray()
'LINE (CX - x, CY - y)-(CX - x, CY + y), , BF
iLoopX = CX - x
For iLoopY
= CY
- y
To CY
+ y
PlotPoint iLoopX, iLoopY, S, MyArray()
' /////////////////////////////////////////////////////////////////////////////
ClearArray MyArray(), "."
iChar = 64
Print "Plot a filled ellipse" Print "Based on fellipse by bplus." Print "Enter parameters to draw an ellipse." Print ArrayToStringTest
(MyArray
())
Print "Type center point x,y (1-32, 1-32) coordinate to plot ellipse," Print "and x radius (1-32) and y radius (1-32) of ellipse." Input "X,Y,RX,RY OR 0 TO QUIT: "; X
, Y
, RX
, RY
iChar = iChar + 1
EllipseFill X
, Y
, RX
, RY
, Chr$(iChar
), MyArray
()
Print ArrayToStringTest
(MyArray
())
' /////////////////////////////////////////////////////////////////////////////
' Based on "BRESNHAM.BAS" by Kurt Kuzba. (4/16/96)
' From: http://www.thedubber.altervista.org/qbsrc.htm
Sub PlotLine
(x1%
, y1%
, x2%
, y2%
, c$
, MyArray
() As String)
sx% = 1
sx% = -1
sy% = 1
sy% = -1
steep% = 1
ev% = 2 * dy% - dx%
For iLoop%
= 0 To dx%
- 1 ''PSET (y1%, x1%), c%:
'LOCATE y1%, x1%
'PRINT c$;
PlotPoint y1%, x1%, c$, MyArray()
''PSET (x1%, y1%), c%
'LOCATE x1%, y1%
'PRINT c$;
PlotPoint x1%, y1%, c$, MyArray()
y1% = y1% + sy%
ev% = ev% - 2 * dx%
x1% = x1% + sx%
ev% = ev% + 2 * dy%
''PSET (x2%, y2%), c%
'LOCATE x2%, y2%
'PRINT c$;
PlotPoint x2%, y2%, c$, MyArray()
' /////////////////////////////////////////////////////////////////////////////
ClearArray MyArray(), "."
iChar = 64
Print "Plot line with Bresenham Algorithm" Print "based on BRESNHAM.BAS by Kurt Kuzba (4/16/96)." Print ArrayToStringTest
(MyArray
()) Print "Enter coordinate values for " Print "line start point x1, y1 (1-32, 1-32)" Print "line end point x2, y2 (1-32, 1-32)" Input "ENTER X1,Y1,X2,Y2 OR 0 TO QUIT: "; X1
, Y1
, X2
, Y2
iChar = iChar + 1
PlotLine X1
, Y1
, X2
, Y2
, Chr$(iChar
), MyArray
()
Print ArrayToStringTest
(MyArray
())
' /////////////////////////////////////////////////////////////////////////////
' 3 shear method testing
' _PUT Rotation Help
' https://www.qb64.org/forum/index.php?topic=1959.0
' 3 Shear Rotation - rotates without any aliasing(holes)
' https://www.freebasic.net/forum/viewtopic.php?t=24557
' From: leopardpm
' Date: Apr 02, 2016 1:21
' Last edited by leopardpm on Apr 02, 2016 17:18, edited 1 time in total.
'
' This is just a little 3-shear rotation routine
' (I am using 3-shear because it leaves no gaps/aliasing)
' that I was wondering if anyone sees how to make it faster.
' Obviously, I am just thinking about inside the double loop.
' Thanks again to BasicCoder2 for linking me to this little routine, it is wonderful so far!
''' roto-zooming algorithm
''' coded by Michael S. Nissen
''' jernmager@yahoo.dk
'
''' ===============================================================
''' Recoded to run on FBC 32/64 bit WIN, Version 1.05.0, 2016, by MrSwiss
''' Heavy flickering before going Full-Screen on 64 Bit !!!
''' This seems NOT to be the Case on 32 Bit ...
''' ===============================================================
'
'Type Pixel
' As Single X, Y
' As ULong C
'End Type
'
''' dim vars
'Dim shared as Any Ptr Img_Buffer
''' write the name of the .bmp image you want to rotozoom here:
''' (it has to be sqare ie. 100x100 pixels, 760x760 pixels or whatever)
'Dim As String Img_Name = "phobos.bmp"
'Dim shared as Integer X_Mid, Y_Mid, scrn_wid, scrn_hgt, P1, P2, P3, P4, C
'Dim shared as Short Img_Hgt, Img_Wid, Img_Lft, Img_Rgt, Img_Top, Img_Btm, X, Y
'Dim Shared As Single Cos_Ang, Sin_Ang, Rot_Fac_X, Rot_Fac_Y, Angle = 0, Scale = 1
'
''' changed Function to Sub (+ recoded arguments list)
'Sub Calc_rotozoom ( ByRef Cos_Ang As Single, _
' ByRef Sin_Ang As Single, _
' ByVal S_Fact As Single, _
' ByVal NewAng As Single )
' Cos_Ang = Cos(NewAng)*S_Fact
' Sin_Ang = Sin(NewAng)*S_Fact
'End Sub
'
''' full screen
'ScreenInfo scrn_wid, scrn_hgt
'screenRes scrn_wid, scrn_hgt, 32,,1
'
''' dim screenpointer (has to be done after screenres)
'Dim As ULong Ptr Scrn_Ptr = Screenptr
'
''' place image in center of screen
'X_Mid = scrn_wid\2
'Y_Mid = scrn_hgt\2
'Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)
'
''' find image dimensions
'Open Img_Name For Binary As #1
'Get #1, 19, Img_Wid
'Get #1, 23, Img_Hgt
'Close #1
'
''' prepare to dim the array that will hold the image.
'Img_Rgt = (Img_Wid-1)\2
'Img_Lft = -Img_Rgt
'Img_Btm = (Img_Hgt-1)\2
'Img_Top = -Img_Btm
'
''' dim array to hold image. Note: pixel (0, 0) is in the center.
'Dim As Pixel Pixel(Img_Lft to Img_Rgt, Img_Top to Img_Btm)
'
''' imagecreate sprite and load image to sprite
'Img_Buffer = ImageCreate (Img_Wid, Img_Hgt)
'Bload (Img_Name, Img_Buffer)
'
''' load image from sprite to array with point command
'For Y = Img_Top to Img_Btm
' For X = Img_Lft to Img_Rgt
' With Pixel(X, Y)
' .X = X_Mid+X
' .Y = Y_Mid+Y
' C = Point (X-Img_Top, Y-Img_Lft, Img_buffer)
' If C <> RGB(255, 0, 255) Then
' .C = C
' Else
' .C = RGB(0, 0, 0)
' End If
' End With
' Next X
'Next Y
'
''' we don't need the sprite anymore, kill it
'ImageDestroy Img_Buffer
'Img_Buffer = 0
'
''' main program loop
'Do
'
' '' scale in/out with uparrow/downarrow
' If Multikey(80) Then
' Scale *= 1.03
' Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)
' ElseIf Multikey(72) Then
' Scale *= 0.97
' Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)
' End If
'
' '' rotate left/right with leftarrow/rightarrow
' If Multikey(77) Then
' Angle -= 0.03
' Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)
' ElseIf Multikey(75) Then
' Angle += 0.03
' Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)
' End If
'
' '' lock screen in order to use screen pointers
' ScreenLock
'
' '' draw pixel in center of image
' Scrn_Ptr[ X_Mid + Y_Mid * scrn_wid ] = Pixel(0, 0).C
' '' draw all other pixels - 4 at a time
' For Y = Img_Top to 0
' For X = Img_Lft to -1
' '' find pixel positions
' P1 = (X_Mid+X) + (Y_Mid+Y) * scrn_wid
' P2 = (X_Mid-X) + (Y_Mid-Y) * scrn_wid
' P3 = (X_Mid+Y) + (Y_Mid-X) * scrn_wid
' P4 = (X_Mid-Y) + (Y_Mid+X) * scrn_wid
' '' erase old pixels (paint them black)
' Scrn_Ptr[P1] = 0
' Scrn_Ptr[P2] = 0
' Scrn_Ptr[P3] = 0
' Scrn_Ptr[P4] = 0
' '' rotate and zoom
' Rot_Fac_X = X*Cos_Ang - Y*Sin_Ang
' Rot_Fac_Y = X*Sin_Ang + Y*Cos_Ang
' If Rot_Fac_X < Img_Lft Or Rot_Fac_X > Img_Rgt Then Continue For
' If Rot_Fac_Y < Img_Top Or Rot_Fac_Y > Img_Btm Then Continue For
' '' draw new pixels
' Scrn_Ptr[P1] = Pixel(Rot_Fac_X, Rot_Fac_Y).C
' Scrn_Ptr[P2] = Pixel(-Rot_Fac_X, -Rot_Fac_Y).C
' Scrn_Ptr[P3] = Pixel(Rot_Fac_Y, -Rot_Fac_X).C
' Scrn_Ptr[P4] = Pixel(-Rot_Fac_Y, Rot_Fac_X).C
' Next X
' Next Y
'
' ScreenUnLock
'
' Sleep 10, 1
'Loop Until InKey() = Chr(27)
' UPDATES:
' Fixed bug where values 135, 224, and 314 all resolve to -45 degrees.
' Fixed bug where an angle of 46-135 degrees caused the image to be flipped wrong.
' TODO:
' Fix issue where image looks bad at 30, 60, 120, 150, 210, 240, 300, 330 degrees
Dim RtoD
As Double: RtoD
= 180 / Pi
' radians * RtoD = degrees Dim DtoR
As Double: DtoR
= Pi
/ 180 ' degrees * DtoR = radians
' initialize new with empty
NewArray(x, y, 0).origx = x
NewArray(x, y, 0).origy = y
NewArray(x, y, 0).c = iEmpty
' angle is reversed
angle = 360 - angle1
' Shearing each element 3 times in one shot
nangle = angle
' this pre-processing portion basically rotates by 90 to get
' between -45 and 45 degrees, where the 3-shear routine works correctly...
nangle = angle - 90
nangle = angle - 180
nangle = angle - 180
nangle = angle - 270
nangle = nangle + 360
nangle = nangle - 360
rotr = nangle * DtoR
shear1
= Tan(rotr
/ 2) ' correct way
' *** NOTE: this had a bug where the values 135, 224, and 314
' *** all resolve to -45 degrees.
' *** Fixed by changing < to <=
'if angle > 45 and angle < 134 then
flipper = 1
flipper = 2
' *** NOTE: this had a bug where this flipper was wrong
' Fixed by adding case 7
'flipper = 3
flipper = 7
flipper = 0
' Here is where it needs some optimizing possibly... kinda slow...
nx = -y
ny = x
nx = -x
ny = -y
nx = -y
ny = -x
nx = -x
ny = y
nx = x
ny = -y
nx = y
ny = x
nx = y
ny = -x
nx = x
ny = y
clr = OldArray(nx, ny, 0).c
y1 = y * shear1
xy1 = x + y1
fy = (y - xy1 * shear2)
fx = xy1 + fy * shear1
NewArray(fx, fy, 0).c = clr
NewArray(fx, fy, 0).origx = fx
NewArray(fx, fy, 0).origy = fy
' /////////////////////////////////////////////////////////////////////////////
' Same as ShearRotate, except adds iOverwriteCount parameter,
' and counts how many points are overwriting existing points,
' and return that value byref in parameter iOverwriteCount.
Dim RtoD
As Double: RtoD
= 180 / Pi
' radians * RtoD = degrees Dim DtoR
As Double: DtoR
= Pi
/ 180 ' degrees * DtoR = radians
' initialize new with empty
NewArray(x, y, 0).origx = x
NewArray(x, y, 0).origy = y
NewArray(x, y, 0).c = iEmpty
' angle is reversed
angle = 360 - angle1
' Shearing each element 3 times in one shot
nangle = angle
' this pre-processing portion basically rotates by 90 to get
' between -45 and 45 degrees, where the 3-shear routine works correctly...
nangle = angle - 90
nangle = angle - 180
nangle = angle - 180
nangle = angle - 270
nangle = nangle + 360
nangle = nangle - 360
rotr = nangle * DtoR
shear1
= Tan(rotr
/ 2) ' correct way
' *** NOTE: this had a bug where the values 135, 224, and 314
' *** all resolve to -45 degrees.
' *** Fixed by changing < to <=
'if angle > 45 and angle < 134 then
flipper = 1
flipper = 2
' *** NOTE: this had a bug where this flipper was wrong
' Fixed by adding case 7
'flipper = 3
flipper = 7
flipper = 0
' Here is where it needs some optimizing possibly... kinda slow...
iOverwriteCount = 0
nx = -y
ny = x
nx = -x
ny = -y
nx = -y
ny = -x
nx = -x
ny = y
nx = x
ny = -y
nx = y
ny = x
nx = y
ny = -x
nx = x
ny = y
clr = OldArray(nx, ny, 0).c
y1 = y * shear1
xy1 = x + y1
fy = (y - xy1 * shear2)
fx = xy1 + fy * shear1
' count points that will be overwritten
If NewArray
(fx
, fy
, 0).c
<> iEmpty
Then iOverwriteCount = iOverwriteCount + 1
NewArray(fx, fy, 0).c = clr
NewArray(fx, fy, 0).origx = fx
NewArray(fx, fy, 0).origy = fy
' /////////////////////////////////////////////////////////////////////////////
' Tries to fix the problem of 2 points resolving to the same coordinate
' (one overwrites the other, which becomes "lost")
' Returns # points missing (that could not be corrected) in iMissing parameter.
Dim RtoD
As Double: RtoD
= 180 / Pi
' radians * RtoD = degrees Dim DtoR
As Double: DtoR
= Pi
/ 180 ' degrees * DtoR = radians
' initialize new with empty
NewArray(x, y, 0).origx = x
NewArray(x, y, 0).origy = y
NewArray(x, y, 0).c = iEmpty
' angle is reversed
angle = 360 - angle1
' Shearing each element 3 times in one shot
nangle = angle
' this pre-processing portion basically rotates by 90 to get
' between -45 and 45 degrees, where the 3-shear routine works correctly...
nangle = angle - 90
nangle = angle - 180
nangle = angle - 180
nangle = angle - 270
nangle = nangle + 360
nangle = nangle - 360
rotr = nangle * DtoR
shear1
= Tan(rotr
/ 2) ' correct way
' *** NOTE: this had a bug where the values 135, 224, and 314
' *** all resolve to -45 degrees.
' *** Fixed by changing < to <=
'if angle > 45 and angle < 134 then
flipper = 1
flipper = 2
' *** NOTE: this had a bug where this flipper was wrong
' Fixed by adding case 7
'flipper = 3
flipper = 7
flipper = 0
' Here is where it needs some optimizing possibly... kinda slow...
nx = -y
ny = x
nx = -x
ny = -y
nx = -y
ny = -x
nx = -x
ny = y
nx = x
ny = -y
nx = y
ny = x
nx = y
ny = -x
nx = x
ny = y
clr = OldArray(nx, ny, 0).c
y1 = y * shear1
xy1 = x + y1
fy = (y - xy1 * shear2)
fx = xy1 + fy * shear1
' only draw here if this spot is empty
If NewArray
(fx
, fy
, 0).c
= iEmpty
Then NewArray(fx, fy, 0).c = clr
NewArray(fx, fy, 0).origx = fx
NewArray(fx, fy, 0).origy = fy
' don't draw, but save it to a list to handle later
arrLost
(UBound(arrLost
)).c
= clr
arrLost
(UBound(arrLost
)).origx
= fx
arrLost
(UBound(arrLost
)).origy
= fy
' try to place any points that would have overwritten to a spot nearby
' can nearby be determined by the angle of rotation?
' perhaps if we divide the screen up into 4 zones:
'
' --------------------------------------
'| | |
'| zone 4 | zone 1 |
'| 271-359 degrees) | (1-89 degrees) |
'|--------------------------------------|
'| | |
'| zone 3 | zone 2 |
'| (181-269 degrees) | (91-179 degrees) |
'| | |
' --------------------------------------
' in zone search direction (y,x)
' ------- ----------------------
' 1 up + right
' 2 down + right
' 3 down + left
' 4 up + left
iMissing = 0
bFound = FindEmptyShearRotationPoint%(arrLost(iLoop), angle1, iEmpty, x, y, NewArray())
_Echo "Plotted missing point " + Chr$(34) + Chr$(arrLost
(iLoop
).c
) + Chr$(34) + " to (x=" + cstr$
(x
) + ", y=" + cstr$
(y
) + ")" iMissing = iMissing + 1
_Echo "Detected missing point " + Chr$(34) + Chr$(arrLost
(iLoop
).c
) + Chr$(34) + " at (x=" + cstr$
(x
) + ", y=" + cstr$
(y
) + ")"
' /////////////////////////////////////////////////////////////////////////////
' Receives
' FindMe (RotationType) = contains the starting location (.origx, .origy) to start looking from, and the value (.c) to write
' angle1 (Integer) = angle we were rotating to, to determine direction to look in
' iEmpty (Integer) = value to test against for empty
' destX (Integer) = if an empty spot is found, returns the x location here byref
' destY (Integer) = if an empty spot is found, returns the y location here byref
' NewArray() (RotationType array (x,y,127) ) = array representing the screen to search in and plot to
' Returns
' FALSE if no empty spot was found
' TRUE if an empty spot was found, and x,y location returned byref in destX,destY parameters
destX = 0
destY = 0
' Choose search direction depending on the angle
dirX = 1
dirY = -1
dirX = 1
dirY = 1
dirX = -1
dirY = 1
dirX = -1
dirY = -1
dirX = 0
dirY = 0
x = FindMe.origx
y = FindMe.origy
' quit if we're out of bounds
' =============================================================================
' BEGIN PRIMARY SEARCH
' =============================================================================
' look along y axis for a blank spot
destX = x
destY = y + dirY
If NewArray
(destX
, destY
, 0).c
= iEmpty
Then NewArray(destX, destY, 0).c = FindMe.c
bResult = TRUE
' look along x axis for a blank spot
destX = x + dirX
destY = y
If NewArray
(x
+ dirX
, y
, 0).c
= iEmpty
Then NewArray(destX, destY, 0).c = FindMe.c
bResult = TRUE
' look diagonally for a blank spot
destX = x + dirX
destY = y + dirY
If NewArray
(x
+ dirX
, y
+ dirY
, 0).c
= iEmpty
Then NewArray(destX, destY, 0).c = FindMe.c
bResult = TRUE
' =============================================================================
' END PRIMARY SEARCH
' =============================================================================
' =============================================================================
' BEGIN SECONDARY SEARCH
' =============================================================================
'yoda
' =============================================================================
' END SECONDARY SEARCH
' =============================================================================
' Keep looking
x = x + dirX
y = y + dirY
' Return result
FindEmptyShearRotationPoint% = bResult
' /////////////////////////////////////////////////////////////////////////////
Dim RoArray1
(-16 To 16, -16 To 16, 127) As RotationType
Dim RoArray2
(-16 To 16, -16 To 16, 127) As RotationType
' GET A SHAPE TO BE ROTATED
Print "3 shear rotation based on code by leopardpm"
sMap = TestSprite1$
' CONVERT SHAPE TO ARRAY
StringToRotationArray RoArray1(), sMap, "."
Print "Initial contents of Rotation Array:" Print RotationArrayToStringTest
(RoArray1
())
' ROTATE THE SHAPE
Print "Type degrees to rotate (0 TO 360) or non-numeric value to quit." Print "Note: Need to fix code for 30,60,120,150,210,240,300,330 degrees (looks bad)."
Input "Degrees to rotate (q to quit)? "; in$
ShearRotate RoArray1
(), RoArray2
(), D
, Asc(".") Print "Rotated by " + cstr$
(D
) + " degrees:" Print RotationArrayToStringTest
(RoArray2
())
' /////////////////////////////////////////////////////////////////////////////
' Now receives parameter sMap
' which comes from TestSprite1$, TestSprite2$, TestSprite3$, etc.
' e.g. ShearRotateTest2 TestSprite1$
Dim RoArray1
(-16 To 16, -16 To 16, 127) As RotationType
Dim RoArray2
(-16 To 16, -16 To 16, 127) As RotationType
'Dim sMap As String
' GET A SHAPE TO BE ROTATED
Print "3 shear rotation based on code by leopardpm" 'sMap = TestSprite1$
' CONVERT SHAPE TO ARRAY
StringToRotationArray RoArray1(), sMap, "."
' GET START ANGLE
D = 0
Print "Rotated by " + cstr$
(D
) + " degrees:" Print RotationArrayToStringTest
(RoArray1
()) Print "Type an angle (-360 to 360) to rotate to, " Print "or blank to increase by 1 degree, or q to quit." Print "Note: Need to fix code for 30,60,120,150,210,240,300,330 degrees (looks bad)." Print "Hold down <ENTER> to rotate continually." Input "Angle (q to quit)? ", in$
D1 = -500
D1 = 1
' ROTATE TO EACH ANGLE
bFinished = FALSE
' ROTATE CLOCKWISE
ShearRotate1 RoArray1
(), RoArray2
(), D
, Asc("."), iOverwriteCount
'Print "Rotated by " + cstr$(D) + " degrees:"
Print "Rotated by " + cstr$
(D
) + " degrees" + IIFSTR$
(iOverwriteCount
= 0, "", " (" + cstr$
(iOverwriteCount
) + " points overwritten)") + ":"
Print RotationArrayToStringTest
(RoArray2
())
Print "Type an angle (-360 to 360) to rotate to, " Print "or blank to increase by 1 degree, or q to quit." Print "Note: Need to fix code for 30,60,120,150,210,240,300,330 degrees (looks bad)." Print "Hold down <ENTER> to rotate continually." Input "Angle (q to quit)? ", in$
D = D - 1
bFinished = TRUE
bFinished = TRUE
' ROTATE COUNTER-CLOCKWISE
ShearRotate1 RoArray1
(), RoArray2
(), D
, Asc("."), iOverwriteCount
'Print "Rotated by " + cstr$(D) + " degrees:"
Print "Rotated by " + cstr$
(D
) + " degrees" + IIFSTR$
(iOverwriteCount
= 0, "", " (" + cstr$
(iOverwriteCount
) + " points overwritten)") + ":"
Print RotationArrayToStringTest
(RoArray2
())
Print "Type an angle (0 to 360) to rotate to, " Print "or blank to increase by 1 degree, or q to quit." Print "Note: Need to fix code for 30,60,120,150,210,240,300,330 degrees (looks bad)." Print "Hold down <ENTER> to rotate continually." Input "Angle (q to quit)? ", in$
D = D + 1
bFinished = TRUE
bFinished = TRUE
' /////////////////////////////////////////////////////////////////////////////
' Tries to correct for missing points.
' Receives parameter sMap
' which comes from TestSprite1$, TestSprite2$, TestSprite3$, etc.
' e.g. ShearRotateTest3 TestSprite1$
Dim RoArray1
(-16 To 16, -16 To 16, 127) As RotationType
Dim RoArray2
(-16 To 16, -16 To 16, 127) As RotationType
'Dim sMap As String
' GET A SHAPE TO BE ROTATED
Print "3 shear rotation based on code by leopardpm" 'sMap = TestSprite1$
' CONVERT SHAPE TO ARRAY
StringToRotationArray RoArray1(), sMap, "."
' GET START ANGLE
D = 0
Print "Rotated by " + cstr$
(D
) + " degrees:" Print RotationArrayToStringTest
(RoArray1
()) Print "Type an angle (-360 to 360) to rotate to, " Print "or blank to increase by 1 degree, or q to quit." Print "Note: Need to fix code for 30,60,120,150,210,240,300,330 degrees (looks bad)." Print "Hold down <ENTER> to rotate continually." Input "Angle (q to quit)? ", in$
D1 = -500
D1 = 1
' ROTATE TO EACH ANGLE
bFinished = FALSE
' ROTATE CLOCKWISE
ShearRotate2 RoArray1
(), RoArray2
(), D
, Asc("."), iMissing
'Print "Rotated by " + cstr$(D) + " degrees:"
Print "Rotated by " + cstr$
(D
) + " degrees" + IIFSTR$
(iMissing
= 0, "", " (" + cstr$
(iMissing
) + " points missing)") + ":"
Print RotationArrayToStringTest
(RoArray2
())
Print "Type an angle (-360 to 360) to rotate to, " Print "or blank to increase by 1 degree, or q to quit." Print "Note: Need to fix code for 30,60,120,150,210,240,300,330 degrees (looks bad)." Print "Hold down <ENTER> to rotate continually." Input "Angle (q to quit)? ", in$
D = D - 1
bFinished = TRUE
bFinished = TRUE
' ROTATE COUNTER-CLOCKWISE
ShearRotate2 RoArray1
(), RoArray2
(), D
, Asc("."), iMissing
'Print "Rotated by " + cstr$(D) + " degrees:"
Print "Rotated by " + cstr$
(D
) + " degrees" + IIFSTR$
(iMissing
= 0, "", " (" + cstr$
(iMissing
) + " points missing)") + ":"
Print RotationArrayToStringTest
(RoArray2
())
Print "Type an angle (0 to 360) to rotate to, " Print "or blank to increase by 1 degree, or q to quit." Print "Note: Need to fix code for 30,60,120,150,210,240,300,330 degrees (looks bad)." Print "Hold down <ENTER> to rotate continually." Input "Angle (q to quit)? ", in$
D = D + 1
bFinished = TRUE
bFinished = TRUE
' /////////////////////////////////////////////////////////////////////////////
m$ = ""
' 11111111112222222222333
' 12345678901234567890123456789012
m$
= m$
+ "11111111111111111111111111111111" + Chr$(13) ' 1 m$
= m$
+ "4..............................2" + Chr$(13) ' 2 m$
= m$
+ "4....##.....#######.....####...2" + Chr$(13) ' 3 m$
= m$
+ "4...####....##...###...######..2" + Chr$(13) ' 4 m$
= m$
+ "4..##..##...##...###..##....##.2" + Chr$(13) ' 5 m$
= m$
+ "4.##....##..#######...##.......2" + Chr$(13) ' 6 m$
= m$
+ "4.########..#######...##.......2" + Chr$(13) ' 7 m$
= m$
+ "4.########..##...###..##....##.2" + Chr$(13) ' 8 m$
= m$
+ "4.##....##..##...###...######..2" + Chr$(13) ' 9 m$
= m$
+ "4.##....##..#######.....####...2" + Chr$(13) ' 10 m$
= m$
+ "4..............................2" + Chr$(13) ' 11 m$
= m$
+ "4..............................2" + Chr$(13) ' 12 m$
= m$
+ "4..ABBBBBBBBBBBBBBBBBBBBBBBBC..2" + Chr$(13) ' 13 m$
= m$
+ "4..A...........EE...........C..2" + Chr$(13) ' 14 m$
= m$
+ "4..A..........FFFF..........C..2" + Chr$(13) ' 15 m$
= m$
+ "4..A.........GGGGGG.........C..2" + Chr$(13) ' 16 m$
= m$
+ "4..A........HHHHHHHH........C..2" + Chr$(13) ' 17 m$
= m$
+ "4..A.......IIIIIIIIII.......C..2" + Chr$(13) ' 18 m$
= m$
+ "4..A......JJJJJJJJJJJJ......C..2" + Chr$(13) ' 19 m$
= m$
+ "4..DDDDDDDDDDDDDDDDDDDDDDDDDC..2" + Chr$(13) ' 20 m$
= m$
+ "4..............................2" + Chr$(13) ' 21 m$
= m$
+ "4..............................2" + Chr$(13) ' 22 m$
= m$
+ "4.######....########..########.2" + Chr$(13) ' 23 m$
= m$
+ "4.#######...########..########.2" + Chr$(13) ' 24 m$
= m$
+ "4.##...###..##........##.......2" + Chr$(13) ' 25 m$
= m$
+ "4.##....##..########..#######..2" + Chr$(13) ' 26 m$
= m$
+ "4.##....##..########..#######..2" + Chr$(13) ' 27 m$
= m$
+ "4.##...###..##........##.......2" + Chr$(13) ' 28 m$
= m$
+ "4.#######...##........##.......2" + Chr$(13) ' 29 m$
= m$
+ "4.######....########..##.......2" + Chr$(13) ' 30 m$
= m$
+ "4..............................2" + Chr$(13) ' 31 m$
= m$
+ "33333333333333333333333333333332" + Chr$(13) ' 32 TestSprite1$ = m$
' /////////////////////////////////////////////////////////////////////////////
m$ = ""
' 11111111112222222222333
' 12345678901234567890123456789012
m$
= m$
+ "...............AA..............." + Chr$(13) ' 1 m$
= m$
+ "..............//BB.............." + Chr$(13) ' 2 m$
= m$
+ ".............??..CC............." + Chr$(13) ' 3 m$
= m$
+ "............==....DD............" + Chr$(13) ' 4 m$
= m$
+ "...........++......EE..........." + Chr$(13) ' 5 m$
= m$
+ "..........&&........FF.........." + Chr$(13) ' 6 m$
= m$
+ ".........zz..........GG........." + Chr$(13) ' 7 m$
= m$
+ "........yy............HH........" + Chr$(13) ' 8 m$
= m$
+ ".......xx..............II......." + Chr$(13) ' 9 m$
= m$
+ "......ww................JJ......" + Chr$(13) ' 10 m$
= m$
+ ".....vv..................KK....." + Chr$(13) ' 11 m$
= m$
+ "....uu....................LL...." + Chr$(13) ' 12 m$
= m$
+ "...tt......DDAAAAAAA.......MM..." + Chr$(13) ' 13 m$
= m$
+ "..ss.......DDAAAAAAA........NN.." + Chr$(13) ' 14 m$
= m$
+ ".rr........DD.....BB.........OO." + Chr$(13) ' 15 m$
= m$
+ "qq.........DD.....BB..........PP" + Chr$(13) ' 16 m$
= m$
+ "pp.........DD.....BB..........QQ" + Chr$(13) ' 17 m$
= m$
+ ".oo........DD.....BB.........RR." + Chr$(13) ' 18 m$
= m$
+ "..nn.......CCCCCCCBB........SS.." + Chr$(13) ' 19 m$
= m$
+ "...mm......CCCCCCCBB.......TT..." + Chr$(13) ' 20 m$
= m$
+ "....ll....................UU...." + Chr$(13) ' 21 m$
= m$
+ ".....kk..................VV....." + Chr$(13) ' 22 m$
= m$
+ "......jj................WW......" + Chr$(13) ' 23 m$
= m$
+ ".......ii..............XX......." + Chr$(13) ' 24 m$
= m$
+ "........hh............YY........" + Chr$(13) ' 25 m$
= m$
+ ".........gg..........ZZ........." + Chr$(13) ' 26 m$
= m$
+ "..........ff........@@.........." + Chr$(13) ' 27 m$
= m$
+ "...........ee......##..........." + Chr$(13) ' 28 m$
= m$
+ "............dd....$$............" + Chr$(13) ' 29 m$
= m$
+ ".............cc..%%............." + Chr$(13) ' 30 m$
= m$
+ "..............bb\\.............." + Chr$(13) ' 31 m$
= m$
+ "...............aa..............." + Chr$(13) ' 32 TestSprite2$ = m$
' /////////////////////////////////////////////////////////////////////////////
m$ = ""
' 11111111112222222222333
' 12345678901234567890123456789012
m$
= m$
+ "................................" + Chr$(13) ' 1 m$
= m$
+ "................................" + Chr$(13) ' 2 m$
= m$
+ "................................" + Chr$(13) ' 3 m$
= m$
+ "................................" + Chr$(13) ' 4 m$
= m$
+ "................................" + Chr$(13) ' 5 m$
= m$
+ "................................" + Chr$(13) ' 6 m$
= m$
+ "................................" + Chr$(13) ' 7 m$
= m$
+ "................................" + Chr$(13) ' 8 m$
= m$
+ "................................" + Chr$(13) ' 9 m$
= m$
+ "................................" + Chr$(13) ' 10 m$
= m$
+ "................................" + Chr$(13) ' 11 m$
= m$
+ "................................" + Chr$(13) ' 12 m$
= m$
+ "................................" + Chr$(13) ' 13 m$
= m$
+ "................................" + Chr$(13) ' 14 m$
= m$
+ "....It's a SCREEN resolution?..." + Chr$(13) ' 15 m$
= m$
+ "................................" + Chr$(13) ' 16 m$
= m$
+ "................................" + Chr$(13) ' 17 m$
= m$
+ "................................" + Chr$(13) ' 18 m$
= m$
+ "................................" + Chr$(13) ' 19 m$
= m$
+ "................................" + Chr$(13) ' 20 m$
= m$
+ "................................" + Chr$(13) ' 21 m$
= m$
+ "................................" + Chr$(13) ' 22 m$
= m$
+ "................................" + Chr$(13) ' 23 m$
= m$
+ "................................" + Chr$(13) ' 24 m$
= m$
+ "................................" + Chr$(13) ' 25 m$
= m$
+ "................................" + Chr$(13) ' 26 m$
= m$
+ "................................" + Chr$(13) ' 27 m$
= m$
+ "................................" + Chr$(13) ' 28 m$
= m$
+ "................................" + Chr$(13) ' 29 m$
= m$
+ "................................" + Chr$(13) ' 30 m$
= m$
+ "................................" + Chr$(13) ' 31 m$
= m$
+ "................................" + Chr$(13) ' 32 PetrText1$ = m$
' /////////////////////////////////////////////////////////////////////////////
MyString = ""
sLine = ""
sLine = sLine + MyArray(iY, iX)
MyString
= MyString
+ sLine
+ Chr$(13) ArrayToString$ = MyString
' /////////////////////////////////////////////////////////////////////////////
MyString = ""
MyString
= MyString
+ " 11111111112222222222333" + Chr$(13) MyString
= MyString
+ " 12345678901234567890123456789012" + Chr$(13) sLine = ""
sLine
= sLine
+ Right$(" " + cstr$
(iY
), 2) sLine = sLine + MyArray(iY, iX)
sLine
= sLine
+ Right$(" " + cstr$
(iY
), 2) MyString
= MyString
+ sLine
+ Chr$(13) MyString
= MyString
+ " 12345678901234567890123456789012" + Chr$(13) MyString
= MyString
+ " 11111111112222222222333" + Chr$(13) ArrayToStringTest$ = MyString
' /////////////////////////////////////////////////////////////////////////////
Function RotationArrayToStringTest$
(RoArray
() As RotationType
) MyString = ""
MyString
= MyString
+ " ---------------- ++++++++++++++++" + Chr$(13) MyString
= MyString
+ " 1111111 1111111" + Chr$(13) MyString
= MyString
+ " 654321098765432101234567890123456" + Chr$(13) sLine = ""
sLine
= sLine
+ Right$(" " + cstr$
(iY
), 3) sLine
= sLine
+ Chr$(RoArray
(iX
, iY
, 0).c
) sLine
= sLine
+ Right$(" " + cstr$
(iY
), 3) MyString
= MyString
+ sLine
+ Chr$(13) MyString
= MyString
+ " 654321098765432101234567890123456" + Chr$(13) MyString
= MyString
+ " 1111111 1111111" + Chr$(13) MyString
= MyString
+ " ---------------- ++++++++++++++++" + Chr$(13) RotationArrayToStringTest$ = MyString
' /////////////////////////////////////////////////////////////////////////////
' 1. split string by line breaks CHR$(13)
' 2. split lines up to 1 column per char
' 3. count rows, columns
' 4. DIM array, making sure array has
' a) an _ODD_ number of rows/columns, with a center point
' b) index is in cartesian format, where center is (0,0)
' 5. populate array with contents of string
' dimension #1 = columns
' dimension #2 = rows
Dim RoutineName
As String: RoutineName
= "StringToRotationArray"
split MyString, delim$, arrLines$()
iRowCount
= UBound(arrLines$
) + 1
' look at all the rows and find the max # of columns used
iColCount = 0
' count the columns for this row
iCount = 0
iCount = iCount + 1
' if this row has the most so far, then set that to the max
iColCount = iCount
' adjust columns to be odd
iColCount = iColCount + 1
bAddedColumn = TRUE
' calculate array bounds for columns
iHalf1 = (iColCount - 1) / 2
iFrom1 = 0 - iHalf1
iTo1 = iHalf1
' adjust rows to be odd
iRowCount = iRowCount + 1
bAddedRow = TRUE
' calculate array bounds for rows
iHalf2 = (iRowCount - 1) / 2
iFrom2 = 0 - iHalf2
iTo2 = iHalf2
' size array to new bounds
ReDim RoArray
(iFrom1
To iTo1
, iFrom2
To iTo2
, 127) As RotationType
' get value for empty
iEmpty = 32 ' (use space as default)
' clear array
RoArray(iX, iY, 0).c = iEmpty
RoArray(iX, iY, 0).origx = iX
RoArray(iX, iY, 0).origy = iY
' fill array
iY = iY + 1
iX = iX + 1
sChar$
= Mid$(arrLines$
(iRow%
), iCol%
, 1) RoArray
(iX
, iY
, 0).c
= Asc(sChar$
)
End Sub ' StringToRotationArray
' /////////////////////////////////////////////////////////////////////////////
split MyString, delim$, arrLines$()
sChar$
= Mid$(arrLines$
(iRow%
), iCol%
, 1)
sChar$
= Left$(sChar$
, 1) sChar$ = "."
MyArray(iRow% + iDim1, (iCol% - 1) + iDim2) = sChar$
' Exit if out of bounds
' Exit if out of bounds
' /////////////////////////////////////////////////////////////////////////////
'SUB ClearArray (MyArray(1 To 32, 1 To 32) AS STRING, MyString As String)
sChar$ = MyString
sChar$ = " "
sChar$
= Left$(MyString
, 1) MyArray(iRow, iCol) = sChar$
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN GENERAL PURPOSE ROUTINES
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' /////////////////////////////////////////////////////////////////////////////
'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
' /////////////////////////////////////////////////////////////////////////////
Function IIF
(Condition
, IfTrue
, IfFalse
)
' /////////////////////////////////////////////////////////////////////////////
Function IIFSTR$
(Condition
, IfTrue$
, IfFalse$
) If Condition
Then IIFSTR$
= IfTrue$
Else IIFSTR$
= IfFalse$
' /////////////////////////////////////////////////////////////////////////////
' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
IsEven% = TRUE
IsEven% = FALSE
' /////////////////////////////////////////////////////////////////////////////
' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
IsOdd% = TRUE
IsOdd% = FALSE
' /////////////////////////////////////////////////////////////////////////////
' By sMcNeill from https://www.qb64.org/forum/index.php?topic=896.0
IsNum% = TRUE
IsNum% = FALSE
' /////////////////////////////////////////////////////////////////////////////
' Split and join strings
' https://www.qb64.org/forum/index.php?topic=1073.0
'Combine all elements of in$() into a single string with delimiter$ separating the elements.
result$ = result$ + delimiter$ + in$(i)
join$ = result$
' /////////////////////////////////////////////////////////////////////////////
' FROM: String Manipulation
' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_5964-0/
'
'SUMMARY:
' Purpose: A library of custom functions that transform strings.
' Author: Dustinian Camburides (dustinian@gmail.com)
' Platform: QB64 (www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there])
' Revision: 1.6
' Updated: 5/28/2012
'SUMMARY:
'[Replace$] replaces all instances of the [Find] sub-string with the [Add] sub-string within the [Text] string.
'INPUT:
'Text: The input string; the text that's being manipulated.
'Find: The specified sub-string; the string sought within the [Text] string.
'Add: The sub-string that's being added to the [Text] string.
' VARIABLES:
Dim lngLocation
As Long ' The address of the [Find] substring within the [Text] string. Dim strBefore
As String ' The characters before the string to be replaced. Dim strAfter
As String ' The characters after the string to be replaced.
' INITIALIZE:
' MAKE COPIESSO THE ORIGINAL IS NOT MODIFIED (LIKE ByVal IN VBA)
Text2 = Text1
Find2 = Find1
Add2 = Add1
lngLocation
= InStr(1, Text2
, Find2
)
' PROCESSING:
' While [Find2] appears in [Text2]...
' Extract all Text2 before the [Find2] substring:
strBefore
= Left$(Text2
, lngLocation
- 1)
' Extract all text after the [Find2] substring:
strAfter
= Right$(Text2
, ((Len(Text2
) - (lngLocation
+ Len(Find2
) - 1))))
' Return the substring:
Text2 = strBefore + Add2 + strAfter
' Locate the next instance of [Find2]:
lngLocation
= InStr(1, Text2
, Find2
)
' Next instance of [Find2]...
' OUTPUT:
Replace$ = Text2
' /////////////////////////////////////////////////////////////////////////////
' Split and join strings
' https://www.qb64.org/forum/index.php?topic=1073.0
'
' FROM luke, QB64 Developer
' Date: February 15, 2019, 04:11:07 AM
'
' Given a string of words separated by spaces (or any other character),
' splits it into an array of the words. I've no doubt many people have
' written a version of this over the years and no doubt there's a million
' ways to do it, but I thought I'd put mine here so we have at least one
' version. There's also a join function that does the opposite
' array -> single string.
'
' Code is hopefully reasonably self explanatory with comments and a little demo.
' Note, this is akin to Python/JavaScript split/join, PHP explode/implode.
'Split in$ into pieces, chopping at every occurrence of delimiter$. Multiple consecutive occurrences
'of delimiter$ are treated as a single instance. The chopped pieces are stored in result$().
'
'delimiter$ must be one character long.
'result$() must have been REDIMmed previously.
Sub split
(in$
, delimiter$
, result$
()) start = 1
start = start + 1
finish
= InStr(start
, in$
, delimiter$
) result$
(UBound(result$
)) = Mid$(in$
, start
, finish
- start
) start = finish + 1
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END GENERAL PURPOSE ROUTINES
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' #END
' ################################################################################################################################################################