Hacker News new | past | comments | ask | show | jobs | submit login
T * sin (t) ≈ Christmas tree (2013) (github.com)
595 points by adamnemecek 25 days ago | hide | past | web | favorite | 44 comments

Hey, author of the project and the 2013 post here.

Just wanted to wish everyone amazing holidays! Thank you for love and shares :D

PS: More projects since 2013 can be found here: https://twitter.com/search?q=from%3Aanvaka%20min_retweets%3A... - hope you enjoy it.

Thank you! Amazes me how some people use it creatively to teach ordinary differential equations


This one [0][1] is probably my favourite variation.

[0] https://community.wolfram.com/c/portal/getImageAttachment?fi...

[1] Silvia Hao's reply at https://community.wolfram.com/groups/-/m/t/175891 (Also, why doesn't it have id attributes for individual replies?)

First idea I read title I thought about Mathematica and first comment is about Mathematica.

And in (quick and dirty) Python, with matplotlib:

    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
    r = 4*np.pi+theta
    z = -r
    x = r * np.cos(theta)
    y = r * np.sin(theta)
    ax.plot(x, y, z, 'g*')

    r2 = 4*np.pi+theta+np.pi/2
    z2 = -r2+np.pi
    x2 = r * np.cos(theta+np.pi/2)
    y2 = r * np.sin(theta+np.pi/2)
    ax.plot(x2, y2, z2, 'r*')
    ax.scatter3D(0, 0, 5, color='gold', s=200, marker="d")

Add this line at the bottom to show the tree:


If this interests you, you should check out the bivector community https://bivector.net/

Join the discord https://discord.gg/vGY6pPk.

Check out a demo https://observablehq.com/@enkimute/animated-orbits

Dumb question: In the code[1], the requestAnimationFrame() function is overwritten with a custom implementation using setTimeout(). From my understanding, this is done unconditionally, even if the browser provides the function (the reason is not a polyfill but having better control over the frame rate).

However, wasn't the whole idea of requestAnimationFrame() that it provides better timing guarantees than setTimeout()? So wouldn't overwriting with setTimeout kind of defeat the purpose of using it?

[1] https://github.com/anvaka/atree/blob/58680a99113cc40cd07c371...

The idea was to match animation speed of the gif and JavaScript implementation (which was 24 frames per second)

requestAnimationFrame() (RAF) is more likely to fire approximately 60 times per second than setTimeout(..., 1000 / 60) would. But I needed 1000 / 24, and setTimeout worked very well, so I used it.

If I were doing it all over again, I'd probably use RAF with window.performance, or simple counting variable as a timer. RAF is indeed much smoother than setTimeout and on top of it, RAF saves battery life when a user doesn't have your page open.

Good question!

What about using normal RAF and slowing the animation itself down to match the original GIF as best as possible?

I think that’s what they were suggesting with

> If I were doing it all over again, I'd probably use RAF with window.performance

Since RAF doesn’t give a guaranteed framerate you’d need to use metrics from window.performance to make the animation framerate-independent, or people on different browsers or devices could see the animation at different speeds.

A use-case where slower framerate is an upgrade - rare, but they exist.

My use case was doing a metaball animation using procedural scribbling[0], because the scribbles are random each frame, I needed a much slower framerate (10 or 15fps, IIRC), otherwise they'd look like a twitchy mess :)

[0] https://www.instagram.com/p/B3FWPi4o4Vq/

Yes, if you want to use setTimeout you should just use it directly. It's bad practice to override built in functions like requestAnimationFrame to do something different.

If the intent is to throttle the frame rate, then you should still use requestAnimationFrame, but simply return immediately if it's not time for a new frame yet. This can get you more consistent frame spacing than using setTimeout. But the difference is probably small.

Throttling the frame rate is a legitimate artistic choice that can evoke the feeling of watching a film projection; however it seems like the intent here may have been to slow down the speed of the dots, not necessarily to use a slower frame rate for its artistic effect. The animation speed is tied to the frame rate because the animation is advanced a fixed amount each frame. This is bad practice as well; instead the animation should be advanced based on the timestamp passed to requestAnimationFrame. Then the speed of the dots would be constant no matter the frame rate, and users of high frame rate displays would enjoy smoother motion.

All that said, it's a pretty animation that serves its purpose perfectly and none of these concerns are important in this context.

Overridden, overriding

It’s Christmas, so being generous, “overwritten” applies by the third definition here (https://www.dictionary.com/browse/overwritten)

Also, conferring correct usage, ie. actionable information, may be a gift as well, as the fourth definition here (https://www.dictionary.com/browse/overridden)

I did not find either on (http://catb.org/jargon/html/)

Language evolves and changes over time. I don't know whether the popular/common usage for the intended meaning (provide an alternative implementation of a function or method) has begun using "overwritten," but I'd argue that the underlying runtime implementation matters.

Typically, one's own implementations doesn't have the ability to literally overwrite the original - the original exists in some place and continues to exist in that place. You can point original symbols at a new implementation, but that old implementation isn't "overwritten" in memory. In OO runtimes, you can override in a subclass (but not overwrite), and the super class implementation is still right there, available as needed.

In the discussed case, if anything is truly "overwritten," it's the value (pointer?) at the symbol "requestAnimationFrame," but I'm doubting that's even that case - I'd wager (without being a deep JS expert) that the original is available in another scope.

Even given all that, if popular usage wants to go with "overwritten," fine - I'm not a linguistic purist.

What kind of ingrate files an issue on a Christmas present?

The same kind of person that thinks santa hats are as offensive as swastikas

I'm always grateful for all issues, on all repos, if the intention is to genuinely improve the project.

I usually agree, but two of the three open issues should really just be PR's :\


After typing that, I realized that this comment should actually just be a PR[1].

1: https://github.com/anvaka/atree/pull/14

I prefer people open issues before sending in PRs. I also always open an issue before creating a PR. It's possible the maintainer has different ideas/context I'm not aware of. You just never know. Surprise PRs can be disappointing for both parties if the maintainer decides to turn them down.

Oh, that's a really good point!

My approach is mostly shaped by my company's culture (which is definitely not one-size-fits-all): if it's a quick thing to code up, I prefer submitting it as a PR with an [RFC] prefix (I've re-titled my PR to include that), so the maintainer knows I'm not too tied to it.

I'll probably lean towards opening issues before PR's in the future though - thanks!

The problem with one-line PRs is that Github forces you to fork the repo first, but I don't want to litter my repository list with forks for one-off contributions.

Someone who wants to give a present to the project.

Desmos always has cool stuff:


Here is my take on it in ~140 characters of Javascript: https://www.dwitter.net/d/16973

A thread from last year: https://news.ycombinator.com/item?id=18758290

Discussed at the time: https://news.ycombinator.com/item?id=6971693

Edit: not implying that this is a dupe—I just mention these links for the curious. On HN, reposts don't count as dupes if a year or so has gone by: https://news.ycombinator.com/newsfaq.html.

Why not progressively reduce the angle to the cone's surface to keep the angle to horizontal the same all the way up?

I love this place.

It’s moments like these that I realize I should have perused more math to find my true programming potential. :/ I’ll never be the good without it.

I think if you find passion that needs math, you'll get your math to solid level too.

I'm personally never was good at math, so I want to see how it looks. That Christmas tree took me probably a week to build, and for someone it is likely a 10-20 minutes project.

Anyway, this curiosity motivates me to learn and build more. Hope it would work for you too!

> I think if you find passion that needs math, you'll get your math to solid level too.

This is an excellent point! There's no surer way not to motivate yourself to learn something than to think "maybe I'll use this one day" (or at least that's how it works for me); there's no surer path to lasting motivation to learn something than thinking that it'll be useful to address my current problem. (And then, once you get started learning it, often you'll find you get so excited that you go far beyond what you actually need–and that's fantastic!)

> It’s moments like these that I realize I should have perused more math to find my true programming potential. :/ I’ll never be the good without it.

It's never too late! I think that this is a good time to roll out:

> “The best time to plant a tree was 20 years ago. The second best time is now.”

(which I first heard from rabidrat at https://news.ycombinator.com/item?id=12204797).

Anyone have any good resources they’d recommend having done this?

HN has a wealth of suggestions on this:


The top links that come up all look interesting to me at first glance, but I am a mathematician by training rather than a programmer, so I can't say for sure.

Getting paid to write software for 20 years. Full-time, professionally, for 12 or so. Been considered "the smart guy" several places (others' words, not mine). Income's great.

I couldn't do anything "harder" than week two or three of Calculus 1 math without doing some reading, and even that would just be stuff I could solve by rote. And some of it I couldn't (I don't remember how to find limits, really). I've used stuff from linear algebra like once or twice ever (bitmap work on Android is the only one I can recall—camera shit, basically) and don't remember a single useful thing from that, really. Graphs? I think I've actually written code that directly worked with graph structures for one project, ever. Got a rough idea of what can and can't be done and know what to look up, which 100% suffices for stuff I do almost, but not quite, never.

Literally the only time I sweat this crap is when it's interview time. Otherwise, I recognize enough and have good enough google skills to find what I need. I'm still with-it enough that I could get actually-good at some of the math if I ever did find myself doing e.g. machine learning. Otherwise? Meh. I'll learn it when I need it. As far as I can tell outside a handful of positions that I am not gonna get hired for (too competitive and I don't got the pedigree for that, most of them require moving and I don't wanna), no one cares. Again, except in interviews when some companies decide you need to have a ton of stuff you have never used memorized.

[EDIT] to be clear, I don't mean to knock people who are more inclined to play with equations & proofs than I am, nor to shit-talk the work in question, which is neat.

If you want to learn some cool math, check out bivector https://bivector.net/

Check out the demo https://observablehq.com/@enkimute/animated-orbits

Join the discord channel https://discord.gg/vGY6pPk

Same boat. Am now working my way through Brilliat.org maths courses.

Their way of focusing on intuition as opposed to rote learning resonates well with me. And being properly motivated makes all the difference this time around.


If you're partying with friends why are you posting on the internet?

Must be a boring party I guess...

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact