# Twisted quads vs. Expressive quads

**URL:** https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292
**Category:** Coding Questions
**Created:** [September 16, 2021, 9:47pm UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292 "2021-09-16T21:47:25Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![humano](https://avatars.discourse-cdn.com/v4/letter/h/dbc845/32.png) [@humano](https://discourse.processing.org/u/humano)
#### Post date: [September 16, 2021, 9:47pm UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292/1 "2021-09-16T21:47:25Z")

</div>

Hi there!

These days i have been working with quads and some Users have gave me different solutions for my problems.

One of my biggest problems is that some of my random quads are twisted. With new ways of drawing quads learned this week that is solved, but I lose the expressivity of these shapes.

Fixing number 1 and number 2 I don’t get any more shapes as number 3 and number 4, and it is Big Lost for a designer. How could I avoid twisted quads without losing these dynamic quads?

Thank you so much for your help!

 ![IMG_20210916_173042](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/1ded4f3e90afded64e472f62f6bfdd5778bef7f5.jpeg)

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [September 17, 2021, 9:11am UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292/2 "2021-09-17T09:11:53Z")

</div>

I have not seen your previous posts so I don’t know what solutions have been provided so there might be some duplication here.

**Twisted Quads**  
When drawing a quad we have to provide the coordinates for the 4 vertices. For a human that would be enough but for a computer we must specify the order they should be processed. Traditionally the approach is to start with one vertex and then order them by tracing the shape anticlockwise. In this picture we use the same coordinates for the vertices but change the order they are processed.  
 ![quad_vertex_order](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/598f7f845ed548e4b62e1ba0b6e8a1f95a06a3a1.png)  
The wrong order can cause two sides to intersect creating a twisted quad.

**Convex vs concave polygons**  
In your picture you call shapes 3 and 4 expressive / dynamic quads but the correct description is ‘concave polygons’. A quad is simply a 4 sided polygon and what I say applies to any polygon of 4 or more sides.  
This picture shows a convex polygon on the left and a concave polygon on the right.  
 ![quad_convex_concave](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/8/8c84f790d5a2aea7f52f1c195b7b232c95a99b6b.png)  
A polygon is concave if at least one internal angle is greater than 180 degrees and is convex if all internal angles are less than 180 degrees.  
Now how the convex polygon is drawn depends on the renderer, for instance the above picture was drawn using Java2D (default option in Processing) whilst the following picture uses OpenGL (P2D mode in Processing), notice the difference.  
 ![quad_convex_concave](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/dc75e32cfad1e0757cdca0c7894916b089231e38.png)  
I don’t know if there is a setting in OpenGL to change its behaviour but I have provided the sketch code below for you to play with.

Another way to render concave polygons is to split it into triangles and render them instead. I use this approach in the Shapes3D library but the code is fairly complex.

```auto
// Convex versus concave quads
// Drawing with OpenGL and Java2D
PVector[] convex = {
  new PVector(30, 30), 
  new PVector(60, 280), 
  new PVector(250, 270), 
  new PVector(220, 60)
};
PVector[] concave = {
  new PVector(30, 30), 
  new PVector(160, 280), 
  new PVector(250, 90), 
  new PVector(140, 200)
};

void setup() {
  size(600, 300, P2D);
  textSize(24);
  background(255);
  fill(255, 255, 0);
  stroke(128, 128, 0);
  strokeWeight(2);
  drawQuad(convex);
  translate(width/2, 0);
  drawQuad(concave);
  save("quad_convex_concave.png");
}

void drawQuad(PVector[] v) {
  beginShape(QUADS);
  fill(255, 255, 0);
  for (int i = 0; i < 4; i++) {
    vertex(v[i].x, v[i].y);
  }
  endShape(CLOSE);
}

```

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [September 17, 2021, 6:33pm UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292/3 "2021-09-17T18:33:18Z")

</div>

As discussed in your previous post

> [@Polygons Distribution with loops](https://discourse.processing.org/t/polygons-distribution-with-loops/32270/6):
>
> Let’s save the coordinates of a little square: float[] coords = new float[] { -10, -10, // x1, y1 10, -10, // x2, y2 10, 10, // x3, y2 -10, 10 // y4, y4 }; Think of it like a metal mold or template for pouring a little rubber stamp. We can make the stamp and use it all at once by passing the coordinates to [beginShape()](https://processing.org/reference/beginShape_.html) or beginShape(QUADS). Here is a stamp method to do that: void stamp(float[] coords) { beginShape(); for(int i=0; i\<coords.length; i+=2) { // read two numbers e…

there are multiple ways to add randomness to a set of points that are not twisted. If you are growing out in four quadrant directions, you won’t give you every possible random quad – but it has a lot of variation, but concave shapes will be quite rare.

One way to get more frequent and “expressive” concave shapes is to do random points (or a random walk of points) and test for line-line intersection to detect invalid crossings.

---

<div class="post-metadata">

### Author: ![rapatski](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/rapatski/32/5164_2.png) [@rapatski](https://discourse.processing.org/u/rapatski)
#### Post date: [September 17, 2021, 7:21pm UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292/4 "2021-09-17T19:21:40Z")

</div>

I see what you’re after. Setting the minSize to 0 and using this adapted version of the method we showed you in the other thread, where here the angle is increased randomly again, like @jb4x initially did for you gets an effect that’s pretty close I think?

```auto
void drawMoreRandomQuad(float x, float y, float minSize, float maxSize) 
{  
  float startAngle = random(HALF_PI); // random start angle for each quad
  float angle = startAngle;
  
  beginShape();
  for (int i = 0; i < 4; i++) {
    // imagine that we're going round a circle, stopping at 4 points along the circle
    float r = random(minSize, maxSize); // choose a different distance from the centre for each point
    float vx = x + r * cos(angle); // look up trigonometry on wikipedia
    float vy = y + r * sin(angle);
    vertex(vx, vy);
    
    // increment angle with a random amount
    angle += random(0, min(startAngle + TWO_PI - angle, PI));
  }
  endShape(CLOSE);
}

```

---

<div class="post-metadata">

### Author: ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)
#### Post date: [September 18, 2021, 8:02am UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292/5 "2021-09-18T08:02:25Z")

</div>

Consider the following image:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/35ca25b3abe2d916f4391fc940d542d15d992f3f.png)

It represents all the possible order/configuration your points can have (minus edge cases with colinear points).

Based on this you can check the following intersection:

- [1, 2] and [3, 4]  
They intersect in cases C and D  
Swap points 2 and 3 to untwist the quad
- [1, 4] and [2, 3]  
They intersect in cases B and F  
Swap points 1 and 2 to untwist the quad

For segment/segment intersection, you can have a look [here](https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/).

I let you figure out how to deal with the edge cases.

---

<div class="post-metadata">

### Author: ![rapatski](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/rapatski/32/5164_2.png) [@rapatski](https://discourse.processing.org/u/rapatski)
#### Post date: [September 18, 2021, 9:25am UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292/6 "2021-09-18T09:25:19Z")

</div>

Again, you’ve made three topics around the same subject. It’s better to keep related questions in one thread, rather than make different ones where people are answering very similar things.

> [@Multiple polygons with a loop](https://discourse.processing.org/t/multiple-polygons-with-a-loop/32260/5):
>
> I have seen that some of this quads are twisted, do you know how could I avoid It? I can’t imagine the way to do that easily

> [@Polygons Distribution with loops](https://discourse.processing.org/t/polygons-distribution-with-loops/32270/4):
>
> @jb4x that’s quite the pro approach. I’ve added below two other ways you achieve a similar result, one a slightly simpler version of the one jb4x proposed. I’m not a fan of the “quad” method… it’s awkward having to put 8 arguments into it… @humano look up “beginShape()” in the Processing reference? int numObjects = 100; void setup() { size(500, 500); } void draw() { background(255); noStroke(); // draw red 'quads' using the random rect method for(int i = 0; i \< numObjects…

---

<div class="post-metadata">

### Author: ![humano](https://avatars.discourse-cdn.com/v4/letter/h/dbc845/32.png) [@humano](https://discourse.processing.org/u/humano)
#### Post date: [September 20, 2021, 9:28pm UTC](https://discourse.processing.org/t/twisted-quads-vs-expressive-quads/32292/7 "2021-09-20T21:28:10Z")

</div>

Sorry, some questions were appearing while i was trying different ways, but I will try to do It better Next time
