Home > Blockchain >  Getting the centers of all triangles in a bound isometric grid
Getting the centers of all triangles in a bound isometric grid

Time:01-14

I have a geometry problem:

Consider the following isometric grid where the center is (0, 0) and a side of a triangle are of length one unit:

enter image description here

How can I get the coordinate of all the individual triangles, including the ones that are not complete?

I tried simply dividing the width and height by different factors, but I cannot seem to find a formula that always encompasses partial triangles.

CodePudding user response:

One way to do it:

  1. The coordinates of the center of a triangle is simply the average of it's three vertices.

  2. Since the grid is vertically aligned, you can find the missing vertices of partial triangles in the vertical directions (up and down) by simply adding/subtracting s the length of a side of the triangles to the Y-axis.

  3. Because these are equilateral triangles, you can find the missing vertices of the partial triangles with 2 visible vertices in the horizontal directions (left and right) by adding/subtracting (√3/2)s to the X-axis of one of the existing vertices and setting the Y-axis value to the average of the Y values of the two existing vertices. You can find the missing vertices of partial triangles that have only one visible vertex in the horizontal directions by getting them from thier adjacent horizontal triangles with two visible vertices.

  4. Partial corner triangles (only one vertex) can be extended as follows: first get the vertically-missing vertex by applying rule (2) above. Second, now that you know two vertices, you can get the horizontally-missing vertex by applying rule (3) above.

Note that this is not the only way to do it, no even necessarily the easiest way.

CodePudding user response:

I see it like this:

hex grid

Yellow are points on grid and Aqua are individual triangles of the grid. So define basis vectors u,v,w and then just transform grid point position (i,j) into (x,y). That can be used to form triangles using triangle index parity of each index (4 possible cases)... Here small C /OpenGL 2D example:

//---------------------------------------------------------------------------
void get_hexpoint(double *p,int i,int j)    // i,j yellow
    {
    static const double deg=M_PI/180.0; // deg -> rad
    static const double u[2]={ cos(30.0*deg),-sin(30.0*deg)};
    static const double v[2]={ cos(30.0*deg), sin(30.0*deg)};
    static const double w[2]={      0.0     ,      1.0     };
    double ii=i,jj=j;
    for (i=0;i<2;i  ) p[i]=0.0;
    for (i=0;i<2;i  ) p[i] =(ii*u[i]) (jj*w[i]);
    }
//---------------------------------------------------------------------------
void get_hextriangle(double *p0,double *p1,double *p2,int i,int j)  // i,j aqua
    {
    if (int(j&1)==0)
        {
        j=(j>>1) (i>>1);
        if (int(i&1)==0)
            {
            get_hexpoint(p0,i,j);
            get_hexpoint(p1,i 1,j);
            get_hexpoint(p2,i 1,j 1);
            }
        else{
            get_hexpoint(p0,i,j);
            get_hexpoint(p1,i,j 1);
            get_hexpoint(p2,i 1,j 1);
            }
        }
    else{
        j=(j>>1) (i>>1);
        if (int(i&1)==0)
            {
            get_hexpoint(p0,i,j);
            get_hexpoint(p1,i 1,j 1);
            get_hexpoint(p2,i,j 1);
            }
        else{
            j  ;
            get_hexpoint(p0,i,j);
            get_hexpoint(p1,i 1,j);
            get_hexpoint(p2,i 1,j 1);
            }
        }
    }
//---------------------------------------------------------------------------
void TMain::draw()
    {
    scr.cls();

    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glScalef(0.2,0.2,1.0);

    int i,j,n=10;
    double p0[2],p1[2],p2[2];

    glLineWidth(3);
    for (i=-n;i<= n;i  )
     for (j=-n;j<= n;j  )
        {
        get_hextriangle(p0,p1,p2,i,j);
        glColor3f(0.2,0.2,0.2);
        glBegin(GL_TRIANGLES);
        glVertex2dv(p0);
        glVertex2dv(p1);
        glVertex2dv(p2);
        glEnd();
        glColor3f(1.0,1.0,1.0);
        glBegin(GL_LINE_LOOP);
        glVertex2dv(p0);
        glVertex2dv(p1);
        glVertex2dv(p2);
        glEnd();
        }
    glLineWidth(1);

    scr.exe();
    scr.rfs();
    }
//---------------------------------------------------------------------------

And here the output:

output

Note that the 4 cases branches might be converted to brunch-less code by changing the logic a bit moving the if statements to point index deltas or by using LUTs... but I am too lazy to do that.

  •  Tags:  
  • Related