How can I turn an image in PNG or SVG format into a ring shape?

I want to use processing to complete the following effect, which is to copy a picture and deform it to make it ring.But I don’t know how to turn the image into a fan shape.


The general method of operation should be as follows
1. Import PNG images
2. Turn the image into a fan shape (here I thought of using polar coordinates)
3. Use rotate() to combine into a ring
Or the second method
1. Import SVG images
2. Make the SVG vertex into a fan shape
3.rotate()
I think the key is how to turn the picture into a fan shape, so is there a way to get it done?

Here I create an image, and use it as a texture to draw 12 trapezoids using that texture. But if you draw more, smaller trapezoids , you can get it to look more like a ring.

PImage img;

void setup() {
  size(400, 400, P3D);
  background(255);
  noStroke();
  fill(200, 0, 0);
  rect(0, 0, 100, 50);
  fill(0, 200, 0);
  rect(200, 50, 100, 50);
  img = get(0, 0, 300, 100);
}

void draw() {
  background(0);
  translate(200, 200);

  for ( int t = 0; t < 12; t++) {
    beginShape();
    texture(img);
    vertex(100*cos(0), 100*sin(0), img.width, img.height);
    vertex(100*cos(-PI/6.0), 100*sin(-PI/6.0), 0, img.height);
    vertex(120*cos(-PI/6.0), 120*sin(-PI/6.0), 0, 0);
    vertex(120*cos(0), 120*sin(0), img.width, 0);
    endShape(CLOSE);
    rotate(-PI/6.0);
  }
  
  scale(.5);
  image(img, -150, -50);
}

Using the image you posted above I created an image of a vertical man and used that in the example sketch below. You can see this image inside the ring in the screen shot.

Rather than use a single shape (e.g. trapezoid) for the ring segment I have created a curved ring by considering the rectangular image (vertical man) as a number of horizontal slices then mapped these to the matching position in the ring.

Here is the output from my sketch using 11 ring segments and each segment made from 10 slices of the man image

and here is the sketch code

PImage img;
// Change this to suit :-)
int nbrRingSegments = 11;

void setup() {
  size(600, 600, P2D);
  img = loadImage("man.png");
}

void draw() {
  background(200, 200, 250);
  translate(width/2, height/2);
  float segAngle = TWO_PI / nbrRingSegments;
  pushMatrix();
  for (int s = 0; s < nbrRingSegments; s++) {
    rotate(segAngle);
    drawRingSegment(img, 240, 50, segAngle, 10);
  }
  popMatrix();
  image(img, -img.width/2, -img.height/2);
}

void drawRingSegment(PImage img, float radius, float ringWidth, float angle, int nbrSlices) {
  float deltaAngle = angle / (nbrSlices - 1);
  float deltaV = 1.0 / (nbrSlices - 1);
  noStroke();
  beginShape(TRIANGLE_STRIP);
  texture(img);
  textureMode(NORMAL);
  for (int i = 0; i < nbrSlices; i++) {
    float x0 = radius * cos(i * deltaAngle);
    float y0 = radius * sin(i * deltaAngle);
    float x1 = (radius + ringWidth) * cos(i * deltaAngle);
    float y1 = (radius + ringWidth) * sin(i * deltaAngle);
    float v = i * deltaV;
    vertex(x0, y0, 0, v);
    vertex(x1, y1, 1, v);
  }
  endShape();
}

void keyTyped() {
  if (key == 's')
    save("manring.png");
}

This is a very good idea. I studied texture() and Vertex(), and then I tried to add vertex(), bezierVertex(), curveVertex(), quadraticVertex() between Vertex() and found the image Distorted directly LOL
However, random() may be used in my code, there may be 12 repeats, there may be two or even 3, 5, and 7, so I am still looking for a more suitable method.
thank you very much, though

Looking at the final result, I think it should be what I want to achieve, but for me as a beginner, I still don’t understand some of the codes. It may take an hour or two to study it. Thank you very much:)

If you comment out the noStroke() statement you will see the triangles used to render the segment.

I now understand how this works, and then I can adjust the size of the triangles to make it rounder

The last parameter 10 is the number of slices simply increase this number until you get the smoothness you want e.g.
drawRingSegment(img, 240, 50, segAngle, 30);

Just looked at the output - looks like a circle to me LOL

I have tried it. When nbrRingSegments is greater than 4, it looks like a circle, so I will try to maximize the last parametert.
You help me a lot, thank you very much:)

If there are nbrRingSegments and each segment is split into nbrSlices then the entire ring consists of
nbrRingSegments * nbrSlices pie sections.

So if you reduce nbrRingSegments then you must increase nbrSlices if you want the ring to appear circular.

So I can change last parameter 10 into 100/nbrRingSegments it will be looks always like a ring LOL

1 Like