问题
I have code for a double pendulum that traces the second pendulums centre with a line by using the previous position of the pendulum. I need to add a function that when the mouse is clicked (on or not on the pendulum, it doesnt matter), the pendulum can be dragged around the screen within the boundaries of the pendulum, im not sure if mouse dragged() would work or if i should use a class for the pendulum to make it easier
float r1 = 200;
float r2 = 200;
float m1 = 40;
float m2 = 40;
float a1 = PI/2;
float a2 = PI/2;
float a1_v = 0;
float a2_v = 0;
float g = 1;
float px2 = -1;
float py2 = -1;
float cx, cy;
PGraphics canvas;
void setup() {
size(900, 600);
cx = width/2;
cy = 200;
canvas = createGraphics(width, height);
canvas.beginDraw();
canvas.background(255);
canvas.endDraw();
}
void draw() {
background(255);
imageMode(CORNER);
image(canvas, 0, 0, width, height);
float num1 = -g * (2 * m1 + m2) * sin(a1);
float num2 = -m2 * g * sin(a1-2*a2);
float num3 = -2*sin(a1-a2)*m2;
float num4 = a2_v*a2_v*r2+a1_v*a1_v*r1*cos(a1-a2);
float den = r1 * (2*m1+m2-m2*cos(2*a1-2*a2));
float a1_a = (num1 + num2 + num3*num4) / den;
num1 = 2 * sin(a1-a2);
num2 = (a1_v*a1_v*r1*(m1+m2));
num3 = g * (m1 + m2) * cos(a1);
num4 = a2_v*a2_v*r2*m2*cos(a1-a2);
den = r2 * (2*m1+m2-m2*cos(2*a1-2*a2));
float a2_a = (num1*(num2+num3+num4)) / den;
translate(cx, cy);
stroke(0);
strokeWeight(2);
float x1 = r1 * sin(a1);
float y1 = r1 * cos(a1);
float x2 = x1 + r2 * sin(a2);
float y2 = y1 + r2 * cos(a2);
line(0, 0, x1, y1);
fill(0);
ellipse(x1, y1, m1, m1);
line(x1, y1, x2, y2);
fill(0);
ellipse(x2, y2, m2, m2);
a1_v += a1_a;
a2_v += a2_a;
a1 += a1_v;
a2 += a2_v;
// a1_v *= 0.99;
// a2_v *= 0.99;
canvas.beginDraw();
//canvas.background(0, 1);
canvas.translate(cx, cy);
canvas.stroke(0);
if (frameCount > 1) {
canvas.line(px2, py2, x2, y2);
}
canvas.endDraw();
px2 = x2;
py2 = y2;
}
回答1:
You're on the right track: cx
and cy
are the coordinates of the system's origin.
Simply update those to the mouse coordinates in the mouseDragged()
callback:
void mouseDragged(){
cx = mouseX;
cy = mouseY;
}
To address your question as clarified in the comments, one quick and dirty option is to simply override x2,y2 with mouse coordinates (offsetting by the cx,cy
system origin position):
float x2 = 0;
float y2 = 0;
if(mousePressed){
x2 = mouseX - cx;
y2 = mouseY - cy;
}else{
x2 = x1 + r2 * sin(a2);
y2 = y1 + r2 * cos(a2);
}
here's a full code listing with the above applied:
float r1 = 200;
float r2 = 200;
float m1 = 40;
float m2 = 40;
float a1 = PI/2;
float a2 = PI/2;
float a1_v = 0;
float a2_v = 0;
float g = 1;
float px2 = -1;
float py2 = -1;
float cx, cy;
PGraphics canvas;
void setup() {
size(900, 600);
cx = width/2;
cy = 200;
canvas = createGraphics(width, height);
canvas.beginDraw();
canvas.background(255);
canvas.endDraw();
}
void draw() {
background(255);
imageMode(CORNER);
image(canvas, 0, 0, width, height);
float num1 = -g * (2 * m1 + m2) * sin(a1);
float num2 = -m2 * g * sin(a1-2*a2);
float num3 = -2*sin(a1-a2)*m2;
float num4 = a2_v*a2_v*r2+a1_v*a1_v*r1*cos(a1-a2);
float den = r1 * (2*m1+m2-m2*cos(2*a1-2*a2));
float a1_a = (num1 + num2 + num3*num4) / den;
num1 = 2 * sin(a1-a2);
num2 = (a1_v*a1_v*r1*(m1+m2));
num3 = g * (m1 + m2) * cos(a1);
num4 = a2_v*a2_v*r2*m2*cos(a1-a2);
den = r2 * (2*m1+m2-m2*cos(2*a1-2*a2));
float a2_a = (num1*(num2+num3+num4)) / den;
translate(cx, cy);
stroke(0);
strokeWeight(2);
float x1 = r1 * sin(a1);
float y1 = r1 * cos(a1);
float x2 = 0;
float y2 = 0;
if(mousePressed){
x2 = mouseX - cx;
y2 = mouseY - cy;
}else{
x2 = x1 + r2 * sin(a2);
y2 = y1 + r2 * cos(a2);
}
line(0, 0, x1, y1);
fill(0);
ellipse(x1, y1, m1, m1);
line(x1, y1, x2, y2);
fill(0);
ellipse(x2, y2, m2, m2);
a1_v += a1_a;
a2_v += a2_a;
a1 += a1_v;
a2 += a2_v;
// a1_v *= 0.99;
// a2_v *= 0.99;
canvas.beginDraw();
//canvas.background(0, 1);
canvas.translate(cx, cy);
canvas.stroke(0);
if (frameCount > 1) {
canvas.line(px2, py2, x2, y2);
}
canvas.endDraw();
px2 = x2;
py2 = y2;
}
Bare in mind this will simply allow you to drag the second ball visually, completely ignoring the simulation. When you release the mouse the simulation will resume. If you do want to affect the simulation from bottom to top you will need to workout the math (lines 32-44 in your case).
来源:https://stackoverflow.com/questions/54183903/how-to-add-mouse-drag-function-to-double-pendulum