Spool
Spool

Reputation: 77

How to get the "edges" of a single dimensional array

Explanation

I'm generating textures for UI elements that have a single pixel outline on the edge of the texture.

The method of setting the color data in the texture is limited to passing a one dimensional array of color values.

These textures are 2D, so they are basically rectangles. I need to be able to identify when the current pixel is at an edge. This is how I currently do it:

Color[] colorData = new Color[width * height];
        for (int p = 0; p < colorData.Length; p++) {

            //Top
            if (p < width - 1) {

                colorData[p] = DefaultOutlineColor;
            }    
            //Left
            else if(p % width == 0) {
                colorData[p] = DefaultOutlineColor;
            }
            //Right
            else if(p % height == height - outlineWidth) {
                colorData[p] = DefaultOutlineColor;
            }
            //Bottom
            else if(p >= width * (height - outlineWidth)) {
                colorData[p] = DefaultOutlineColor;
            }
            //Fill
            else {
                colorData[p] = DefaultBaseColor;
            }
        }

The Problem

Some Modulo math and what not. The problem I am having is with the Right side of the Texture. More specifically calculating the right side edge. A picture is worth a thousand words:

UI Texture

I know it is just a miss calculation in the Right edge part. But I have no idea how to make it work. Any help would be highly appreciated.

EDIT: Figured it out. Here is the working code:

        //Fill
        for (int p = 0; p < colorData.Length; p++) {

            colorData[p] = DefaultBaseColor;
        }

        //Top
        for (int p = 0; width * outlineWidth > p; p++) {

            colorData[p] = DefaultOutlineColor;
        }

        //Left and Right
        for (int p = 1; height > p; p++) {

            for (int i = 0; i < outlineWidth; i++) {

                colorData[(p * width) + i] = DefaultOutlineColor; //Left
                colorData[((p * width) - i) - 1] = DefaultOutlineColor; //Right
            }

        }

        //Bottom
        for (int p = width * height - (width * outlineWidth); colorData.Length > p; p++) {

           colorData[p] = DefaultOutlineColor;
        }

Upvotes: 2

Views: 104

Answers (3)

Matt Rollins
Matt Rollins

Reputation: 91

In practice you're doing a one-pixel border - but you use outlineWidth in your original code, so here's an alternative method that works fine for arbitrary border sizes.

for (int p = 0; p < colorData.length; p++) {
    // retrieving the x/y coords isn't expensive if you do this only once
    int x = p % height;
    int y = p / height;

    if (x < outlineSize || y < outlineSize || x >= width - outlineSize || y >= height - outlineSize) {
        colorData[p] = DefaultOutlineColor;
    }
}

Upvotes: 0

SoronelHaetir
SoronelHaetir

Reputation: 15172

Why not do it in three loops? One for the top, one for the left and right and then one for the bottom? That way you can skip all the items that don't need to be touched at all.

for(int ndx = 0; Width > ndx; ++ndx)
{
  colorData[ndx] = DefaultOutlineColor;
}

for(int ndx = 1; Height > ndx; ++ndx)
{
  colorDatandx * Widthp] = DefaultOutlineColor;
  colorData[ndx*Width + Width] = DefaultOutlineColor;}
}

for(int ndx = Width * Height - Width; Length > ndx; ++ndx)
{
  colorDatandxp] = DefaultOutlineColor;
}

Upvotes: 2

Spool
Spool

Reputation: 77

Using SoronelHaetir's method I figured it out. Had to edit the math a little bit. Here is the working code if anyone is interested:

        for (int ndx = 0; width > ndx; ndx++) {
            colorData[ndx] = DefaultOutlineColor;
        }
        for (int ndx = 1; height > ndx ; ndx++) {
            colorData[ndx * width] = DefaultOutlineColor;
            colorData[(ndx * width) - 1] = DefaultOutlineColor;
        }
        for (int ndx = width * height - width; colorData.Length > ndx; ndx++) {
            colorData[ndx] = DefaultOutlineColor;
        }

Upvotes: 1

Related Questions