# Hide all bezier curves except the one on mouse hover

**URL:** https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618
**Category:** Coding Questions
**Created:** [August 26, 2019, 2:26pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618 "2019-08-26T14:26:57Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 26, 2019, 2:26pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/1 "2019-08-26T14:26:57Z")

</div>

Greetings!  
I have four bezier curves (pasted code for two below as MCVE), and would like to be able to show only one if the mouse is hovered over the respective one.  
I tried finding how to assign a class to the curve, use a distance condition, but all were failed attempts. I could use some guidance, so if anyone could help me out here, pretty please? thank you!

```auto
var activitesCurve = function(bzCurve) {
  bzCurve.setup = function() {
    var run = [25, 50, 60, 70];
    var walk = [15, 75, 80, 40];
    bzCurve = new BzCurve();
  }
  bzCurve.draw = function() {
    bzCurve.show();
    class BzCurve {
      constructor() {
        this.stroke = (239, 31, 193);
        this.margin = 50;
        this.height = bzCurve.windowHeight;
        this.arr = run;
        this.maxLength = run.length;
        this.pointGap = position;
      }
      show() {
        bezierCurve.stroke(this.stroke);
        bezierCurve.beginShape();
        bezierCurve.vertex(this.margin, this.height / 2 - this.arr[0]);
        for (int i = 1; i < this.maxLength; i++) {
          var posX = bezierCurve.float(i * this.pointGap + this.margin);
          var posY = bezierCurve.float(this.height / 2 - this.arr[i]);
          var c1 = bezierCurve.float((i - 1) * this.pointGap + this.margin);
          var c2 = bezierCurve.float(this.height / 2 - this.arr[i - 1]);
          var c3 = posX;
          var c4 = posY;
          bezierCurve.bezierVertex(c1, c2, c3, c4, posX, posY);
        }
        bezierCurve.endShape();
      }
    }
  }

  // Walk Line
  bezierCurve.stroke(23, 225, 0);
  bezierCurve.beginShape();
  bezierCurve.vertex(margin, height / 2 - walk[0]);
  for (int i = 1; i < walk.length; i++) {
    var posWX = bezierCurve.float(i * pointGap + margin);
    var posWY = bezierCurve.float(height / 2 - walk[i]);
    var cW1 = bezierCurve.float((i - 1) * pointGap + margin);
    var cW2 = bezierCurve.float(height / 2 - walk[i - 1]);
    var cW3 = posWX;
    var cW4 = posWY;
    bezierCurve.bezierVertex(cW1, cW2, cW3, cW4, posWX, posWY);
  }
}

```

---

<div class="post-metadata">

### Author: ![William3954](https://avatars.discourse-cdn.com/v4/letter/w/6a8cbe/32.png) [@William3954](https://discourse.processing.org/u/William3954)
#### Post date: [August 26, 2019, 3:49pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/2 "2019-08-26T15:49:57Z")

</div>

First, make a class for your curves. Make a Boolean variable within the class for visibility.  
Within your class, create a update function and a draw function. During the draw loop, run your update function for your curve(s) which you will have code to check the distance from the mouse; if it within a certain threshold, set the visibility variable to true (all within the update function still). Then call your draw function for that curve which you will have coded to only draw if the vis is true. This could be simplified but it is the default way I would approach it.

---

<div class="post-metadata">

### Author: ![William3954](https://avatars.discourse-cdn.com/v4/letter/w/6a8cbe/32.png) [@William3954](https://discourse.processing.org/u/William3954)
#### Post date: [August 26, 2019, 3:56pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/3 "2019-08-26T15:56:12Z")

</div>

Btw - class for a curve would be something like this:

```auto

Class myCurve{
Boolean myVisibility;
//add variable you need to define the curve etc

//constructor below
 Void myCurve(){
//build the base curve here
}

Void update(){
//check the mouse pos vs your curve pos here
}

Void drawCurve(){
//put your drawing stuff here 
}

}
‘’’
```

---

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 26, 2019, 4:48pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/4 "2019-08-26T16:48:22Z")

</div>

Hi William!

Thanks for the response.

Apologies as I messed up, I’m working on P5js and not Processing :-/  
Also made updates, I’m working with multiple Canvases, this one named bezierCurve. The updated code is;

```auto
bezierCurve.stroke(239, 31, 193);
// Run Line
  bezierCurve.beginShape();
  bezierCurve.vertex(margin, height/2-run[0]);
  for (int i=1; i<run.length; i++) {
    var posX = bezierCurve.float(i*pointGap+margin);
    var posY = bezierCurve.float(height/2-run[i]);
    var c1 = bezierCurve.float((i-1)*pointGap+margin);
    float c2 = bezierCurve.float(height/2-run[i-1]);
    float c3 = posX;
    float c4 = posY;
    bezierCurve.bezierVertex(c1, c2, c3, c4, posX, posY);
  }
  bezierCurve.endShape();

// Walk Line
  bezierCurve.stroke(23, 225, 0);
  bezierCurve.beginShape();
  bezierCurve.vertex(margin, height/2-walk[0]);
  for (int i=1; i<walk.length; i++) {
        var posX = bezierCurve.float(i*pointGap+margin);
    var posY = bezierCurve.float(height/2-walk[i]);
    var c1 = bezierCurve.float((i-1)*pointGap+margin);
    float c2 = bezierCurve.float(height/2-walk[i-1]);
    float c3 = posX;
    float c4 = posY;
    bezierCurve.bezierVertex(c1, c2, c3, c4, posX, posY);
  }

```

I tried adding a class but not able to define it for some reason.

```auto
bzCurve = new BzCurve();

```

followed by defining the class with a nested function to display (show)

```auto
class BzCurve {
constructor(){
...
}
show() { 
... }
}

```

But when I try to load it by entering

```auto
bzCurve.show();

```

Im getting an error;  
Uncaught ReferenceError: BzCurve is not defined.

Quite lost here…

Thanks much!

---

<div class="post-metadata">

### Author: ![William3954](https://avatars.discourse-cdn.com/v4/letter/w/6a8cbe/32.png) [@William3954](https://discourse.processing.org/u/William3954)
#### Post date: [August 26, 2019, 4:56pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/5 "2019-08-26T16:56:45Z")

</div>

Ah, on the road and have not played with p5.js too much. The only thing that I could see quickly is that there isn’t a constructor in your class, but this may be different in p5.js. Maybe one of the other lads will jump in with suggestions.

---

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 26, 2019, 6:41pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/6 "2019-08-26T18:41:34Z")

</div>

Thanks for letting know William, I do have a constructor included. Left it out to keep the MCVE down to M 😛  
Still trying to figure this out so I’m hoping a lad would chime in and help out here.  
Cheers!

---

<div class="post-metadata">

### Author: ![micycle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micycle/32/201_2.png) [@micycle](https://discourse.processing.org/u/micycle)
#### Post date: [August 26, 2019, 7:25pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/7 "2019-08-26T19:25:26Z")

</div>

For each curve, enumerate the coordinates of the points that lie on it and check, using the mouse coordinate, for an overlap.

An O(n) time complexity and `pixelCount` space complexity solution to determine mouse hover is to create a 2D array with the dimensions of the screen and assign a number to each pixel indicating the ID of the bezier curve that overlays the given pixel (where a value of 0, or -1 could indicate that no bezier curve intersects the pixel). During runtime, lookup `array[mouseX][mouseY]` to determine intersection (if any) between the mouse coordinate and bezier curves.

_How might you determine the coordinates of points that lie on a bezier curve?_

Processing provides the following method: _bezierPoint(a, b, c, d, t)_, where…

```auto
a	float: coordinate of first point on the curve
b	float: coordinate of first control point
c	float: coordinate of second control point
d	float: coordinate of second point on the curve
t	float: value between 0 and 1

```

…to enumerate the coordinates of the points that lie on each bezier curve.

Iterate over `t` (increments of 0.005 would seem suitable) to find coordinates of points over the entirety of each curve.

Note that for each value `t`, the x and y coordinates of the point are calculated separately, by feeding in solely x values of the control points to bezierPoint(), followed by another call where solely y values of control points are input. See the [reference](https://processing.org/reference/bezierPoint_.html) for more information.

---

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 26, 2019, 8:25pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/8 "2019-08-26T20:25:16Z")

</div>

Thanks for the post!

I will admit, I read and have to yet read your response multiple times to make sense of it. Seems a bit too complicated for where I am at the moment, which is stuck trying to figure out why I’m not even able to define a new class for one curve on one of the two canvases.

Seems like setting up a mouseOver/ mousePressed function on a class would be the simplest way to do achieve my goal here, if only I can know why I see the error that my class is not defined when it is.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [August 26, 2019, 10:41pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/9 "2019-08-26T22:41:31Z")

</div>

What would be the purpose to hide all but one curve?? User would have to move the mouse randomly to find other curves!

Consider all curves are pale and one curve is highlighted?

Also, you didn’t understand mcve.  
Your mcve should be runnable so people can improve it instead of giving advice without running code…

---

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 27, 2019, 4:09am UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/10 "2019-08-27T04:09:21Z")

</div>

Thanks for the message, Chrisir!

Sure, all pale and one curve highlighted sounds good. I meant to hide all but one ‘only on hover’ of the respective one. So curve A,B,C,D loads just fine but when user hovers over A, the others B,C and D could be hidden or even better as you suggested, pale. Thanks for clarifying.

Point noted on mcve. I’ve updated the code and also pasted below. I’m still debugging logic here, so kindly pardon the novice approach here. [http://tiny.cc/fbisbz](http://tiny.cc/fbisbz)  
If you could improve, that would be simply perfect!

```auto
var activitesCurve = function(bzCurve) {
  bzCurve.setup = function() {
    var run = [25, 50, 60, 70];
    var walk = [15, 75, 80, 40];
    bzCurve = new BzCurve();
  }
  bzCurve.draw = function() {
    bzCurve.show();
    class BzCurve {
      constructor() {
        this.stroke = (239, 31, 193);
        this.margin = 50;
        this.height = bzCurve.windowHeight;
        this.arr = run;
        this.maxLength = run.length;
        this.pointGap = position;
      }
      show() {
        bezierCurve.stroke(this.stroke);
        bezierCurve.beginShape();
        bezierCurve.vertex(this.margin, this.height / 2 - this.arr[0]);
        for (int i = 1; i < this.maxLength; i++) {
          var posX = bezierCurve.float(i * this.pointGap + this.margin);
          var posY = bezierCurve.float(this.height / 2 - this.arr[i]);
          var c1 = bezierCurve.float((i - 1) * this.pointGap + this.margin);
          var c2 = bezierCurve.float(this.height / 2 - this.arr[i - 1]);
          var c3 = posX;
          var c4 = posY;
          bezierCurve.bezierVertex(c1, c2, c3, c4, posX, posY);
        }
        bezierCurve.endShape();
      }
    }
  }

  // Walk Line
  bezierCurve.stroke(23, 225, 0);
  bezierCurve.beginShape();
  bezierCurve.vertex(margin, height / 2 - walk[0]);
  for (int i = 1; i < walk.length; i++) {
    var posWX = bezierCurve.float(i * pointGap + margin);
    var posWY = bezierCurve.float(height / 2 - walk[i]);
    var cW1 = bezierCurve.float((i - 1) * pointGap + margin);
    var cW2 = bezierCurve.float(height / 2 - walk[i - 1]);
    var cW3 = posWX;
    var cW4 = posWY;
    bezierCurve.bezierVertex(cW1, cW2, cW3, cW4, posWX, posWY);
  }
}

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [August 27, 2019, 5:22am UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/11 "2019-08-27T05:22:32Z")

</div>

We talk about an animation here because view changes depending on mouse position: which curve is highlighted.

Hence you should let your mcve have setup and draw()/loop

---

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 27, 2019, 5:26am UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/12 "2019-08-27T05:26:35Z")

</div>

Yup, setup and draw now included.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [August 27, 2019, 6:36am UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/13 "2019-08-27T06:36:11Z")

</div>

Here I worked with beziers

> [@Camera Animation: Move camera on 3D curve](https://discourse.processing.org/t/camera-animation-move-camera-on-3d-curve/13623):
>
> Hello all, when making a movie, I always wanted to go by the scene or object with a flying camera. This would be cool for Animation. I made a sketch now that features two different curves to animate the flying camera: one for camera position one for camera Look At. Both beziers can be edited separately. Then you can hit 0 or 9 to see the camera in action: it travels on one curve and looks to the point (same point number) on the other curve. There are 3 edit view modes: from south (proc…

I hope this helps.

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [August 27, 2019, 6:07pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/14 "2019-08-27T18:07:24Z")

</div>

If you have four curves and they aren’t updating every frame, then the picking algorithm is probably faster and more flexible.

1. create an index of colors, 1 for each stroke.
2. create a Graphics
3. set a thick stroke (e.g. 3-4), and draw each curve to the Graphics in a different color. update only when the curve locations change.
4. to check what stroke you are over, get your mouse pointer pixel from the Graphics and look it up in the index.

That is going to be way, way faster than trying to compute distance. because the picking lookup is layered, it will also avoid a lot of weird corner cases with distance detection – at each intersection, some lines will be implicitly “above” other lines because their pixels are drawn onto the lookup later.

Later, if you want to ovals or hexagons or rotated trapezoids or whatever, picking will handle that too – it doesn’t need new collision math for new entities.

---

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 27, 2019, 7:44pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/15 "2019-08-27T19:44:36Z")

</div>

Thanks for the your response, Jeremy!

I have SO much to learn. Could you help with resources on where to start?

> [@jeremydouglass](#):
>
> then the picking algorithm is probably faster and more flexible.

- Kindly advice what is a picking algorithm?

1. By index of colors, did you mean an array (just being sure here)?
2. Also, to clarify, I should try drawing all curve to the one Graphics created right?
3. I didn’t understand this point. I know how to get x and y coordinates using mousex and mouseY but not sure what you meant by looking it up in the index.

Thanks a ton!

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [August 28, 2019, 12:11am UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/16 "2019-08-28T00:11:01Z")

</div>

Here is a simple demonstration. Hopefully it answers your questions.

[https://editor.p5js.org/jeremydouglass/sketches/83XyPImMP](https://editor.p5js.org/jeremydouglass/sketches/83XyPImMP)

 ![26%20PM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/8/8e3b0c46a604e0585820c3716b934aeb5346f462.png)

Notice that there are two kinds of drawing from the curve data:

1. drawing the map, which is done in unique colors that are added to an index.
2. drawing on the sketch canvas – the curves don’t need to be unique colors, they can all be black.

In this sketch, the picking map is displayed on the right-hand side, but normally it is just an invisible off-screen buffer – it is only shown here to help you understand how the left-hand picker is working.

The mouse position is then checked against the map to identify which curve is under the mouse, and that curve can be styled at render time.

For a full library implementation in Processing (Java) – not p5.js – see the Picking library:

[http://n.clavaud.free.fr/processing/library/picking/](http://n.clavaud.free.fr/processing/library/picking/)

This enables you to generate your map as a byproduct of your drawing code, rather than the manual “drawing twice” approach.

---

<div class="post-metadata">

### Author: ![VMK](https://avatars.discourse-cdn.com/v4/letter/v/919ad9/32.png) [@VMK](https://discourse.processing.org/u/VMK)
#### Post date: [August 28, 2019, 1:52pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/17 "2019-08-28T13:52:17Z")

</div>

Hi Jeremy!

Thank you so much for illustrating with a simple and yet very helpful example. 🙌

If I may, could I use this logic for data that’s pulled from a JSON file? In other words, say if I would be drawing the bezier curves by first setting up a class in setup for eg,

```auto
curve1 = new BzCurve(column1);
curve2 = new BzCurve(column2);

```

where the JSON file would be =

```auto
[{ 
"column1": 50,
"column2": 75,
},
{
"column1": 75,
"column2": 95,
}
{
"column1": 10,
"column2": 120,
}
]

```

I’m not sure how to replace ‘cs’ in your beautiful example, and customize it.  
Also, this one went straight above my head 😒  
`pg.get(mouseX, mouseY)[0]==ccols[i]`

I see;

```auto
// compare the map color at mouse location
// with the index color for this object

```

What exactly are we getting here? What’s the meaning of map color?

I hope you don’t mind my followup Qs, but I’m looking forward to your response 🙂

Once again, thank you!

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [August 28, 2019, 2:16pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/18 "2019-08-28T14:16:45Z")

</div>

> [@VMK](#):
>
> pg.get(mouseX, mouseY)[0]==ccols[i]

I would expect

pg.get(mouseX, mouseY)==ccols[i]  
…

here.

But theoretically the idea is that **pg** holds the image of the same curves as the screen and the Image has the same size.  
pg has the curves in distinct unique colors ccols. These colors identify each curve. Use `image(pg,0,0);` to see **pg**.

Now `get()` gives us the color at mouse position in **pg**. When we find a color in that position that matches a curve we found that the mouse is over that curve. That’s one way of picking a shape/curve.

It’s a fantastic solution.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [August 28, 2019, 2:38pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/19 "2019-08-28T14:38:51Z")

</div>

> [@VMK](#):
>
> curve1 = new BzCurve(column1);

Shouldn’t you need 4 Positions (each with x and y and z) for each curve??

It 2 anchor points and 2 control points and each has x,y,z

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [August 28, 2019, 4:45pm UTC](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618/21 "2019-08-28T16:45:11Z")

</div>

> [@Chrisir](#):
>
> I would expect
> 
> ```auto
> pg.get(mouseX, mouseY)==ccols[i]
> 
> ```
> 
> here.

Yes, this is because p5.js colors work slightly differently than Processing(Java). We are using simple grayscale index values rather than full colors:

- save a grayscale value, like “64”, to ccols.
- Use it in makePicker to draw the line, e.g. pg.stroke(64);
- When we check with our mouse, we check the pg.get(mouseX, mouseY) pixel. In p5.js, get() “Returns an array of [R,G,B,A] values for any pixel”. So we get back [64, 64, 64, 255].
- get()[0] gives us… 64, which matches the index value in ccols.

[Next page](https://discourse.processing.org/t/hide-all-bezier-curves-except-the-one-on-mouse-hover/13618.md?page=2)
