Problem in PShape? QUAD_STRIP?

edited September 2016 in Questions about Code

this code is cut down from a bigger example so it's probably a bit verbose.

it creates a bunch of coordinates and puts them in a pvector list.

it then uses this list to define the top (POLYGON) and then the sides (QUAD STRIP) of a cylinder using pshapes. it then puts both these child pshapes into a GROUP pshape.

and it looks fine in 3.0b7 but after upgrading to 3.1.1 there are extra lines in the image.

// bug?

String WIRE_COLOUR = "ff00ff00";
int SEGMENTS = 12;
int BUTTON_RADIUS = 25;
int TOP = 25;
PShape shape1, shape2;

void setup() {
  size(600, 600, P3D);
  shape1 = createKey(-50, 0);
  shape2 = createKey(50, 0);
}

PShape createKey(float x, float y) {
  ArrayList<PVector> points = new ArrayList();

  for (int i = 0; i < 24; i++) {
    float angle = i * TWO_PI / SEGMENTS;
    points.add(new PVector(x + BUTTON_RADIUS * cos(angle), y + BUTTON_RADIUS * sin(angle)));
  }

  // top
  PShape top = createShape();
  top.beginShape(POLYGON);
  top.noFill();
  top.stroke(255, 0, 0);
  top.strokeWeight(10);
  for (PVector p : points) {
    top.vertex(p.x, p.y, TOP);
  }
  // close circle
  top.vertex(points.get(0).x, points.get(0).y, TOP);
  top.endShape();

  // sides
  PShape sides = createShape();
  sides.beginShape(QUAD_STRIP);
  sides.noFill();
  sides.stroke(unhex(WIRE_COLOUR));
  sides.strokeWeight(2);
  for (PVector p : points) {
    sides.vertex(p.x, p.y, 0);
    sides.vertex(p.x, p.y, TOP);
  }
  // close strip
  sides.vertex(points.get(0).x, points.get(0).y, 0);
  sides.vertex(points.get(0).x, points.get(0).y, TOP);
  sides.endShape();

  // add children to shape
  PShape shape = createShape(GROUP);
  shape.addChild(top);
  shape.addChild(sides);
  return shape;
}

void draw() {
  background(0);
  camera(100, 200, 100, 0, 0, 0, 0, 1, 0);
  scale(2);
  shape(shape1);
  shape(shape2);
  noLoop();
  save("buttons.png");
}    

it looks like the last point of every quad in a quad strip is being connected to the first point. will investigate.

i guess my question is 'am i doing something wrong?' or 'anybody else seen this?'

3.0b7

buttons_30b7

3.1.1

buttons_311

Tagged:

Answers

  • if i comment out line 53 then the lines go away.

    if i swap lines 53 and 54 the lines go away.

  • edited September 2016

    Did you ever report this as a bug, and if so did you hear anything back?

    Ran into a version of this recently, Processing 3.2.1 on OS X 10.10.5 -- think I figured it out.

    I think you are right that there is a bug in QUAD_SHAPE. This was driving me nuts so I created a test sketch that uses the beginShape sample data for a QUAD_SHAPE to confirm. Detailed explanation in code comments.

    Drag the mouse around to view the extra lines.

    /**
     * QUAD_STRIP extra lines bug
     * Processing 3.2.1
     * 2016-09-07 Jeremy Douglass
     * forum.processing.org/two/discussion/17876/0/
     * 
     * When child QUAD_STRIPs are added to a PShape, even closed shapes,
     * sets extra lines are rendered from child as follows
     * 
     * -  Three extra lines the same color as background
     *    are drawn from first child vertex 1,3,5...n-3 to origin (0,0,0)
     * -  Three extra lines are drawn from second child vertex 1,3,5...n-3
     *    to first child vertex n-3. These lines are gradient from
     *    child2 color to child1 color, and from child2 stroke to 0.
     * -  Three extra lines are drawn from third child to second child...
     * -  Three extra lines are drawn from fourth child to third child... etc.
     *
     * The extra lines are always rendered, but are most visible when
     * each child shape is separate and nothing is overdrawing (e.g. noFill).
     */
    
    PShape group;
    PShape red;
    PShape green;
    PShape blue;
    
    int translatex = 0;
    int translatey = 0;
    
    color RED = color(255,0,0,255);
    color GREEN = color(0,255,0,255);
    color BLUE = color(0,0,255,255);
    color GREYA = color(255,255,255,16);
    
    void setup() {
      size(400, 400, P3D); 
      group = createShape(GROUP);
      red   = makeChild(GREYA,RED,80);
      green = makeChild(GREYA,GREEN,40);
      blue  = makeChild(GREYA,BLUE,0);
      group.addChild(red);
      group.addChild(green);
      group.addChild(blue);
    }
    
    void draw(){
      background(0);
      camera(100, 50, 200, 0, 0, 0, 0, 1, 0);
      text("0,0,0",0,0,0);
      shape(group,-translatex, -translatey);
      stroke(255);
    }
    
    PShape makeChild(color fill_, color stroke_, float offset_){
      PShape shape_ = createShape();
      shape_.beginShape(QUAD_STRIP);
      shape_.stroke(stroke_);
      shape_.strokeWeight(5);
      shape_.noFill();
      //// example quad data copied from https://processing.org/reference/beginShape_.html
      shape_.vertex(30, 10, offset_); /// v1 - line from here to previous child v5
      shape_.vertex(30, 75, offset_); 
      shape_.vertex(50, 20, offset_); /// v3 - line from here to previous child v5
      shape_.vertex(50, 75, offset_);
      shape_.vertex(65, 10, offset_); /// v5 - line from here to previous child v5
      shape_.vertex(65, 75, offset_); 
      shape_.vertex(85, 20, offset_);
      shape_.vertex(85, 75, offset_);
      shape_.endShape(CLOSE);
      return shape_;
    }
    
    /* *** INTERFACE *** */
    
    void mouseDragged(){
      // translate(60 * mouseX/width, 60 * mouseY/height);
      translatex = 30 - 60 * mouseX/width;
      translatey = 30 - 60 * mouseY/height;
      updateShapes();
    }
    void updateShapes(){
      group.removeChild(2);
      group.removeChild(1);
      group.removeChild(0);
      group.addChild( makeChild(GREYA,RED,80 + translatex) );
      group.addChild( makeChild(GREYA,GREEN,40) );
      group.addChild( makeChild(GREYA,BLUE,0 - translatex) );
    }
    
  • edited September 2016

    Also koogs, if you are glutton for debugging punishment, here is remixed version of your sample sketch with the line error in full glory. Press +/- to cycle segments down to 2, drag the mouse to get a good angle on the inter-child and first-child-to-origin buggy line drawing.

    /**
     * forum.processing.org/two/discussion/17876/0/#Form_Comment
     */
    PShape shape;
    int segments;
    int translatex = 0;
    int translatey = 0;
    String text = "0,0,0";
    
    void setup() {
      size(400, 400, P3D);
      segments = 20;
      shape = createKey(0, 0, segments);
    }
    
    void draw() {
      background(0);
      camera(100, 200, 150, 0, 0, 0, 0, 1, 0);
      scale(2);
      text(text,0,0,0);
      shape(shape, translatex, translatey);
    }
    
    PShape createKey(float x, float y, int segments_) {
      int BUTTON_RADIUS = 25;
      ArrayList<PVector> points = new ArrayList();
      for (int i = 0; i < segments_*2; i++) {
        float angle = i * TWO_PI / segments_;
        points.add(new PVector(x + BUTTON_RADIUS * cos(angle), y + BUTTON_RADIUS * sin(angle)));
      }
      PShape red   = createChild(points, color(255,0,0), 9,  40 + translatey);
      PShape green = createChild(points, color(0,255,0), 7,   0);
      PShape blue  = createChild(points, color(0,0,255), 5, -40 - translatey);
    
      // add children to shape
      PShape s = createShape(GROUP);
      s.addChild(red);
      s.addChild(green);
      s.addChild(blue);
      return s;
    }
    
    PShape createChild(ArrayList<PVector> points_, color color_, int weight_, int translate_){
      PShape shape_ = createShape();
      shape_.beginShape(QUAD_STRIP);
      shape_.translate(0,0,translate_);
      shape_.noFill();
      shape_.stroke(color_);
      shape_.strokeWeight(weight_);
      for (PVector p : points_) {
        shape_.vertex(p.x, p.y, 0);
        shape_.vertex(p.x, p.y, 25);
      }
      shape_.endShape(CLOSE);
      return shape_;
    }
    
    /* *** INTERFACE *** */
    
    void keyPressed(){
      switch(key){
        case '_':
        case '-':
          segments = max(2, segments-1);
          drawShape();
          break;
        case '=':
        case '+':
          segments = segments+1;
          drawShape();
          break;
        case ' ':
          if(segments == 2){ segments = 20; }
          else { segments = 2; }
          drawShape();
          break;
      }
    }
    
    void mouseDragged(){
      // translate(60 * mouseX/width, 60 * mouseY/height);
      translatex = 30 - 60 * mouseX/width;
      translatey = 30 - 60 * mouseY/height;
      drawShape();
    }
    
    void drawShape(){
      shape = createKey(0, 0, segments);
      redraw();
    }
    
  • @koogs -- the bug in quad edge closing code was found and this was resolved.

    It was a single change to addQuadStripEdges() -- a true that should have been false.

  • Cool, thanks.

Sign In or Register to comment.