# Fill colors not blending on triangle strip object

In order to draw multiple rows of triangle strips (for terrain), either they need to be looped, in which case it glitches by drawing a line from the end of one row to the beginning of the next, or begin shape needs to be in front of every row, and each row is not blended together, creating lines in the fill color. How can I get the whole plane to shade smoothly?

yes, i think you try it all in one loop,

do not connect the end of the STRIP
to the beginning of the next STRIP

make a loop for one strip only
( actually 2 point plus loop over triangles )
and do that again for the next strip ( with a offset )

OR
use a array of triangles
( each made by 3 points (PVector) )
as a object (class), where each can have a different colorâ€¦

example sorry 2D only / just for the idea
``````// mouse inside triangle question
// 2D only!
//  copy from https://stackoverflow.com/a/13301035
// https://discourse.processing.org/t/background-of-triangular-objects/5857/4
// v1    3 test point
// v2    class of 3 pvector and color, pvector array of lines
// v3    master fill color editor: click PI and press key [f],[F],[Alt][f] and mouse scroll
// v4    edit small things

// lwide 22 is 22 point as 20 triangles
int lwide=22, plong = 10*lwide;    // line and point array length           now 200 triangles
PVector[] p = new PVector[plong];  // point array
PVector pm;                        // mouse
boolean showstroke = true, shownum = false, cedit = false, dbug = false;

int i = 0;   // point counter
int j = 0;   // triangle counter

int sw = 440, sh = sw;            // screen pix
int x0 = 10, y0 = 10, xw = 40, yw = 40;
color ct, cm;                    // init color // master color start default

Tri[] my_triangles = new Tri[plong];

void settings() {
//  fullScreen();
size(sw, sh);
}
//_________________________________________________
void make_array() {
int l = 0;
while ( i < plong ) {
p[i] = new PVector(x0+xw*(0), y0+yw*(i%2)+yw*l );
if (dbug) println("i: "+i+" j "+j+" "+p[i]);
i++;
p[i] = new PVector(x0+xw*(0), y0+yw*(i%2)+yw*l );
if (dbug) println("i: "+i+" j "+j+" "+p[i]);
i++;
for ( int k = 1; k < lwide/2; k++) {
p[i] = new PVector(x0+xw*(k), y0+yw*(i%2)+yw*l );
if (dbug) println("i: "+i+" j "+j+" "+p[i]);
my_triangles[j] = new Tri(p[i-2], p[i-1], p[i], ct, j);
i++;
j++;

p[i] = new PVector(x0+xw*(k), y0+yw*(i%2)+yw*l );
if (dbug) println("i: "+i+" j "+j+" "+p[i]);
my_triangles[j] = new Tri(p[i-2], p[i-1], p[i], ct, j);
i++;
j++;
}
l++;
}
}

//_________________________________________________
void setup() {
colorMode(RGB, 100, 100, 100);
ct = color(100, 100, 0);    // init color
cm = color(100, 0, 0);      // master color start default
make_array();
println("mouse click: left SET, right UNSET ");
println(" key[r] RESET all / key [n] show number / key [s] show stroke");
}

//_________________________________________________
void draw() {
background(0, 80, 0);
for (int i = 0; i < j; i++)   my_triangles[i].show();
do_the_PI();
}

//_________________________________________________
class Tri {
PVector p1, p2, p3;
PVector pm = new PVector(0, 0);
color cf;
int j;
Tri(PVector p1, PVector p2, PVector p3, color cf, int j) {
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
this.cf = cf;
this.j  = j;
}

public void show() {
pm.x = mouseX;
pm.y = mouseY;
if ( over_t(pm) ) stroke(200, 0, 0);
else        if ( showstroke ) stroke(0, 0, 200);
else noStroke();
fill(cf);
//    triangle(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
beginShape();
vertex(p1.x, p1.y);
vertex(p2.x, p2.y);
vertex(p3.x, p3.y);
endShape(CLOSE);
if (shownum) {
fill(0);
text(j+1, p1.x+20*(j%2), p1.y+10-10*(j%2));
}

cset();
creset();
}

private void cset() {
pm.x = mouseX;
pm.y = mouseY;
if ( mousePressed && mouseButton == LEFT && over_t(pm) ) cf = cm;
}

private void creset() {
pm.x = mouseX;
pm.y = mouseY;
if ( mousePressed && mouseButton == RIGHT && over_t(pm) ) cf = ct;
}

public void cdefault() {
cf = ct;
}

private boolean over_t(PVector pm) {
float alpha = ((p2.y - p3.y)*(pm.x - p3.x) + (p3.x - p2.x)*(pm.y - p3.y)) /
((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
float beta = ((p3.y - p1.y)*(pm.x - p3.x) + (p1.x - p3.x)*(pm.y - p3.y)) /
((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
float gamma = 1.0 - alpha - beta;
if ( gamma > 0 && alpha > 0 && beta > 0 ) return true;
return false;
}
}

// add secret PI function
int rposX =sw-25, rposY=sh-25, rwide=24;
boolean altKey = false, ctrlKey = false, shiftKey = false;
boolean mousePresent = false;
int   e_fillR=100, e_fillG=0, e_fillB=0;

void do_the_PI() {
if ( cedit ) {
if ( over(mouseX, mouseY) ) {
stroke(0, 0, 0);
fill(0);
text("use [f],[F],[Alt][f] for fill color= ("+e_fillR+" , "+e_fillG+" , "+e_fillB+" ) ( RGB 0 .. 100 )", rposX-320, rposY+20);
} else noStroke();
fill(cm);
rect( rposX, rposY, rwide, rwide );
} else {
fill(0);
text("Ď€", rposX+5, rposY+10);
}
}

boolean over(int mx, int my) {
if ((mx > (rposX)) & (mx < (rposX+ rwide))) {
if ((my > (rposY))  & (my < (rposY+ rwide))) {
return true;
}
}
return false;
}

void mouseExited() {
mousePresent = false;
}
void mouseEntered() {
if (focused) mousePresent = true;
}

void mousePressed() {
if ( over(mouseX, mouseY) ) {
cedit = !cedit;
if ( cedit )  println("+++ fill color editor function");
if ( cedit )  println("+++ use key [f] (Red), [F] (Green), [Alt][f] (Blue) and scroll mousewheel");
}
}

void mouseWheel(MouseEvent event) {
float e = event.getCount();
if ( cedit && over(mouseX, mouseY) ) {
if ( keyPressed && key == 'f' && !altKey ) {
e_fillR += 2*e;
e_fillR = constrain(e_fillR, 0, 100);
cm = color(e_fillR, e_fillG, e_fillB);
}          // [f] fill hue color
if ( keyPressed && key == 'F' ) {
e_fillG += 2*e;
e_fillG = constrain(e_fillG, 0, 100);
cm = color(e_fillR, e_fillG, e_fillB);
}          // [F]  ([Shift][f] or [Capslock][f]) fill saturation
if ( keyPressed && key == 'f' && altKey ) {
e_fillB += 2*e;
e_fillB = constrain(e_fillB, 0, 100);
cm = color(e_fillR, e_fillG, e_fillB);
}          // [Alt][f] fill brt
}
}

//_______________________________________________ Code KEY set
void keyPressed () {
if (key == CODED) {
if      (keyCode == ALT)     altKey   = true;
else if (keyCode == SHIFT)   shiftKey = true;
else if (keyCode == CONTROL) ctrlKey  = true;
}
if ( key == 'r' ) {
for (int i = 0; i < j; i++)  my_triangles[i].cdefault();
}
if ( key == 'n' ) {
shownum = !shownum;
}
if ( key == 's' ) {
showstroke = !showstroke;
}
}
//_______________________________________________ Code KEY unset
void keyReleased() {
if ((keyCode >= '0' && keyCode <= '9') || // digit
(keyCode >= 'A' && keyCode <= 'Z') || // upper-case letter
(keyCode >= 'a' && keyCode <= 'z')) { // lower-case letter
if (altKey) {
//println("ALT " + char (keyCode)+" "+keyCode);
altKey = false;
} else if (ctrlKey) {
//println("CTRL " + char (keyCode)+" "+keyCode);
ctrlKey = false;
} else if (shiftKey) {
//println("SHIFT " + char (keyCode)+" "+keyCode);
shiftKey = false;
} //else println("KEY = "+ key+" "+keyCode);
}
}

``````

Yeah, this is what I did originally, however each strip is a new shading group, creating lines down the model making everything look striped. Even if all the stripes were the same color, there were still stripes visible if the model isnâ€™t flat.

use a array of triangles
( each made by 3 points (PVector) )

This is a good idea, however that seems like it will just make non-blended facets in individual triangles instead of strips. That might still be better than striped objects, but still not the smoothed surface I was going for.

In 3D modeling this is kind of like â€śsmoothing groups,â€ť when vertices arenâ€™t connected they are different smoothing groups. I need all the faces to be in the same smoothing group.

1 Like

What is your goal for the color? is it a 1D or 2D gradient? Small sample code would be helpful.

Depending on your goals, you could output the mesh boustrophedon style â€“ like plowing a field, or mowing a lawn.

``````// beginShape
int row = 0;
while(row < rowcount-1) {
for(int col=0; col<colcount; col++){
// draw row L-R
}
row=row+1;
for(int col=0; col<colcount; col++){
// draw row R-L
}
row=row+1;
}
// endShape
``````