Procedurally Generated Heart In Three.JS

Hey all, I’ve been slowly learning JavaScript on the side and wanted to try and animate this with Three.JS:

I was trying to re-create that equation but ran into a wall in that the code below is not producing the right results at all! I had read that JS has some big issues with floating point numbers and in particular cubed roots don’t really work all that well…

Here is my code implementation using Three.js:

The main issue is on line 30.

Anyone have any ideas!?



1 Like

There you can see functions for a heart. Maybe it helps?
Line 171

Just try out functions
See Addon to create special / extended geometries

1 Like

@Phred, what’s wrong with the answers you got in StackOverflow? It looks like you’re not taking any of those responses into account in your new code.

Oh yes I tried those too, you can see the new pow function further down in the link I sent. Also didn’t work. You can sub in the function name and see for yourself.

What about the other posted answer? Did you take that one into consideration? The formula you’re using will return 0 for all values except those within x = [-1.7, 1.7], but you’re sampling x values from [-150, 150]. You can see the x/y-values on the GIF you linked, the axis tick-marks are all very close to 0.

It’s a problem of scale, you’re using numbers that are too big.

Yeah tried that too! No dice! :frowning:

Can you elaborate? What did you try? What part didn’t work?

Tried it with the range from -1.8 to 1.8, 2000 vertices and THREE.ShaderMaterial():


Very cool approach! Never thought of using the VS for that.

Though when I ran it, it only showed the left half of the heart.


Can you elaborate? What did you try? What part didn’t work?
I tried both using the new pow method someone posted AND using a smaller loop.

The current result is here:

It seems from the output that values are quiet small and looks more than the last part of the equation is what’s doing that:
Math.sin(30 * Math.PI * x)

Interesting, I’ve got the correct result on an built-in Intel GPU and that half-hearted shape on GTX :smile:

After some changes it looks okay on GTX (can’t check it on Intel as it’s at work). Just wrapped all x values in pow() functions with abs() :slight_smile:

Oh, yeah )) This is my reference for that scene, dedicated to 100th revision of Three.js :slight_smile:

1 Like

ok so I finally solved this! Turns out it wasn’t to difficult and if you follow the original link to my Code Sandbox you can see the final result and play with it.

It came down to this line with the key being to use Math.abs(x) inside the first Math.pow statement:
var y = Math.pow(Math.abs(x), 0.66) + (0.9 * Math.sqrt(3.3 - x * x)) * Math.sin(10 * Math.PI * x);

Thanks for everyone who provided input and help!