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 & HelpSyntax Questions › how o make a shape follow a curved path
Pages: 1 2 
how o make a shape follow a curved path? (Read 1528 times)
how o make a shape follow a curved path?
Oct 24th, 2008, 1:44am
 
I have been learning the Processing today and in 2hours I made this:

boolean going = false;

// Location of moving circle to start with (stationary)
int circleX = 300;  
int circleY = 241;  

//size of page
void setup() {  
 size(600,600);  
 smooth();
}  

//background colour
void draw() {  
 background(255);  
 smooth();

 // Disc
fill(255);
ellipse(300,250,160,30);  

// Divider
stroke(0);
line(300,250,300,0);
line(300,300,300,600);

// little dot
fill(0);
ellipse(300,250,3,3);
 
 // Moving circle shape size and colour details
 stroke(0);  
 fill(122, 222, 33);  
 ellipse(circleX,circleY,22,6);  
 
 // Only move the circle when "going" is true
 if (going) {
   //speed of movement
   circleX = circleX - 4;
 }
}  

// Set going to true when the mouse is pressed!
void mousePressed() {  
 going = true;
}


Which I'm really happy about, its supposed to look like this:

http://flickr.com/photos/8-8/2962150678/sizes/o/


The disc in the middle is supposed to rotate on mouseover (I have it as a click event at the moment as I don't know how to do mouseover, mouseX ? am I along the right lines?) and the program icon would rotate on the disc from behind to the front, to be clicked on and downloaded.

What I would like to do is make that green shape follow a path around the disc, but I can only find tutorials to make it go in a strait line. I did find a tutorial that had a wavy line but I didn't get it and I need it to follow basically just a semicircle path from behind to the front and stay put.


Can somebody please hep thanks.
Re: how o make a shape follow a curved path?
Reply #1 - Oct 25th, 2008, 6:39pm
 
I got something correct with following code:
Code:
boolean going = false;

// I like to use variables, make easier to change / adapt
int centerX = 300;
int centerY = 250;

// Location of moving circle to start with (stationary)
int circleX = centerX;  
int circleY = centerY - 9;

int diskW = 160;
int diskH = 30;
float pos = 0;

//size of page
void setup() {  
 size(600, 600);  
 smooth();
}  

//background colour
void draw() {  
 background(255);  
 smooth();

 // Disc
fill(255);
ellipse(centerX, centerY, 160, 30);  

// Divider
stroke(0);
line(centerX, centerY, centerX, 0);
line(centerX, centerY + 50, centerX, height);

// little dot
fill(0);
ellipse(centerX, centerY, 3, 3);
 
 // Moving circle shape size and colour details
 stroke(0);  
 fill(122, 222, 33);  
 ellipse(circleX, circleY, 22, 6);  
 
 // Only move the circle when "going" is true
 if (going) {
   //speed of movement
   pos += 0.1; // Change value to modify speed
   circleX = int(centerX + 0.5 * diskW * sin(pos));
   circleY = int(centerY + 0.5 * diskH * cos(pos));
 }
}  

// Set going to true when the mouse is pressed!
void mousePressed() {  
 going = true;
}
Re: how o make a shape follow a curved path?
Reply #2 - Oct 26th, 2008, 3:02am
 
Wow, thanks very much, above and beyond. I played with the code you left to get it to move how I want. But, I only want it to move 180deg and stop at the front - so imagine a web surfer sees the apparatus and naturally using the mouse as their eyes they move over it, the green circle then moves from behind and round to the foremost front (180deg) and stops, the user then clicks this green circle (which will ultimately be an icon) to result in downloading the thing on offer. However, if not interested (after having moved the mouseover the central disc) moves the mouse away, with a delay of 2 seconds to be sure of disinterest, would then reverse the path of the little green disc to go back into hiding.

Now that seems a lot more complicated, what I have been able to figure out is how to get the little green circle to start from its stationary position, not jump to the bottom, and move within the circle, fine. But not how to stop at 180deg and I also don't understand why it zips off really fast when starting, but keeps a steady pace when in motion, did you notice that?

I thought then to counteract this I could put a white opaque block to the right of the divider to hide the green circle and then to start from behind that, your not supposed to see it to start with anyway, so when you see it move its smooth. With only 180deg of movement jutting too quickly for 30deg of it is too much of a compromise.


Here is the path that I am happy with:

int circleY = centerY - 9;

 // Only move the circle when "going" is true
 if (going) {
   //speed of movement
   pos += 0.05; // Change value to modify speed
   circleX = int(centerX - 0.4 * diskW * cos(pos));
   circleY = int(centerY + 0.3 * diskH * sin(pos));



Above I mentioned this was ultimately going to be a mouse over event, currently I have a mouse click event. I saw a tutorial on how to mouse over squares and they change colour, I should think it would be very similar to that: to pause while over and to reverse when moved away. Is it this one I should be looking at: Conditionals

http://www.learningprocessing.com/examples/chapter-5/example-5-2/


Thanks again for the help, its the mathmatics I'm no good at. Good tip about the variables.
Re: how o make a shape follow a curved path?
Reply #3 - Oct 28th, 2008, 9:42pm
 
It is an amusing challenge, so I tried to do what you describe...
Code:
boolean going = false, ready = false;
int timer = 0;

// I like to use variables, make easier to change / adapt
int centerX = 300;
int centerY = 250;

int diskW = 250;
int diskH = 50;
float ratioV = 0.3;
float offset = ratioV * diskH;

// Location of moving circle to start with (stationary)
float circleX = centerX;
float circleY = centerY - offset;

float pos = -HALF_PI;
float speed = 0.07;
color DISK_COLOR = #7ADE21;

//size of page
void setup() {
size(600, 600);
smooth();
}

//background colour
void draw() {
drawBackground();

// Moving circle shape size and colour details
stroke(0);
fill(DISK_COLOR);
ellipse(circleX, circleY, 22, 6);

// Only move the circle when "going" is true
if (going) {
pos += speed;
circleX = centerX - 0.4 * diskW * cos(pos);
circleY = centerY + offset * sin(pos);
if (pos >= HALF_PI) {
going = false;
ready = true;
timer = millis();
}
if (pos <= -HALF_PI) {
going = false;
speed = -speed;
}
}
if (ready) { // Wait for user input
if (millis() - timer > 2000) {
ready = false;
speed = -speed;
going = true;
}
}
}

// Set going to true when the mouse is over the green shape
void mousePressed() {
if (get(mouseX, mouseY) == DISK_COLOR) {
link("http://my.shop.com");
}
}

void mouseMoved() {
if (!ready && get(mouseX, mouseY) == DISK_COLOR) {
going = true;
}
}

void drawBackground() {
background(255);

// Disc
fill(255);
ellipse(centerX, centerY, diskW, diskH);

// Divider
stroke(0);
line(centerX, centerY - offset, centerX, 0);
line(centerX, centerY + 50, centerX, height);

// Bottom
noFill();
arc(centerX, centerY, diskW, diskH * 2, 0, PI);

// Big dot
fill(0);
ellipse(centerX, centerY + offset, 50, 15);

// Little dot
ellipse(centerX, centerY - offset, 7, 3);
}

Not the cleanest code I did, but it works...

See how to make gradient ellipse if you want to make a gradient in your ellipse.

Note: I "cheated" for the mouse over/click on disk code, another way is to compare mouse coordinates to radii of ellipse. Was lazy...
Re: how o make a shape follow a curved path?
Reply #4 - Oct 29th, 2008, 5:34pm
 
Hello, I have been playing with the code you so kindly provided, this is a lot more like what I wanted. I must confess that the green circle will actually have to be replaced with a graphic, one that scales, so it grows in size as it nears the front. Will this be hard to achieve with the exiting code?

It seems that you have completely understood the requirements I sought, I'm very greatfull to you for helping me out. Even hinting at a gradient effect, but I think I'll leave it with the wire like structure it has.

One thing I noticed was catching the green circle out by clicking it at its stationary position, launching the external webpage link, was coming back to the applet and clicking anywhere on it, the webpage would load again - its as if the whole applet is responsive to that line of code. However, if clicking the green dot when at the foremost position the effect would not be repeated ~ can you reproduce this result?
    Would it be possible to make the circle (image) invisible, becoming opaque only once the image is in motion so as to prevent users from clicking it in its stationary position and causing the error I mentioned? While providing a nice transition.

I was trying to move the "line(centerX, centerY + 37, centerX, height);" line of code which (I believe) draws the top half of the dividing line. I had the idea of placing this before the green button was coded so it would appear in front (the line is to look as if in the centre of the disc), that is in front of the green disc when stationary but behind when at the foremost part of the larger circle. I don't know if you positioned it behind because it would stay like that when the green disc had rotated to the front, so it would remain behind, I don't know if the swooping motion could tell if something is in the middle. But thinking now, if I can get the green disc (image) to be transparent to start with then it does not matter.

Regarding the mouse over event I was looking for a wider area that would be recognised, at the moment its set to focus on the small green button itself but I had the feeling this would not be obvious (as it was not to me at first!!) as what to focus on, this is an alien looking object. The entire large disc I though would be a better trigger. Also, I was hoping that the green disc (image) would remain at the front until the user moved away, at the moment it defaults to 2sec before returning, regardless, I only wanted that instance to occur when the mouse strayed away from the recognised area - which would be considerably greater with my proposals.

Would it be possible for the mouse pointer to morph into a hand to give feedback that the green circle (image) is a link. I only noticed in the code that it would link to a website, its not obvious without this indicator I think.

You said that you enjoyed the challenge of this, I think you've completely understood the idea and I'm glad you took it upon yourself to flex your skills. I couldn't have done it! Do let me know if you feel up to the above changes.

Thank you in advance.
Re: how o make a shape follow a curved path?
Reply #5 - Oct 29th, 2008, 11:25pm
 
OK, here is my little improvement of the day. It is late, I will continue tomorrow...
Code:
boolean going = false, ready = false;
int timer = 0;

// I like to use variables, make easier to change / adapt
int centerX = 300;
int centerY = 250;

int diskW = 250;
int diskH = 50;
float ratioV = 0.3;
float offset = ratioV * diskH;

// Location of moving circle to start with (stationary)
float shapeX = centerX;
float shapeY = centerY - offset;

float pos = -HALF_PI;
float speed = 0.07;
color SHAPE_COLOR = #7ADE21;
float SHAPE_WIDTH_MIN = 10;
float SHAPE_WIDTH_MAX = 25;
float SHAPE_HEIGHT_MIN = 3;
float SHAPE_HEIGHT_MAX = 6;
float shapeWidth = SHAPE_WIDTH_MIN;
float shapeHeight = SHAPE_HEIGHT_MIN;

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

void draw() {
drawBackground();
drawMovingShape();
drawUpperDivider();

// Only move the circle when "going" is true
if (going) {
pos += speed;
shapeX = centerX - 0.4 * diskW * cos(pos);
shapeY = centerY + offset * sin(pos);
if (pos >= HALF_PI) {
going = false;
ready = true;
timer = millis();
}
if (pos <= -HALF_PI) {
going = false;
speed = -speed;
}
float amount = (HALF_PI + pos) / PI;
shapeWidth = lerp(SHAPE_WIDTH_MIN, SHAPE_WIDTH_MAX, amount);
shapeHeight = lerp(SHAPE_HEIGHT_MIN, SHAPE_HEIGHT_MAX, amount);
}

if (ready) { // Wait for user input
if (millis() - timer > 2000 && !IsMouseInDisk()) {
ready = false;
speed = -speed;
going = true;
}
}
}

void mousePressed() {
if (ready && IsMouseInDisk()) {
link("http://Processing.org");
}
}

void mouseMoved() {
cursor(ARROW);
if (IsMouseInDisk()) {
if (ready) {
cursor(HAND);
} else {
going = true;
}
} else {
if (ready) {
ready = false;
speed = -speed;
going = true;
}
}
}

void drawBackground() {
background(255);

// Disk
fill(255);
ellipse(centerX, centerY, diskW, diskH);

// Bottom divider
stroke(0);
line(centerX, centerY + 50, centerX, height);

// Bottom
noFill();
arc(centerX, centerY, diskW, diskH * 2, 0, PI);

// Big dot
fill(0);
ellipse(centerX, centerY + offset, 50, 15);
}

void drawUpperDivider() {
// Divider
stroke(0);
line(centerX, centerY - offset, centerX, 0);

// Little dot
fill(0);
ellipse(centerX, centerY - offset, SHAPE_WIDTH_MIN, SHAPE_HEIGHT_MIN);
}

void drawMovingShape() {
// Moving circle shape size and colour details
stroke(0);
fill(SHAPE_COLOR);
ellipse(shapeX, shapeY, shapeWidth, shapeHeight);
}

boolean IsMouseInDisk() {
return IsPointInEllipse(mouseX, mouseY,
centerX, centerY, diskW, diskH);
}

boolean IsPointInEllipse(int x, int y,
int ellipseX, int ellipseY, int ellipseW, int ellipseH) {
// Compute position of focal points
float c = sqrt(ellipseW * ellipseW - ellipseH * ellipseH) / 2.0;
float f1x = ellipseX - c;
float f2x = ellipseX + c;
// Compute distances from focal points to given point
float d1 = dist(x, y, f1x, ellipseY);
float d2 = dist(x, y, f2x, ellipseY);
// Distance from focal points to point on ellipse is constant, equal to width
// (twice the distance between foci)
return d1 + d2 <= ellipseW;
}

[EDIT 2008-11-04] Now with cursor change, ellipse collision detection and improved behavior.
Re: how o make a shape follow a curved path?
Reply #6 - Oct 31st, 2008, 5:11am
 
Once again, thank you for helping out! I really like circle coming from nowhere!
Re: how o make a shape follow a curved path?
Reply #7 - Nov 4th, 2008, 7:47am
 
Just a quick note to say I improved slightly the code with ellipse collision (mouse in big ellipse), cursor change when ready to click and improved behavior (shape remains in front as long as cursor is in ellipse, or remains 2 seconds if out of ellipse before its reaches position or return to initial position as soon as cursor goes out).
Re: how o make a shape follow a curved path?
Reply #8 - Nov 4th, 2008, 8:12am
 
Thanks that's great!

Could a picture be substituted for the moving green ellipse? Would it scale as the ellipse does; so full size at the front and nothing from behind? I originally though of keeping the picture the same size and just fading its transparency to nothing when behind, I don't know if that would look better ~but I don't think it matters.

Thanks again for your help.
Re: how o make a shape follow a curved path?
Reply #9 - Nov 5th, 2008, 7:13am
 
I suppose it can be done, but there is an issue of resizing quality. I thought of a couple of solutions to keep the quality correct, I will try.
What kind of image, and what will be the final size of this icon?
Re: how o make a shape follow a curved path?
Reply #10 - Nov 5th, 2008, 11:25am
 
Well its a b/w jpeg, I could make it a PNG or GIF if that would help ~let me know. The dimension I think work are 72x71px I have uploaded an image of those dimension here for you:

http://lovelago.googlepages.com/t.jpg


Many thanks again for your efforts, far and above appreciated!
Re: how o make a shape follow a curved path?
Reply #11 - Nov 8th, 2008, 7:21pm
 
OK, yet another update.
I did a slight cleanup. It is still a bit messy, but OK for the given goal...
I added a little flexibility to choose from the old green ellipse and an icon.

Mmm, instead of pasting lot of code here, I put it in PasteBin, to keep formatting, get syntax highlighting and ease copying.

http://philho.pastebin.com/f6fa7a19c
Re: how o make a shape follow a curved path?
Reply #12 - Nov 8th, 2008, 10:05pm
 
Ahh, all good things come to those who wait. This is great, exactly what I wanted. I was trying to figure out how to arrange the void "drawUpperDivider()" so that is was positioned behind the moving shape, right now it overlaps it, what should I be looking up?

I'll let you see it soon.

Thanks.
Re: how o make a shape follow a curved path?
Reply #13 - Nov 8th, 2008, 10:20pm
 
Ah, the problem is that it must be draw after in the first part (hiding the shape) then before in the second part (so shape is over it). Not too difficult, fortunately.
New version at http://philho.pastebin.com/f7c9afb67

Note: I used a PNG image with partial transparency, like the light bulb seen at http://www.sitepoint.com/examples/8bit/ (indexed PNG with transparency).
Re: how o make a shape follow a curved path?
Reply #14 - Nov 8th, 2008, 10:52pm
 
Thanks very much, here it is:

http://lovelago.googlepages.com/index.html

Thanks very much for all your help, I couldn't have done it by myself.
Pages: 1 2