Tuesday, June 25, 2013

Bogged Down

I'm having Euphoria sequence withdrawals. The Euphoria sequence data type is the greatest invention in programming since programming. No other language has it. Rebol might allow you to create something like it, but PureBasic, even with a list type is just not the same. For example:

temp = {{},{}}
for Index = 1 to 360 do
    temp[1] = append(temp[1], sin(Index*PI/180))
    temp[2] = append(temp[2], cos(Index*PI/180))
end for
constant sin_lookup = temp[1], cos_lookup = temp[2]

function Rotate(sequence shape, atom facing)
    for ndex = 1 to length(shape) do
        shape[ndex] = {
            (shape[ndex][Xord] * cos_lookup[facing])
            -(shape[ndex][Yord] * sin_lookup[facing]),
            (shape[ndex][Yord] * cos_lookup[facing])
            +(shape[ndex][Xord] * sin_lookup[facing])}
    end for
    return shape
end function


Let's take out the math so we can focus on the structure...

1)   temp = {{},{}}
          for Index = 1 to 360 do
2)           temp[1] = append(temp[1], some_real_number)
               temp[2] = append(temp[2], some_real_number)
           end for
3)        constant sin_lookup = temp[1], cos_lookup = temp[2]

        function Rotate(sequence shape, atom facing)
            for ndex = 1 to length(shape) do
4)             shape[ndex] = {new_real_x,new_real_y}
            end for
            return shape
        end function


1) Temp is an empty sequence but already with structure. Temp is not an array but does the work of an array and more.

2) We can lengthen just part of a sequence. It just happens we need to lengthen both legs by the same amount.

3) We create two immutable sequences from part of another and assign values and structure all in one operation. Under the covers it's just a pointer to an allocated block of memory but Euphoria does all allocation and deallocation for you without straining a single programmer brain cell.

4) Didn't you see those five lines were actually just one?

Translating this to PureBasic starts with:

Structure some_point // range from -128 to 127. Enough for my sprites //
    X.b
    Y.b
EndStructure

Structure real_point // for rotation values (both factors and results) //
    X.d
    Y.d
EndStructure

Procedure GetRotationFactors(facing)
    rads=Radian(facing)
    rotation_factors.real_point/X = sin(rads)
    rotation_factors.real_point/Y = cos(rads)
    ProcedureReturn rotation_factors
EndProcedure

NewList temp()
Index = 1
While (Index <= 360)
    AddElement temp()
    temp() = GetRotationFactors(Index)
    Index += 1
Wend

...and so on...

No comments: