Jordan Savant # Software Engineer

Vector Math Functions

Get Random Vector

sf::Vector2f bit::VectorMath::getRandomVector()
{
    float r = (float)std::rand()/(float)RAND_MAX;
    float angle = (r * bit::Math::TwoPi);
    return sf::Vector2f(std::cos(angle), std::sin(angle));
}

Normalize

sf::Vector2f bit::VectorMath::normalize(sf::Vector2f &vector)
{
    if(vector.x != 0 || vector.y != 0)
    {
        float length = std::sqrt((vector.x * vector.x) + (vector.y * vector.y));
        return sf::Vector2f(vector.x / length, vector.y / length);
    }
    return vector;
}
sf::Vector2f bit::VectorMath::normalize(float x, float y)
{
    if(x != 0 || y != 0)
    {
        float length = std::sqrt((x * x) + (y * y));
        return sf::Vector2f(x / length, y / length);
    }
    return sf::Vector2f(0, 0);
}

Distance

float bit::VectorMath::distance(float x1, float y1, float x2, float y2)
{
    float x = (x1 - x2);
    float y = (y1 - y2);
    return std::sqrt(x*x  + y*y);
}

Direction Vector

sf::Vector2f bit::VectorMath::directionToVector(float x1, float y1, float x2, float y2)
{
    return bit::VectorMath::normalize(x2 - x1, y2 - y1);
}

Rotation To Vector

float bit::VectorMath::rotationToVector(float x1, float y1, float x2, float y2)
{
    return std::atan2(y1 - y2, x1 - x2);
}

To Radians

float bit::VectorMath::toRadians(sf::Vector2f v)
{
    v = normalize(v.x, v.y);
    return std::atan2(v.y, v.x);
}

Radians To Vector

sf::Vector2f bit::VectorMath::radiansToVector(float radians)
{
    return sf::Vector2f(std::cos(radians), std::sin(radians));
}

Average

sf::Vector2f bit::VectorMath::average(std::vector<sf::Vector2f> &vectors)
{
    if(vectors.size() == 0)
        return sf::Vector2f(0, 0);

    sf::Vector2f average(0, 0);
    for(unsigned int i=0; i < vectors.size(); i++)
    {
        average.x += vectors[i].x;
        average.y += vectors[i].y;
    }
    average.x /= vectors.size();
    average.y /= vectors.size();

    return average;
}

Rotate

void bit::VectorMath::rotate(sf::Vector2f &point, float radians)
{
    float cosRadians = std::cos(radians);
    float sinRadians = std::sin(radians);

    point.x = point.x * cosRadians - point.y * sinRadians;
    point.y = point.x * sinRadians - point.y * cosRadians;
}

void bit::VectorMath::rotateAroundPivot(sf::Vector2f &point, float radians, sf::Vector2f &pivot)
{
    float cosRadians = std::cos(radians);
    float sinRadians = std::sin(radians);

    sf::Vector2f translatedPoint;
    translatedPoint.x = point.x - pivot.x;
    translatedPoint.y = point.y - pivot.y;

    point.x = translatedPoint.x * cosRadians - translatedPoint.y * sinRadians + pivot.x;
    point.y = translatedPoint.x * sinRadians + translatedPoint.y * cosRadians + pivot.y;
}

Lerp

sf::Vector2f bit::VectorMath::lerp(float x1, float y1, float x2, float y2, float ratio)
{
    return sf::Vector2f((x1 + ratio * (x2 - x1)), (y1 + ratio * (y2 - y1)));
}

Increment Towards

void bit::VectorMath::incrementTowards(float &x1, float &y1, float x2, float y2, float xAmount, float yAmount)
{
    float tx = x2 - x1;
    float ty = y2 - y1;
    float dist = std::sqrt(tx*tx + ty*ty);

    float velX = (tx / dist)*xAmount;
    float velY = (ty / dist)*yAmount;

    if (dist > xAmount) {
        // add our velocities
        x1 += velX;
        y1 += velY;
    }
    else {
        x1 = x2;
        y1 = y2;
    }

    return;
}

Function Towards

void bit::VectorMath::functionTowards(float &x1, float &y1, float x2, float y2, float xAmount, float yAmount)
{
    x1 += (x2 - x1) / xAmount;
    y1 += (y2 - y1) / yAmount;
    return;
}

Smoothstep

function smoothstep (min, max, value) {
  var x = Math.max(0, Math.min(1, (value-min)/(max-min)));
  return x*x*(3 - 2*x);
};

Apply Dead Zone

void bit::VectorMath::applyDeadZone(sf::Vector2f* v, float deadZone)
{
    if(deadZone > 0)
    {
        if((v->x > 0 && v->x < deadZone) || (v->x < 0 && v->x > -deadZone))
        {
            v->x = 0;
        }
        if((v->y > 0 && v->y < deadZone) || (v->y < 0 && v->y > -deadZone))
        {
            v->y = 0;
        }
    }
}

Bresenham Line

std::vector<sf::Vector2i> bit::VectorMath::bresenhamLine(int x1, int y1, int const x2, int const y2)
{
    std::vector<sf::Vector2i> result;

    int delta_x(x2 - x1);
    // if x1 == x2, then it does not matter what we set here
    signed char const ix((delta_x > 0) - (delta_x < 0));
    delta_x = std::abs(delta_x) << 1;

    int delta_y(y2 - y1);
    // if y1 == y2, then it does not matter what we set here
    signed char const iy((delta_y > 0) - (delta_y < 0));
    delta_y = std::abs(delta_y) << 1;

    //plot(x1, y1);
    result.push_back(sf::Vector2i(x1, y1));

    if (delta_x >= delta_y)
    {
        // error may go below zero
        int error(delta_y - (delta_x >> 1));

        while (x1 != x2)
        {
            if ((error >= 0) && (error || (ix > 0)))
            {
                error -= delta_x;
                y1 += iy;
            }
            // else do nothing

            error += delta_y;
            x1 += ix;

            //plot(x1, y1);
            result.push_back(sf::Vector2i(x1, y1));
        }
    }
    else
    {
        // error may go below zero
        int error(delta_x - (delta_y >> 1));

        while (y1 != y2)
        {
            if ((error >= 0) && (error || (iy > 0)))
            {
                error -= delta_y;
                x1 += ix;
            }
            // else do nothing

            error += delta_x;
            y1 += iy;

            //plot(x1, y1);
            result.push_back(sf::Vector2i(x1, y1));
        }
    }

    return result;
}

In Radius

bool bit::VectorMath::inRadius(float x, float y, float radiusX, float radiusY, float radius)
{
    return distance(x, y, radiusX, radiusY) <= radius;
}

Normal to Isometric

sf::Vector2f bit::VectorMath::normalToIsometric(float x, float y)
{
    return sf::Vector2f(x - y, (x + y) / 2);
}

Isometric to Normal

sf::Vector2f bit::VectorMath::isometricToNormal(float x, float y)
{
    return sf::Vector2f((2 * y + x) / 2, (2 * y - x) / 2);
}