Código de ordenação de voxels

Prometi, aqui está. O mestrado começou e percebi que ele vai destruir o que resta de minha alma =D

Em breve faço um post sobre colisão de polígonos convexos.

EDIT: Sugestões para otimização são bem-vindas!

import math

def trans(xa, ya, xb, yb, voxel):
    """
    Given a start and end point, returns the list of voxels
    that must be checked against collisions, in priority order,
    as a list of (voxel_x, voxel_y) tuples.

    A brief study about parametric line equations will help!

    Implements the method seem at: http://www.cs.yorku.ca/~amana/research/grid.pdf

    @param xa: The start x coord
    @param ya: The start y coord
    @param xb: The end x coord
    @param yb: The end y coord
    @param voxel: The voxel width and length (i.e. for 16x16 tiles it would be 16)

    @author: Paolo victor, paolovictor@gmail.com
    """
    # Getting start and end x and y voxels
    xa_g, ya_g = xa // voxel, ya // voxel
    xb_g, yb_g = xb // voxel, yb // voxel

    # Base cases: same y voxel, same x voxel
    if xa_g == xb_g or ya_g == yb_g:
        # Getting x and y increments
        if xa_g < xb_g: x_inc = 1
        else: x_inc = -1

        if ya_g < yb_g: y_inc = 1
        else: y_inc = -1

        # If it's in same horizontal voxel, test if it's in the same
        # vertical voxel. Return a straight vertical line otherwise
        if xa_g == xb_g:
            if ya_g == yb_g:
                return [(xa_g, ya_g)]

            return [(xa_g, i) for i in range(ya_g, yb_g + y_inc, y_inc)]
        elif ya == yb: # Similar for being in the same vertical voxel
            return [(i, ya_g) for i in range(xa_g, xb_g + x_inc, x_inc)]

    # Usual case: different start and end voxels
    xbxa = xb - xa
    ybya = yb - ya

    # Evaluating horizontal increment
    x_dir = float((xbxa) // abs(xbxa))
    y_dir = float((ybya) // abs(ybya))

    # Initializing and starting loop
    xp, yp = xa, ya

    result = []
    r = 0.0
    while r <= 1.0: # Goes through the whole vector
        # Add current voxel to results
        xp_g, yp_g = xp // voxel, yp // voxel
        result.append((xp_g, yp_g))

        # Evaluate horizontal and vertical increase
        delta_rx = ((xp_g + x_dir) * voxel - xp) / xbxa
        delta_ry = ((yp_g + y_dir) * voxel - yp) / ybya

        # Choose the smaler increment
        if delta_rx < delta_ry:
            xp += delta_rx * xbxa
            yp += delta_rx * ybya
            r += delta_rx
        else:
            xp += delta_ry * xbxa
            yp += delta_ry * ybya
            r += delta_ry

    return result

Deixe um comentário