I’m trying to produce a red draggable circle with two other circles dynamically adapting their positions to create equilateral triangle. Could you please suggest a better solution than the one i paste here?
Ideally, in the final code, all the circles should be draggable.
Thanks in advance for your help.
let x1 = 400;
let y1 = 200;
let x2 = 350;
let y2 = 350;
let x3 = 200;
let y3 = 350;
let spd = 3;
function setup() {
createCanvas(800, 800);
}
function draw() {
background(0);
stroke(255);
strokeWeight(4);
let r = 20;
push();
fill('red');
circle(x1, y1, r);
pop();
push();
fill('blue');
circle(x2, y2, r);
pop();
push();
fill('green');
circle(x3, y3, r);
pop();
if (mouseIsPressed) {
var red_blue = createVector(x2 - x1, y2 - y1);
var blue_green = createVector(x2 - x3, y2 - y3);
var green_red = createVector(x3 - x1, y3 - y1);
red_blue.normalize();
blue_green.normalize();
green_red.normalize();
let d_rb = dist(x1, y1, x2, y2);
let d_bg = dist(x2, y2, x3, y3);
let d_gr = dist(x1, y1, x3, y3);
if (d_rb - d_bg > 5) {
x2 += blue_green.x * spd;
y2 += blue_green.y * spd;
x2 -= red_blue.x * spd;
y2 -= red_blue.y * spd;
} else if (d_rb - d_bg < -5){
x2 -= blue_green.x * spd;
y2 -= blue_green.y * spd;
x2 += red_blue.x * spd;
y2 += red_blue.y * spd;
}
if (d_gr - d_rb > -5) {
x3 -= green_red.x * spd;
y3 -= green_red.y * spd;
x3 -= blue_green.x * spd;
y3 -= blue_green.y * spd;
} else {
x3 += green_red.x * spd;
y3 += green_red.y * spd;
x3 += blue_green.x * spd;
y3 += blue_green.y * spd;
}
}
}
// To drag the red circle
function mouseDragged() {
x1 = mouseX;
y1 = mouseY;
}
I think that if I create a triangle then all the circles will move at the same time (right?). The effect that I’m looking for is to move the red and then the other two will run to reach the right position and stop there.
Anyway I’ll try your suggestion …
This is a really challenging problem and if I was to code this I would want to create a class to represent the ‘cicle’. Although it could be coded without the need for class it would be a real challenge and the code would be large, hard to maintain and difficult to scale up.
IIt’s made harder with this requirement -
When looking at a problem like this it is good to try and describe the system / solution algorithms in natural language so here I go. I will call them balls for clarity.
Problem statement
We have a system of 3 balls positioned at the vertices of an equilateral triangle.
When any one of the balls is dragged then the other two will move to maintain their relative positions
The 2 following balls movement will exhibit some form of inertia so arrive at the correct position some time after the dragged ball stops.
Initial thoughts
Since any ball can be dragged then there is no significant difference between balls and so we can have a single class to represent them. The only difference is in the behaviour between dragged and following balls.
Any realistic solution should be able to
handle any number of balls i.e. scalable.
any arrangement of stationary balls, not just the equilateral triangle
Possible mechanism
To simplify the discussion we will restrict ourselves to the 3 ball system. In out system we will have 4 objects, the 3 balls and a fourth which I will call the anchor which is invisible. To keep everything simple the anchor will be represented by another class which has the following attributes
position [x,y]
array of balls in the system - each ball remembers its current position on the screen
array of ball at rest positions [rx, ry] these are relative to the anchor position [x,y]
On every frame we update the balls position with the following algorithm
for every ball
if the ball is being dragged then
calculate the new position of the ball
move the anchor so the ball is at its correct rest position relative to the ball
if the ball is not being dragged then
if the ball is not at its rest position relative to the anchor then move towards it.
I would create this system in stages
Create the Ball class with the basic attributes
a vector for its current screen position
Create the Anchor class with the basic attributes - a vector its position
a vector for its current screen position
an array of balls making up the system
an array of vectors for the rest position for each ball
Add a draw method to the Ball class
Add a method to the Anchor to add a ball and its relative at rest postion
Test this by creating and displaying simple systems (different arrangements of balls)
Add a method to enable a ball to be dragged (several ways to do this)
Add the update method to the Ball class but move the following balls instantaneously to their correct position
Test the ball drag
Modify the update method to add ‘inertia’ for the following balls
Test it all out
I think you willl find this quite a challenge but it makes for a nice roadmap