Circle to Line Interpolation


#1

I’ve been trying to achieve an effect like the one that is achieved here., I’ve mostly been able to get it to work, but there’s this strange offset that I’m not really sure why it’s there. Here’s the code I’ve written so far.

vec3 v;
vec3 p0 {1,0,0}, p1 {-1, 0, 0};

TOGGLE(DBG);
SLIDER(pox);
SLIDER(p1x);
SLIDER(bend_factor, 0.001…1);
SLIDER(pivot);

vec3 gen(float t){

p0.x = pox;
p1.x = p1x;

float lineLength = abs(p0.x - p1.x);
float radius = (lineLength / (bend_factor * two_pi) );

float arcLength = (bend_factor * two_pi);

vec3 circCenter = { p0.x + (lineLength * pivot), p0.y + radius, 0};

float adjust = (1-bend_factor) * half_pi;
float angle = (pi + adjust) + arcLength * tri( 2 * t);

v.x = radius * cos(angle) + circCenter.x;
v.y = radius * sin(angle) + circCenter.y;

if(t < 0.5) return v;
else return blend((t*2), {pox, -0.1,0}, {p1x, -0.1,0});
}


#2

hey!

sorry, don’t really have time to dive into your code.

maybe this helps:

if you can generate 3 points, you can use these equations to derive the center and radius of the circle:
http://ambrsoft.com/TrigoCalc/Circle3D.htm


#3

Hi!
Reviving the topic here.
I gave it a take following closer the code of the link you posted. Here is my implementation:

PHASOR(bend_factor, 0.001…1);
PHASOR(pivot);
SLIDER(p1x, -1..1);
SLIDER(p1y, -1..1);
SLIDER(p2x, -1..1);
SLIDER(p2y, -1..1);



vec3 lerp(vec3 p1, vec3 p2, float t) {
	return p1 + (p2-p1) * t;
}

vec3 getPosOnBentLine(vec3 lineStart, vec3 lineEnd, float t, float bendFactor, float pivot) {
	if (bendFactor == 0) bendFactor = 0.00001;
	vec3 segmentVector = lineEnd - lineStart;
	float lineLength = (segmentVector).length();
	float circleRad = lineLength / (bendFactor * 2 * PI);
	vec3 circleCenter = lerp(lineStart, lineEnd, pivot) + vec3(-segmentVector.y, segmentVector.x, 0) * circleRad / lineLength;

	float angle = bendFactor * (1.0 - (t+pivot)) * 2 * PI - atan2(segmentVector.x, segmentVector.y);
	vec3 posOnCircle = circleCenter + vec3(cos(angle), sin(angle), 0) * circleRad;
	return posOnCircle;
}

int state = 0;

vec3 gen(float t){
	vec3 startPoint = vec3(p1x, p1y, 0);
	vec3 endPoint = vec3(p2x, p2y, 0);
;
	if (state == 0) return(getPosOnBentLine(startPoint, endPoint, tri(t), bend_factor, pivot));
	else return lerp(startPoint, endPoint, tri(t));
 }


int duration = 30000;
int counter = 0;

void update() {
	if (duration == 0) duration = 1;
	
	counter++;
	counter %= duration;
	state = (counter > duration/2) ? 0 : 1;
}

#4

pretty cool!

only note i have is that the “state” change is currently dependent on the sample rate of your audio interface.

to get reliable timing you can do this instead:

    // state will loop at 1x the current bpm
	state = mod1(globals().time)<0.5;

   // state will loop at 0.5x the bpm
	state = mod1(globals().time/2)<0.5;

   // state will loop at 2x the bpm
	state = mod1(globals().time*2)<0.5;