Module Module1

    Sub Main()
        Dim e As IEnumerator(Of LatticePoint) = New LatticePointEnumerator()
        Dim i As Integer
        For i = 1 To 999
            e.MoveNext()
        Next
        e.MoveNext()
        Console.WriteLine(i.ToString() & ":" & e.Current.ToString())

        For i = 1001 To 999999
            e.MoveNext()
        Next
        e.MoveNext()
        Console.WriteLine(i.ToString() & ":" & e.Current.ToString())

        For i = 1000001 To 99999999
            e.MoveNext()
        Next
        e.MoveNext()
        Console.WriteLine(i.ToString() & ":" & e.Current.ToString())

        Console.ReadKey()
    End Sub

End Module

Public Class LatticePointEnumerator
    Implements IEnumerator(Of LatticePoint)

    Private _list As LinkedList(Of LatticePoint)
    Private _r As Integer
    Private _pointlist As List(Of LatticePoint)
    Private _enumerator As IEnumerator(Of LatticePoint)

    Public Sub New()
        _list = New LinkedList(Of LatticePoint)
        _pointlist = New List(Of LatticePoint)
        Reset()
    End Sub

    Public Sub Reset() Implements System.Collections.IEnumerator.Reset
        _list.Clear()
        _list.AddLast(New LatticePoint(0, 0))
        _list.AddLast(New LatticePoint(1, 0))
        _list.AddLast(New LatticePoint(1, 1))
        _list.AddLast(New LatticePoint(2, 0))
        _list.AddLast(New LatticePoint(2, 1))
        _list.AddLast(New LatticePoint(2, 2))
        _list.AddLast(New LatticePoint(3, 0))
        _list.AddLast(New LatticePoint(3, 1))
        _list.AddLast(New LatticePoint(3, 2))
        _list.AddLast(New LatticePoint(3, 3))
        _r = 4
        _pointlist.Clear()
        _enumerator = _pointlist.GetEnumerator()
    End Sub

    Public ReadOnly Property Current() As LatticePoint Implements System.Collections.Generic.IEnumerator(Of LatticePoint).Current
        Get
            Return _enumerator.Current
        End Get
    End Property

    Public ReadOnly Property Current1() As Object Implements System.Collections.IEnumerator.Current
        Get
            Return DirectCast(_enumerator, IEnumerator).Current
        End Get
    End Property

    Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
        If _enumerator.MoveNext() Then Return True

        If _list.First.Value._r2 >= _r * _r Then
            Dim node As LinkedListNode(Of LatticePoint)
            Dim p As LatticePoint
            node = _list.First
            For y As Integer = 0 To _r
                p = New LatticePoint(_r, y)
                While node IsNot Nothing AndAlso p._r2 > node.Value._r2
                    node = node.Next
                End While
                If node Is Nothing Then _list.AddLast(p) Else _list.AddBefore(node, p)
            Next
            _r += 1
        End If

        _pointlist.Clear()
        _pointlist.Add(_list.First.Value)
        _list.RemoveFirst()
        While _list.First.Value._r2 = _pointlist(0)._r2
            _pointlist.Add(_list.First.Value)
            _list.RemoveFirst()
        End While

        Dim j As Integer
        j = _pointlist.Count - 1
        If _pointlist(j).X = _pointlist(j).Y Then j -= 1
        For i As Integer = j To 0 Step -1
            _pointlist.Add(New LatticePoint(_pointlist(i).Y, _pointlist(i).X))
        Next
        j = _pointlist.Count - 1
        If _pointlist(j).X = 0 Then j -= 1
        For i As Integer = j To 0 Step -1
            _pointlist.Add(New LatticePoint(-_pointlist(i).X, _pointlist(i).Y))
        Next
        j = _pointlist.Count - 1
        If _pointlist(j).Y = 0 Then j -= 1
        For i As Integer = j To 1 Step -1
            _pointlist.Add(New LatticePoint(_pointlist(i).X, -_pointlist(i).Y))
        Next
        If _pointlist(0).Y <> 0 Then _pointlist.Add(New LatticePoint(_pointlist(0).X, -_pointlist(0).Y))

        _enumerator = _pointlist.GetEnumerator()
        _enumerator.MoveNext()

        Return True
    End Function

    Public Sub Dispose() Implements IDisposable.Dispose
    End Sub

End Class

Public Class LatticePoint
    Friend _x As Integer
    Friend _y As Integer
    Friend _r2 As Long

    Friend Sub New(ByVal x As Integer, ByVal y As Integer)
        _x = x
        _y = y
        _r2 = x * x + y * y
    End Sub

    Public ReadOnly Property X() As Integer
        Get
            Return _x
        End Get
    End Property

    Public ReadOnly Property Y() As Integer
        Get
            Return _y
        End Get
    End Property

    Public ReadOnly Property SquaredRadius() As Long
        Get
            Return _r2
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return String.Format("({0}, {1}) [{2}]", _x.ToString(), _y.ToString(), _r2.ToString())
    End Function

End Class