How to calculate the Xmin,Xmax,Ymin,Ymax of an object?

Asked

Viewed 494 times

1

I’m playing a simple game like "space Invaders" in Opengl and in the part of the collisions need to calculate the minimum and maximum X and Y values, but I still can’t figure out how to do this.

This is the code I use to create an enemy ship:

void Inimiga::Corpo(void){
    glColor3f(0.545, 0.000, 0.000);

    glScalef(1.0,0.5,0.0);
    glBegin(GL_QUADS);{
        glVertex2f(0.0,0.0);
        glVertex2f(0.8,0.0);
        glVertex2f(0.8,0.25);
        glVertex2f(0.0,0.25);
    }
    glEnd();
}

void Inimiga::asaDireita(void){

    glColor3f(0.545, 0.000, 0.000);
    glScalef(0.5,1.0,0.0);

    glBegin(GL_TRIANGLES);{
        glVertex2f(0.0,0.0);
        glVertex2f(2.0,1.0);
        glVertex2f(0.0,2.0);
    }
    glEnd();
}

void Inimiga::asaEsquerda(void){

    glColor3f(0.545, 0.000, 0.000);

    glScalef(0.5,1.0,0.0);
    glBegin(GL_TRIANGLES);{
        glVertex2f(0.0,1.0);
        glVertex2f(2.0,0.0);
        glVertex2f(2.0,2.0);
    }
    glEnd();
}
  • 1

    I added the tag [tag:c++] since your code seems to be from this language. In the future, when preparing such an issue, provide a [mcve] instead of just snippets of code. It can make it easier for you to get a better answer or faster.

2 answers

2


You just iterate over the vertices and save the smallest/largest comparing to each new observed vertex. But for this you will need to keep the vertices in a list/vector (today you only draw them).

Here’s an example of code:

#include <iostream>
#include <vector>
#include <limits>

using namespace std;

// Define um tipo genérico para um ponto 2D
class Ponto2D
{
public:
    float x;
    float y;

    Ponto2D(float x = 0, float y = 0)
    {
        this->x = x;
        this->y = y;
    }
};

int main() {

    // Cria o vetor com todos os pontos do seu objeto
    vector<Ponto2D> pontos;

    // Adiciona os pontos do corpo
    pontos.push_back(Ponto2D(0.0, 0.0));
    pontos.push_back(Ponto2D(0.8, 0.0));
    pontos.push_back(Ponto2D(0.8, 0.25));
    pontos.push_back(Ponto2D(0.0, 0.25));

    // Adiciona os pontos da asa direita
    pontos.push_back(Ponto2D(0.0, 0.0));
    pontos.push_back(Ponto2D(2.0, 1.0));
    pontos.push_back(Ponto2D(0.0, 2.0));

    // Adiciona os pontos da asa esquerda
    pontos.push_back(Ponto2D(0.0, 1.0));
    pontos.push_back(Ponto2D(2.0, 0.0));
    pontos.push_back(Ponto2D(2.0, 2.0));

    // Calcula o bounding box para a colisão
    float xmin, xmax, ymin, ymax;

    xmin = ymin = numeric_limits<float>::max();
    xmax = ymax = numeric_limits<float>::min();

    for(auto &ponto : pontos)
    {
        if(ponto.x < xmin)
            xmin = ponto.x;
        if(ponto.x > xmax)
            xmax = ponto.x;
        if(ponto.y < ymin)
            ymin = ponto.y;
        if(ponto.y > ymax)
            ymax = ponto.y;
    }

    cout << "xmin: " << xmin << " xmax: " << xmax << endl;
    cout << "ymin: " << ymin << " ymax: " << ymax << endl;

    return 0;
}

You can see running in Ideone.

If you prefer, you can build a class that represents the bounding box of its object and make a method addVertex that adds the point and already updating the minimum and maximum values. Then just call this method next to the moment you add the vertex to render.

1

The standard library from C++11 has the algorithms "min_element", "max_element" and "minmax_element" that work with element sequences.

Below is an example of how to use.

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

struct Point
{
   int x;
   int y;
   bool operator<(const Point& other)
   {
      return (x < other.x) || ((x == other.x) && (y < other.y));
   }
};

ostream& operator<<(ostream& o, const Point& p)
{
   o << '{' << p.x << ',' << p.y << '}';
   return o;
}

int main()
{
   // minmax de inteiros
   vector<int> v { 3, 9, 1, 4, 2, 5, 9 };
   auto r1 = minmax_element(v.begin(), v.end());
   cout << "min element: " << *r1.first  << '\n';
   cout << "max element: " << *r1.second << '\n';

   // minmax de classes
   vector<Point> p { {3, 4}, {14, 0}, {1, 4}, { 2, 7}, {5, 4}, {9, 11} };
   auto r2 = minmax_element(p.begin(), p.end());
   cout << "min element: " << *r2.first  << '\n';
   cout << "max element: " << *r2.second << '\n';
}

References:
http://en.cppreference.com/w/cpp/algorithm/min_element
http://en.cppreference.com/w/cpp/algorithm/max_element
http://en.cppreference.com/w/cpp/algorithm/minmax_element

  • Well remembered. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.