We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › connecting rectangles with arrows
Pages: 1 2 
connecting rectangles with arrows (Read 5093 times)
connecting rectangles with arrows
Mar 29th, 2010, 7:26pm
 
I am using Processing to generate some technical diagrams.  Currently my related rectangles are connected with a line from the center of each rectangle.  However, for the diagram to be meaningful, I really need that line to be an arrow.  The rectangles can (and do) vary in size and can be dragged around the screen.  

Any thoughts on how to connect them such that the arrow head can move along the outside of the rectangle as it is dragged to a different position?  I've been trying to get my head around the geometry involved (and failing).

Many thanks!
Re: connecting rectangles with arrows
Reply #1 - Mar 30th, 2010, 12:20am
 
Can your rectangles rotate? Do you want the arrow to connect the edge of one rectangle to the edge of the other rectangle?

Wow, this is a lot harder than I thought!
Re: connecting rectangles with arrows
Reply #2 - Mar 30th, 2010, 12:58am
 
Do the arrow-heads scale or should they be fixed in size? Do they have to rotate freely or just in 90degree steps? If the arrow-heads are fixed size & 90deg only, you might want to define the shape of the arrow head in a function which takes the "center" of the head has input and then simply draws the head. You can then call this "arrow head" function for each "ending" of the line in your code.
If the arrow-heads need to scale/rotate arbitrarily, you migth want to define such a function using PVectors instead.
Re: connecting rectangles with arrows
Reply #3 - Mar 30th, 2010, 3:31am
 
something like this ?

void draw() {
 background(204);
 strokeWeight(2);
 float a = atan2(mouseY-height/2, mouseX-width/2);
 line(width/2,height/2,mouseX,mouseY);
 translate(mouseX,mouseY);
 rotate(a-HALF_PI);
 triangle( -5, -10, 0, 0, +5,-10);
 }
Re: connecting rectangles with arrows
Reply #4 - Mar 30th, 2010, 3:28pm
 
Many thanks for all the help.  I got something working in a test sketch so now I'll try and integrate it with the larger program.  Here's the final code for those who are interested.  

BTW: The program treats the rectangle more like an ellipse for the purposes of drawing the arrows (it goes inside the rectangle at the corners) but I'll still call this a win (and it works perfectly for circles).  If anyone has any improvements, please let me know.

float x = random(50, 200);
float y = random(50, 300);
float w = random(50, 100);
float h = random(50, 100);

void setup() {
 size(600, 600);
 smooth();
}

void draw() {
 background(255);
 noStroke();
 fill(200, 200);
 rectMode(CORNER);
 rect(x - w/2, y - h/2, w, h);
 rect(mouseX - w/2, mouseY - h/2, w, h);
 float a = atan2(mouseY-y, mouseX-x);
 stroke(1);
 line(x + cos(a) * (w/2), y + sin(a) * (h/2), mouseX - cos(a) * (w/2), mouseY - sin(a) * (h/2));

 translate(mouseX - cos(a) * (w/2), mouseY - sin(a) * (h/2));
 rotate(a-HALF_PI);
 fill(0);
 triangle(-5, -10, 0, 0, 5, -10);
}
Re: connecting rectangles with arrows
Reply #5 - Mar 30th, 2010, 4:06pm
 
hmm but you want something more like this ?



void setup(){
size(300,300);
}

void draw() {
background(204);
strokeWeight(2);
float a = atan2(mouseY-height/2, mouseX-width/2);
line(width/2,height/2,mouseX,mouseY);
pushMatrix();
translate(mouseX,mouseY);
rotate(a-HALF_PI);
triangle( -5, -10, 0, 0, +5,-10);
popMatrix();
rect(mouseX,mouseY,50,50);
}
Re: connecting rectangles with arrows
Reply #6 - Mar 30th, 2010, 4:58pm
 
Cool sketch, but I don't want the arrow tied to a specific corner.  I need to be able to move around all the edges of the rectangle.  What I came up with does that, but the arrowhead moves into the rectangle on the corners because w/2 and h/2 aren't long enough, but I can't think of a simple way to expand them.
Re: connecting rectangles with arrows
Reply #7 - Mar 30th, 2010, 7:56pm
 
I got it. Modify this to suit your needs.

Quote:
// Code provided AS-IS!

float recW = 160;
float recH = 100;

void setup(){
 size(400,400);
}

void draw(){
 background(0);
 // Center space.
 translate(width/2.0, height/2.0);
 // Draw rectangle.
 fill(200,0,0,128);
 noStroke();
 float hW = recW/2.0;
 float hH = recH/2.0;
 rect(-hW,-hH,recW,recH);
 float mx = mouseX-width/2.0;
 float my = mouseY-width/2.0;
 // Get the angle the line makes with horizontal.
 float angle = atan2( my, mx );
 // Get the angle the corners make
 float TR = atan2(  hH,  hW );
 float TL = atan2(  hH, -hW );
 float BL = atan2( -hH, -hW );
 float BR = atan2( -hH,  hW );
 float x=0, y=0; // The location of the desired point.
 if( angle >= BR && angle < TR ){
   x = hW;
   y = x * my / mx;
 } else if( angle >= TR && angle < TL ){
   y = hH;
   x = y * mx / my;
 } else if( angle >= TL || angle < BL ){ // THIS OR IS NOT A TYPO!
   x = -hW;
   y = x * my / mx;
 } else if( angle >= BL && angle < BR ){
   y = -hH;
   x = y * mx / my ;
 }
 strokeWeight(2);
 stroke(255,255,0);
 line(x, y, mx, my);
}


Cool
Re: connecting rectangles with arrows
Reply #8 - Mar 31st, 2010, 1:34am
 
hmm yeah, but couldnt this be simple done, by drawing the rect over the arrow ?
like this ?


Code:
void draw() {
background(204);
strokeWeight(2);
pushMatrix();
float a = atan2(mouseY-height/2, mouseX-width/2);
line(width/2,height/2,mouseX,mouseY);
translate(mouseX,mouseY);
rotate(a-HALF_PI);
triangle( -5, -10, 0, 0, +5,-10);
fill(255);
popMatrix();
rectMode(CENTER);
rect(50,50,30,30);

}
Re: connecting rectangles with arrows
Reply #9 - Mar 31st, 2010, 1:37am
 
but your code is really cool, if you add the gap, that he probably wanted...

Code:

float recW = 160;
float recH = 100;

void setup(){
size(400,400);
}

void draw(){
background(255);
// Center space.
translate(width/2.0, height/2.0);
// Draw rectangle.

fill(255);
stroke(0);
float hW = recW/2.0;
float hH = recH/2.0;
rect(-hW+10,-hH+10,recW-20,recH-20);
float mx = mouseX-width/2.0;
float my = mouseY-width/2.0;
// Get the angle the line makes with horizontal.
float angle = atan2( my, mx );
// Get the angle the corners make
float TR = atan2( hH, hW );
float TL = atan2( hH, -hW );
float BL = atan2( -hH, -hW );
float BR = atan2( -hH, hW );
float x=0, y=0; // The location of the desired point.
if( angle >= BR && angle < TR ){
x = hW;
y = x * my / mx;
} else if( angle >= TR && angle < TL ){
y = hH;
x = y * mx / my;
} else if( angle >= TL || angle < BL ){ // THIS OR IS NOT A TYPO!
x = -hW;
y = x * my / mx;
} else if( angle >= BL && angle < BR ){
y = -hH;
x = y * mx / my ;
}
strokeWeight(2);
stroke(0);
line(x, y, mx, my);
}
Re: connecting rectangles with arrows
Reply #10 - Mar 31st, 2010, 12:35pm
 
@Cedric @TfGuy44
Wow.  Thanks.  That last post looks exactly like what I had in mind.  

Not to impose further, but I have been trying to make the code work for a connection between 2 rectangles (like the code I posted earlier), but I cannot get the rectangles and arrow to line up (it seems to be tied into centering a single rectangle in the screen).  

Do you have any suggestions?  And many thanks for the time and effort you've put in.  
Re: connecting rectangles with arrows
Reply #11 - Mar 31st, 2010, 7:02pm
 
I have a suggestion, and it was the same as the last time I gave it: "Modify this to suit your needs."
Wink
Re: connecting rectangles with arrows
Reply #12 - Mar 31st, 2010, 11:07pm
 
hehe Wink right
Re: connecting rectangles with arrows
Reply #13 - Apr 1st, 2010, 2:25am
 
Actually I do have another suggestion, but it's going to sound crazy.
Find the midpoint of the line connecting the two rectangles, and use that, instead of the center of the other rectangle, to find the point to start/end your arrow at. Then do this again for the other rectangle.
Re: connecting rectangles with arrows
Reply #14 - Apr 2nd, 2010, 6:57am
 
@TFGuy44  Interesting.  I'll have to think about that.  Many thanks.
Pages: 1 2