Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

Given two points (vectors), plot a 3rd so all three can be bisected by a straight line

edited March 2017

Hi,

I have small issue with creating linked beziers in that the link between each bezier is not that smooth. I'm using bezierVertex to draw the connected beziers.

What I'm trying to do is smooth out this join, and from what I understand I need to do the following "In order to make two curves A and B smoothly continuous, the last control point of A, the last point of A, and the first control point of B have to be on a straight line."

So, given two vectors like so;

``````function setup() {
createCanvas(windowWidth, windowHeight);
background(255);
noLoop();

rectMode(CENTER);

var v1 = createVector(random(200, 300), random(200, 300));
var v2 = createVector(random(100, 400), random(300, 400));

ellipse(v1.x, v1.y, 20, 20);
ellipse(v2.x, v2.y, 20, 20);

var angle = p5.Vector.angleBetween(v1, v2);

ellipse( 200 * sin(angle) , 200 * cos(angle), 30, 30);
}
``````

I want to be able to plot the 3rd, so that I can set the control point of the next bezier in my in a straight line, and smooth the bezier connection point.

First time using p5. I'm converting an old Director project as a learning exercise. The Director version looks like this; https://goo.gl/photos/K6zmabEyPUgTsmYMA

Tagged:

• It would help if your example draw a curve. And then you want that curve to continue to another point? I'm confused about which points you want as endpoints and which you want as control points.

Here is a bezier curve with dragaballs to play with in the meantime.

``````class DragaBall {
int x, y, r;
color c;
boolean grabbed;
DragaBall(int _x, int _y, color _c) {
x=_x;
y=_y;
c=_c;
r = 10;
grabbed = false;
}
boolean isOver() {
return( dist( mouseX, mouseY, x, y) < r );
}
void draw() {
// Grabbed but nothing is held, release it.
if ( grabbed && !mousePressed ) {
grabbed = false;
}
// Otherwise it's where the mouse is.
if ( grabbed ) {
x = mouseX;
y = mouseY;
}
// Keep it on the grid too.
x = constrain(x, r, width-r);
y = constrain(y, r, height-r);
// Actually draw it.
fill(c);
noStroke();
ellipseMode(CENTER);
ellipse(x, y, 2*r, 2*r);
}
void mouseDown() {
if ( isOver() ) {
//// Clone balls instead by uncommenting.
//if( !grabbed ){
//   dragaballs.add( new DragaBall( x, y, c ) );
//}
grabbed = true;
}
}
}

DragaBall e0 = new DragaBall(200, 200, color(255, 0, 0));
DragaBall e1 = new DragaBall(400, 200, color(255, 0, 0));
DragaBall c0 = new DragaBall(300, 100, color(0, 255, 0));
DragaBall c1 = new DragaBall(300, 300, color(0, 0, 255));

void setup() {
size(600, 400);
strokeWeight(2);
}

void draw() {
background(0);
stroke(0,128,0);
line(e0.x, e0.y, c0.x, c0.y);
stroke(0,0,128);
line(e1.x, e1.y, c1.x, c1.y);
stroke(255);
noFill();
bezier(e0.x, e0.y, c0.x, c0.y, c1.x, c1.y, e1.x, e1.y);
e0.draw();
e1.draw();
c0.draw();
c1.draw();
}

void mousePressed() {
e0.mouseDown();
e1.mouseDown();
c0.mouseDown();
c1.mouseDown();
}
``````

(Uses Processing, not P5.js!)

• edited March 2017

Hi,

Sorry, I took out the curve drawing, as I thought that would complicate things.

Basically I'm trying to do what is mentioned here;

https://processing.org/tutorials/curves/

At the bottom of the page, an example is given for drawing two joined beziers, and then again, with a solution for an uneven join where the first bezier connects to the next in the sequence.

I have the bezier line drawing all complete, its just getting a solution to make the connection between the beziers smooth. Which is basically finding the angle between 2 points, and being able to plot a 3rd point further along that same line. As illustrated below;

• edited March 2017

Seems that lerp() with a number larger than 1 does basically what I'm after.

``````function setup() {
createCanvas(windowWidth, windowHeight);
background(255);
frameRate(30);

rectMode(CENTER);

var v1 = createVector(random(200, 300), random(200, 300));
var v2 = createVector(random(100, 400), random(300, 400));

ellipse(v1.x, v1.y, 20, 20);
ellipse(v2.x, v2.y, 20, 20);

var v3 = p5.Vector.lerp(v1, v2, 1.5);

ellipse( v3.x , v3.y, 30, 30);
}
``````
• edited March 2017

@ noponies , very interesting
Then I read your question and thought it only worked between points, so you taught me something new.
Can you also test what happens with negative values?
It seems to also lerp the other way for negative number which I hoped it would.

• Yeah, I was surprised it worked with numbers great that 1. Not in the docs.

In other words, given a line v1-v2, find a new point v3 at a scaling factor m along that line by: `v3 = v1 + m*(v2-v1)`