I want to make a line rotate. I studied the pi and radians and I made my own algorithm (if I can call it like that). I don't like to use already-made code from the Internet. I want to discover them alone, but using logic. Here is the code:
Dim pi As Double
Dim a, b, c, d, e, x, y As Double
Dim speed, radius As Integer
Private Sub Form_Load()
pi = 3.14159265358979
speed = 1
radius = 600
End Sub
Private Sub Command1_Click()
Timer1.Enabled = Not Timer1.Enabled
If Timer1.Enabled = True Then
Command1.Caption = "Stop"
Else
Command1.Caption = "Start"
End If
End Sub
Private Sub Timer1_Timer()
ForeColor = vbWhite
timer1.interval=speed
Refresh
a = a + 2
b = Sin((a * pi) / 180)
c = Cos((a * pi) / 180)
y = radius * b
x = radius * c
Call Label1.Move(6240 + x, 4200 + y)
If Left(b, 1) = "-" Then
Label1.Caption = "---"
Else
Label1.Caption = "+++"
End If
If Left(c, 1) = "-" Then
Label1.Caption = Label1.Caption & " " & "---"
Else
Label1.Caption = Label1.Caption & " " & "+++"
End If
Line (3000 + x, 4200 + y)-(6240 + x, 4200 + y)
Line (3000, 4200)-(3000 + x, 4200 + y)
Line (6240, 4200)-(6240 + x, 4200 + y)
For d = 3000 To 6240
Line (d, 4200)-(3000 + x, 4200 + y)
Next
For e = 3000 + x To 6240 + x
Line (e, 4200 + y)-(6240, 4200)
Next
End Sub
I want to rotate the line on x-axis, not z (it appears to be z). I recalculated everything, but I don't see where is the problem. What would be an explained formula?
I believe you are after the following effect:
Option Explicit
Dim D As Long, S As Long, Y As Long
Private Sub Command1_Click()
Timer1.Enabled = Not Timer1.Enabled
If Timer1.Enabled = True Then
Command1.Caption = "Stop"
Else
Command1.Caption = "Start"
End If
End Sub
Private Sub Form_Load()
D = 1 'Start going down; change to 0 to start going up instead
Y = 100 'Mid point
End Sub
Private Sub Timer1_Timer()
If S Then
If S = 8 Then
S = 0
Else
S = S + 1
lblRate = "0"
Exit Sub
End If
End If
Refresh
If D Then
If Y < 200 Then
Select Case Y
Case Is < 20
'Begin to accelerate
Y = Y + 1
lblRate = "+1"
Case Is < 40
'Continue to accelerate
Y = Y + 2
lblRate = "+2"
Case Is < 160
'Set acceleration to peak
Y = Y + 3
lblRate = "+3"
Case Is < 180
'Begin to decelerate
Y = Y + 2
lblRate = "+2"
Case Else
'Continue to decelerate
Y = Y + 1
lblRate = "+1"
End Select
Else
'Stop and reverse direction
D = 0
S = 1
lblRate = "0"
End If
Else
If Y > 0 Then
Select Case Y
Case Is < 20
'Begin to accelerate
Y = Y - 1
lblRate = "-1"
Case Is < 40
'Continue to accelerate
Y = Y - 2
lblRate = "-2"
Case Is < 160
'Set acceleration to peak
Y = Y - 3
lblRate = "-3"
Case Is < 180
'Begin to decelerate
Y = Y - 2
lblRate = "-2"
Case Else
'Continue to decelerate
Y = Y - 1
lblRate = "-1"
End Select
Else
'Stop and reverse direction
D = 1
S = 1
End If
End If
Line (120, 100)-(120, Y)
End Sub
While not technically following a properly calculated curvature, it is more of a simplified version of a line rotating around the X-axis.
Also, make sure to use the Pixel scale mode, rather than Twips, for better drawing performance.
Related
I need your help with the coordinates. What I would like to happen is to print an "X" after the given coordinates. Example: The given coordinates for x-axis is 2 and y-axis is 2
the output will be:
So basically, 2 "#" on the top and 2 "#" on the left, then it will print the letter "X"
Dim d As String = ""
For i = 0 To NumericUpDownX.Value
For j = 0 To NumericUpDownY.Value
d = d & "#"
Next
d = d & vbNewLine
Next
output.Text = d
I was able to print the # but I can't seem to figure out how to put the "X" there.
I'd do it like this with the String constructor and PadLeft:
Dim d As New System.Text.StringBuilder
For y = 0 To NumericUpDownY.Value
If y < NumericUpDownY.Value Then
d.AppendLine(New String("#", NumericUpDownX.Value + 1))
Else
d.AppendLine("X".PadLeft(NumericUpDownX.Value + 1, "#"))
End If
Next
output.Text = d.ToString
If you want something more inline with what you were originally doing, then:
Dim d As String = ""
For y = 0 To NumericUpDownY.Value
For x = 0 To NumericUpDownX.Value
If y = NumericUpDownY.Value AndAlso x = NumericUpDownX.Value Then
d = d & "X"
Else
d = d & "#"
End If
Next
d = d & vbCrLf
Next
output.Text = d
I have rectangle that's add another rectangle depend on how many stamps/receipt to be print.
I add another rectangle using for loop but if I manage to add more than 3 rectangles the other rectangles will not diplay because it's keeping align straight or if I use if else if e.pagebounds.widht < (the last width of my rectangle) it goes down and it's fine but how about the next... next ... next for the row 3 and up how can I get that this is my code so far
Dim rec As Rectangle
Dim x1, y1 As Integer
Dim nextline As Integer
x1 = 40
y1 = 40
Dim b As Integer = 0
Dim containerrectangle As Rectangle
containerrectangle = New Rectangle(e.PageBounds.X, e.PageBounds.Y, e.PageBounds.Width, e.PageBounds.Height)
For i = 0 To 6
If e.PageBounds.Width - 100 < x1 + b Then
nextline = 40
'reset the x-axis of the rectangle
y1 = 250
b = 40
rec = New Rectangle(b, y1 + 50, 250, 250)
e.Graphics.DrawRectangle(Pens.Sienna, rec)
y1 += 250
b += 10
Else
rec = New Rectangle(x1 + b, 40, 250, 250)
e.Graphics.DrawRectangle(Pens.Sienna, rec)
x1 += 250
b += 10
End If
Next
please see image https://imgur.com/a/ssv6YzX
Have a look into this code - I'd say it's more straight forward:
Dim RectTemplate As New Rectangle(0, 0, 250, 250)
Dim GapPx As Int32 = 12 ' set gap between rectangles
Dim StaPt As New Point(GapPx, GapPx * 2) ' set starting point
Dim N As Int32 = 15 ' set (or get) the totalnumber of rectangles
Dim nL As Int32 = Math.Floor((e.PageBounds.Width - GapPx) / (RectTemplate.Width + GapPx)) ' number of rectangles per row
Dim nR As Int32 = Math.Ceiling(N / nL) ' number of rows of rectangles
For ir = 0 To nR - 1 ' process all rows
For il = 0 To nL - 1 ' process all rectangles in a row
Dim rect As New Rectangle(StaPt.X + il * (RectTemplate.Width + GapPx), StaPt.Y + ir * (RectTemplate.Height + GapPx), RectTemplate.Width, RectTemplate.Height)
e.graphics.DrawRectangle(Pens.Sienna, rect)
Next
Next
I'm trying to create a method converting a number to normalized scientific notation, here is the code that I'm using to calculate mantissa and exponent:
ConvNSN 1000, M, P
MsgBox M & "e" & P
Sub ConvNSN(N, M, P)
If N = 0 Then
P = 0
M = 0
Else
P = Int(Log(Abs(N)) / Log(10))
M = N / 10 ^ P
End If
End Sub
The problem I am facing is that this code gives wrong exponent value for some numbers, eg 1000, 10E+6, 10E+9, 10E+12, 10E+13, etc... Exactly for 1000 converted should be 1e3, but not 10e2. It's obvious that the same problem with numbers, whose logarithms are close to an integer value, like Log(1 - 5.55111512312578E-17) / Log(10), which result is 0, however 1 - 5.55111512312578E-17 less then 1, and result has to be negative.
How can I get rid of Double type imprecision, and get this code to work properly?
UPDATE
I assume the fastest and quite accurate method to calculate mantissa and exponent of number in normalized scientific notation may be as follows:
Sub ConvNSN(N, M, P)
Dim A
If N = 0 Then
P = 0
M = 0
Exit Sub
End If
A = Abs(N)
If A < 1 Then
P = Int(Log(A) / Log(10))
Else
P = Int(Log(A) / Log(10) * (2 + Log(.1) / Log(10)))
End If
M = N / 10 ^ P
End Sub
Or another one, based on #Bob's solution:
Sub ConvNSN(N, M, P)
If N = 0 Then
P = 0
M = 0
Else
P = Int(Log(Abs(N)) / Log(10))
M = N / 10 ^ P
End If
If Abs(M) = "10" Then
M = M / 10
P = P + 1
End If
End Sub
First one slightly faster. Both of them process exponent from -322 to 308, but return not normalized mantissa with powers of 10 less then -310. I have not tested them yet with numbers, whose logarithms are a marginally less but very close to an integer values.
UPDATE 2
I decided to attach here an extra Sub ConvEN(), allowing to represent a number in engineering notation with SI prefixes from "p" to "T":
N = .0000456789
ConvNSN N, M, P
M = Round(M, 2)
ConvEN M, P, R, S
MsgBox R & " " & S & "Units"
Sub ConvNSN(N, M, P)
Dim A
If N = 0 Then
P = 0
M = 0
Exit Sub
End If
A = Abs(N)
If A < 1 Then
P = Int(Log(A) / Log(10))
Else
P = Int(Log(A) / Log(10) * (2 + Log(.1) / Log(10)))
End If
M = N / 10 ^ P
End Sub
Sub ConvEN(M, P, R, S)
DIM Q, P3
Q = int(P / 3)
P3 = Q * 3
If Q >= -4 And Q <= 4 Then
S = Array("p", "n", ChrW(&H03BC), "m", "", "k", "M", "G", "T")(Q + 4)
Else
S = "e" & P3 & " "
End If
R = M * 10 ^ (P - P3)
End Sub
Try this:
ConvNSN 1000, M, P
MsgBox M & "E" & P
ConvNSN 0.00000000000000001234, M, P
MsgBox M & "E" & P
ConvNSN -0.00000000000000001234, M, P
MsgBox M & "E" & P
Sub ConvNSN(N, M, P)
P = 0
If N < 0 Then
S = -1
ElseIf N > 0 Then
S = 1
Else
M = 0
Exit Sub
End If
M = Abs(N)
If M >= 10 Then
While M >= 10
M = M / 10
P = P + 1
Wend
M = M * S
Exit Sub
End If
If M < 1 Then
While M < 1
M = M * 10
P = P - 1
Wend
M = M * S
Exit Sub
End If
End Sub
Based on the comments, I re-wrote this my way, ignoring the structure from the OP.
MsgBox NSN(-0.0000000000000000000123456789,4)
MsgBox NSN(1234567890000000000000000000,4)
Function NSN(Number, Accuracy)
Exponent = 0
If Number > 0 Then
Sign = 1
ElseIf Number < 0 Then
Sign = -1
Else
NSN = 0
Exit Function
End If
Number = Number * Sign
If Number >= 10 Then
While Number >= 10
Number = Number / 10
Exponent = Exponent + 1
Wend
ElseIf Number < 1 Then
While Number < 1
Number = Number * 10
Exponent = Exponent - 1
Wend
End If
Number = Round(Number, Accuracy)
If Number = "10" Then
Number = 1
Exponent = Exponent + 1
End If
Number = Number * Sign
If Exponent = 0 Then
NSN = Number
Else
NSN = Number & "E" & Exponent
End If
End Function
Using strings rather than maths can help. Add your own error checking.
Num = "1000000.0005"
NumOfDigits = 4
Mag = Instr(Num, ".")
Num = Replace(Num, ".", "")
MSD = Left(Num, 1)
Rest = Mid(num, 2, NumOfDigits)
msgbox MSD & "." & Rest & " x 10^" & (Mag -2)
So I recently purchased the draw library on Touch Lua! I've started trying to make a simple Tic Tac Toe game. I'm using a simple setup they used to detect clicks on the NumPad default program, so the buttons should work.
The problem is that when you tap a square, the O fills into seemingly-random squares, sometimes more than 1, up to 4+ squares may get filled.
I suspect the problem is the function Picked, which sets the title to X/O and then updates the board.
local Turn = nil
local Move = "O"
local Mode = nil
::ModePick::
print("1 player mode? (y/n)")
local plrs = io.read()
if plrs == "y" then
Mode = 1
goto TurnChoice
elseif plrs == "n" then
Mode = 2
goto Game
else
goto ModePick
end
::TurnChoice::
print("Would you like to go first? (Be O) (y/n)")
do
local pick = io.read()
if pick == "y" then
Turn = 1
elseif pick == "n" then
Turn = 2
else
goto TurnChoice
end
end
::Game::
local Buttons = {}
draw.setscreen(1)
draw.settitle("Tic Tac Toe")
draw.clear()
width, height = draw.getport()
function Picked(b)
for i,v in pairs(Buttons) do
if v == b then
b.title = Move
UpdateBoard()
end
end
--Fill in X/O details
--Detect if there's a tic/tac/toe
--Set winning screen
if Move == "O" then
--Compute Move (1 player)
--Move = "X" (2 player)
else
Move = "O"
end
end
function DrawButton(b)
draw.setfont('Helvetica', 50)
draw.setlinestyle(2, 'butt')
local x1, y1 = b.x, b.y
local x2, y2 = x1+b.width, y1+b.height
draw.rect(x1, y1, x2, y2, b.color)
local w, h = draw.stringsize(b.title)
local x = b.x + (b.width - w)/2
local y = b.y + (b.height - h)/2
draw.string(b.title, x, y, draw.black)
return b
end
function Button(x, y, x2, y2, title, color, action)
local action = action or function() end
local button = {x = x, y = y, width = x2, height = y2, color = color, title = title, action = action}
table.insert(Buttons, button)
return button
end
function LookUpButton(x, y)
for i = 1, #Buttons do
local b = Buttons[i]
if x > b.x and x < b.x+b.width and y > b.y and y < b.y+b.height then
return b
end
end
return nil
end
function TouchBegan(x, y)
local b = LookUpButton(x, y)
if b then
b.action(b)
end
end
function TouchMoved(x, y)
end
function TouchEnded(x, y)
end
draw.tracktouches(TouchBegan, TouchMoved, TouchEnded)
function CreateButton(x,y,x2,y2,txt,col,func)
return DrawButton(Button(x, y, x2, y2, txt, col, func))
end
function UpdateBoard()
draw.clear()
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons[i + ii].title, draw.blue, Picked)
end
end
end
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, "", draw.blue, Picked)
end
end
while true do
draw.doevents()
sleep(1)
end
Note: Sorry if the indention came out wrong, I pasted all this code in on my iPod, so I had to manually put in 4 spaces starting each line.
If anybody could help me out with this small setback I have, I'd love the help, if there's anything I'm missing I'd gladly edit it in just reply in the comments :D
EDIT: I've modified some of the code to fix how the table keeps getting new buttons, this is the code I have now, same problem, buttons are added in wrong place (and getting removed now):
function Button(x, y, x2, y2, title, color, action, prev)
local action = action or function() end
local button = {x = x, y = y, width = x2, height = y2, color = color, title = title, action = action}
if prev then
for i,v in pairs(Buttons) do
if v == prev then
table.remove(Buttons, i)
end
end
end
table.insert(Buttons, button)
return button
end
function CreateButton(x,y,x2,y2,txt,col,func, prev)
return DrawButton(Button(x, y, x2, y2, txt, col, func, prev))
end
function UpdateBoard()
draw.clear()
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons[i + ii].title, draw.blue, Picked, Buttons[i + ii])
end
end
end
EDIT: Thanks to Etan I've fixed UpdateBoard, squares are still random:
function UpdateBoard()
draw.clear()
local n = 1
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons[n].title, draw.blue, Picked, Buttons[n])
n = n + 1
end
end
end
It's been a while since I've got around to post the finished code, but this is what it looks like:
function UpdateBoard(ended)
local ended = ended or false
local Act = nil
if ended == true then
Act = function() end
else
Act = Picked
end
draw.clear()
local Buttons2 = {}
for i,v in pairs(Buttons) do
Buttons2[i] = v
end
Buttons = {}
local n = 1
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons2[n].title, draw.blue, Act, Buttons2[n], i, ii)
n = n + 1
end
end
OpenButtons = {}
ClosedButtons = {}
for i,v in pairs(Buttons) do
if v.title == "" then
table.insert(OpenButtons, v)
else
table.insert(ClosedButtons, v)
end
end
end
It may seem a bit complicated for the question, but this is the code after multiple other things.
The main difference you should note here, is that it's recreating the table of buttons, so it does not recount new buttons, and it uses n to count up, instead of using i and ii.
for i = 0 to 23
'' ...
'' create 'line' control
'' ...
line.x1 = (inner_radius*cos(15 * i)) + centerx
line.y1 = (inner_radius*sin(15 * i)) + centery
line.x2 = (outer_radius*cos(15 * i)) + centerx
line.y2 = (outer_radius*sin(15 * i)) + centery
next
I'm using this algorithm to render many line controls to make something like the following:
The result is rather bizarre:
I think this happens due to the rounding of the cos() and sin() functions, so my question is, is there some algorithm I can apply to fix the rounding? Or is there a better way to render such controls, perhaps?
EDIT:
The problem, as pointed by Hrqls was that I was using degrees instead of radians... this is the function that I ended up using:
Sub ProgressAnim(ByVal centerx, _
ByVal centery, _
ByVal outer_radius, _
ByVal inner_radius, _
ByVal step_count, _
ByVal line_width)
Dim pi
Dim degstep
Dim scan
Dim newcontrol As Line
Dim controlid
pi = 4 * Atn(1)
degstep = pi / (step_count / 2)
For scan = 0 To step_count - 1
controlid = "line" & (scan + 1)
Set newcontrol = Me.Controls.Add("vb.line", controlid)
newcontrol.X1 = centerx + (inner_radius * Cos(degstep * scan))
newcontrol.Y1 = centery + (inner_radius * Sin(degstep * scan))
newcontrol.X2 = centerx + (outer_radius * Cos(degstep * scan))
newcontrol.Y2 = centery + (outer_radius * Sin(degstep * scan))
newcontrol.BorderStyle = 1
newcontrol.BorderWidth = line_width
newcontrol.Visible = True
Next
End Sub
Calling it like this
ProgressAnim 150, 250, 16, 9, 18, 1
produces this:
which is much closer to what I expected... sadly, I still don't know how to achieve anti-aliasing, but this will do. (For the moment, at least) :)
Your problem is that you calculate the angles in degrees while VB uses radians for its angles
have a look at the following project :
Option Explicit
Private Sub Form_Click()
DrawWheel
End Sub
Private Sub DrawWheel()
Dim intI As Integer
Dim sngRadius As Single
Dim sngRadiusY As Single
Dim sngCenterX As Single, sngCenterY As Single
Dim sngX1 As Single, sngY1 As Single
Dim sngX2 As Single, sngY2 As Single
Dim sngStep As Single
Dim sngAngle As Single
Dim sngCos As Single, sngSin As Single
'calculate form sizes
sngRadius = (ScaleWidth - 240) / 2
sngRadiusY = (ScaleHeight - 240) / 2
sngCenterX = 120 + sngRadius
sngCenterY = 120 + sngRadiusY
If sngRadiusY < sngRadius Then sngRadius = sngRadiusY
'draw circle
Circle (sngCenterX, sngCenterY), sngRadius
'calculate step between lines
sngStep = Atn(1) / 3
'draw lines
For intI = 0 To 23
'calculate angle for each line
sngAngle = sngStep * intI
'calculate coordinates for each line
sngCos = Cos(sngAngle)
sngSin = Sin(sngAngle)
sngX1 = sngCenterX + sngCos * sngRadius / 10
sngY1 = sngCenterY + sngSin * sngRadius / 10
sngX2 = sngCenterX + sngCos * sngRadius
sngY2 = sngCenterY + sngSin * sngRadius
'draw each lines
Line (sngX1, sngY1)-(sngX2, sngY2)
'print sequence number
Print CStr(intI)
Next intI
End Sub
Click on the form to draw the wheel
Atn(1) is PI/4 ... For 24 lines you need to divide 2*PI by 24 .. thus you need to divide PI by 12 ... which makes you divide Atn(1) by 3
change for i = 0 to 23 to for i = 0 to 21
and (15 * i) with (0.3 * i)
Try that code in form1 with a timer1:
Dim c As Integer, centerx As Integer, centery As Integer, inner_radius As Integer, outer_radius As Integer
Dim x1 As Single, y1 As Single, x2 As Single, y2 As Single
Private Sub Form_Load()
c = 0
centerx = Form1.Width / 2
centery = Form1.Height / 2
inner_radius = 1200
outer_radius = 1
Timer1.Interval = 200
End Sub
Private Sub Timer1_Timer()
x1 = (inner_radius * Cos(0.3 * c)) + centerx
y1 = (inner_radius * Sin(0.3 * c)) + centery
x2 = (outer_radius * Cos(0.3 * c)) + centerx
y2 = (outer_radius * Sin(0.3 * c)) + centery
Line (x1, y1)-(x2, y2), RGB(0, 0, 0)
c = c + 1
If c = 21 Then Timer1.Enabled = False
End Sub
check your numbers in this example to see the drawing behavior.
I would ensure that you keep the greatest accuracy by using proper fractions of 2PI.
Fiddle with the constants until you get roughly what you want:
Option Explicit
Private Sub Form_Load()
Timer.Interval = 50
End Sub
Private Sub Timer_Timer()
DrawRadialLines
End Sub
Private Sub DrawRadialLines()
Const ksngPI As Single = 3.14159!
Const ksngCircle As Single = 2! * ksngPI
Const ksngInnerRadius As Single = 130!
Const ksngOuterRadius As Single = 260!
Const ksngCenterX As Single = 1200!
Const ksngCenterY As Single = 1200!
Const klSegmentCount As Long = 12
Const klLineWidth As Long = 3
Static s_lActiveSegment As Integer ' The "selected" segment.
Dim lSegment As Long
Dim sngRadians As Single
Dim sngX1 As Single
Dim sngY1 As Single
Dim sngX2 As Single
Dim sngY2 As Single
Dim cLineColour As OLE_COLOR
Me.DrawWidth = klLineWidth
' Overdraw previous graphic.
Me.Line (ksngCenterX - ksngOuterRadius - Screen.TwipsPerPixelX * 2, ksngCenterY - ksngOuterRadius - Screen.TwipsPerPixelY * 2)-(ksngCenterX + ksngOuterRadius + Screen.TwipsPerPixelX * 2, ksngCenterY + ksngOuterRadius + Screen.TwipsPerPixelY * 2), Me.BackColor, BF
For lSegment = 0 To klSegmentCount - 1
'
' Work out the coordinates for the line to be draw from the outside circle to the inside circle.
'
sngRadians = (ksngCircle * CSng(lSegment)) / klSegmentCount
sngX1 = (ksngOuterRadius * Cos(sngRadians)) + ksngCenterX
sngY1 = (ksngOuterRadius * Sin(sngRadians)) + ksngCenterY
sngX2 = (ksngInnerRadius * Cos(sngRadians)) + ksngCenterX
sngY2 = (ksngInnerRadius * Sin(sngRadians)) + ksngCenterY
' Work out how many segments away from the "current segment" we are.
' The current segment should be the darkest, and the further away from this segment we are, the lighter the colour should be.
Select Case Abs(Abs(s_lActiveSegment - lSegment) - klSegmentCount \ 2)
Case 0!
cLineColour = RGB(0, 0, 255)
Case 1!
cLineColour = RGB(63, 63, 255)
Case 2!
cLineColour = RGB(117, 117, 255)
Case Else
cLineColour = RGB(181, 181, 255)
End Select
Me.Line (sngX1, sngY1)-(sngX2, sngY2), cLineColour
Next lSegment
' Move the current segment on by one.
s_lActiveSegment = (s_lActiveSegment + 1) Mod klSegmentCount
End Sub