Transform path to follow an arc

Hello

I’m hoping for some help - I’d also really appreciate any guidance as to if this is the best way of thinking.

In my example, I have a line in the shape of a sine wave (although I’d like to apply this thinking to any points following a ‘flat’ path).

I am trying to turn this ‘linear path’ so that the same pattern follows a circular path.

I’ve tried calculating the distance from a set y-axis to the y-axis that my sine wave follows and using this distance as the radius for the curve but I have three issues:

  1. I’m not sure if this is the best way of thinking.
  2. My ‘curve’ doesn’t join
  3. My lines in the curve don’t join either (I’m not sure what I’ve done wrong by creating the x2,y2 points for my curve.

Any help / pointers would be greatly appreciated.

Thanks in advance

Becky

void setup() {
  
  size(400,500);
  background(0);
  stroke(255);

  
  for (int i = 0; i <360; i++) {   //i for each degree around the circle
  
  //calculations for initial line where line would be line(x1,y1,x2,y2)
   float angleLineStart = map(i,0,359,0,12);
   float angleLineEnd = map(i+1,1,360,0,12);
  
   float x1 = i;    
   float y1 = sin((angleLineStart))*60;

   float x2 = (i+1);
   float y2 = sin((angleLineEnd))*60;
  
  
  //calculations for circle  
    float circleAngleStart = radians(i);
    float circleAngleEnd = radians(i+1);
   
 //radius is based on the distance from -100 on the y axis and i on the x axis to translate to the new circle   
    float radiusStart = dist(x1,-100,x1,y1);
    float radiusEnd = dist(x2,-100,x2,y2);      
       
    float xCurve = 200 + (cos(circleAngleStart)*radiusStart);
    float yCurve = 200 + (sin(circleAngleStart)*radiusStart);    
       
    float xCurve2 = 200 + (cos(circleAngleEnd)*radiusEnd);
    float yCurve2 = 200 + (sin(circleAngleEnd)*radiusEnd);  
    
    line(xCurve,yCurve,xCurve2,yCurve2);

    
  }
  
}
1 Like

It was a bit hard to follow the code so I just rewrote a quick sketch to try to simulate what you wanted. In essence I just drew a circle and modulated the radius. You can play around with the calc_radius to get the effect you want. I haven’t learned tweak mode yet, but I guess this is a perfect use case for it.

void setup() {
  
  size(400,500);
  background(0);
  stroke(255);
}

void draw()
{
  float radius = 100.f;
  int center_x = width/2;
  int center_y = height/2;
  float step = 2 * PI / 360;
  
  for (float i = 0; i < 2 * PI; i += step) {
  float x0, y0, x1, y1;
  x0 = calc_radius(radius, i) * sin(i);
  y0 = calc_radius(radius, i) * cos(i);
  x1 = calc_radius(radius, i+step) * sin(i+step);
  y1 = calc_radius(radius, i+step) * cos(i+step);
  
    line(x0 + center_x, y0 + center_y, x1 + center_x, y1 + center_y);
    
  }
  
}

float calc_radius(float base, float rad){
  return 20 * sin(rad * 4.0f) + base;
}
1 Like

Thank you for replying - this does work and I’m going to go through it properly to make sure I understand (more so that I can replicate this for other lines - not just the line following a sine curve).

If you don’t mind (and have time) would you mind telling me if this is the right thinking - it doesn’t seem to work but I was trying to replicate what I thought your code was doing in my own way (i.e. using the shape of the line to calculate the radius and applying this radius to the curve calculation.

Thanks in advance and also for you help with the above.

Becky

void setup() {
  
  size(400,500);
  background(0);
  
  float factor = 20;
  float translationX = 130;
  float translationY = 130; 
  
  stroke(255);
  
  translate(0,200);
  
  
  //create a series of points
   for (int i = 0; i <360; i++) {
   float angle = radians(i);
   float y = sin(angle)*factor;
   float x = i;    
   
   point(x,y); //the line I want to transform into a circle
   point(x,50);  //the 'baseline' I'm using to calculate my radius for the circle
   
   //now wrap these points around a circle
   //all points are evenly spaced so the only calculation we need is the radius.
   //the radius is the distance between a point and the current y.
   
   float radius = dist(x,y,x,50);
   
   float xCircle = translationX+(cos(angle)*radius);
   float yCircle = translationY+(sin(angle)*radius);
   
   point(xCircle,yCircle);
   
   println(xCircle,yCircle, radius);
       
    
  }
  
}
1 Like

I have a bit of a hard time understanding your original question.

What are your initial points?
What is a “flat path”?

Can you draw this original “linear” path first before you apply your transformation?

Could you provide a screenshot of what you mean with that?

Please rephrase your challenge as it will be easier to answer.

If I word what you are trying to do, you want to do a vectorial addition of your initial linear path with a sinusoidal path which will result in a curve path. And you want this path to join at the end.

Probably this post relates to your effort? Wave displaced circle

image

I have modified your initial code to make it dynamic. You can move your mouse along the x and y. Along the x, it adjust the amplitude of the sine wave. Along the Y, it adjust the steps to draw the curve. I use the blue color to draw your base line for the wave, red and green to plot your referential wave and yellow to be your initial line (?). This is the output:

image

Kf

3 Likes

I think you are on the right track. You just can’t see it very well due to the fact that your y is pretty plain. Try changing the line:

float y = sin(angle)*factor;

to

float y = sin(2*angle)*factor;

You will have what you are looking for. Also, the graph will only connect the start and end depending on if the modulation of the radius and y has the same phase.

@kfrajer has a much better example in the link that he posted.

1 Like

Thanks so much for your time and help with this - I see it now - that’s really helpful.

Thanks again

Becky

Hello,

Thank you for your help with this - I struggled explaining what I wanted to do but you answered it perfectly - that really helps to see with the interaction.

Thanks

Becky