HNHacker News
TopNewBestAskShowJobs

amitp

934 karma · joined January 14, 2012

I try to write better explanations of algorithms. I'm in the Silicon Valley area (south bay) and am happy to meet for coffee or lunch. See my interactive tutorials at https://www.redblobgames.com/

twitter:@redblobgames

submissionscomments
amitp··on Building a Hexagonal Grid in CSS
Thank you! Glad to hear it!
amitp··on Building a Hexagonal Grid in CSS
There are some gotchas when using sprites/images for hexagons. 1. The bounding boxes overlap, so you'll want to make sure that the sprites have transparent corners so that they don't overwrite what's in the next hexagon. 2. The images won't be exactly regular (equal sided) hexagons because regular hexagons have an irrational side width or height. The image size will be rounded off to the nearest pixel. You'll need to adjust for this in your hexagon calculations, either shrinking or expanding one of the axes a tiny bit so that both axes are integer sized. For example if your hexagon spacing is 173.20508 x 150 then you'll change your spacing to be 173 x 150, or whatever matches your image size.
amitp··on Building a Hexagonal Grid in CSS
Also cool: the last one wasn't discovered until 2015.
amitp··on Building a Hexagonal Grid in CSS
Vue is pretty good at generating SVG (I use Vue+SVG on https://www.redblobgames.com/grids/hexagons/) but there's a trick for making it work with Canvas too. https://simblob.blogspot.com/2018/03/using-vue-with-canvas.h... — it will make the canvas drawing function depend on the right data in Vue, so that if any of that data changes, it re-draws the canvas automatically.
amitp··on Ask HN: What scientific phenomenon do you wish someone would explain better?
It's magic. But here's a fun interactive explanation: http://www.jezzamon.com/fourier/
amitp··on Gears
I love ObservableHQ! I think it's a neat model that fixes a lot of things I didn't like about notebooks. I don't use it much though. It makes the simple things easier but it makes the complex things harder. Examples:

1. I often start making a diagram interactive by adding a slider connected to some state. The slider/state is in one "viewof" cell and the diagram is in another cell. But for more polished work I often want to use direct manipulation, where you move something around in the diagram itself. In my usual JS+Vue code it's a small amount of extra work. But in ObservableHQ it seems like a lot of work: the diagram has to modify state defined in a different cell (breaking the simple spreadsheet model in my head), and the diagram is being re-rendered while it has event handlers active.

2. I often start out by making one diagram. This is nice and easy. But then I want to make multiple diagrams with some shared state. In my usual JS+Vue code I can lift the diagram code into a function, pass in a shared object for shared state, and instantiate objects for non-shared state. In ObservableHQ those properties are in cells, and I can't generate multiple cells programatically (afaik).

I also would prefer to host things myself, both because of longevity, but also because I sometimes work offline (e.g. in a park or on a train). And the biggest reason I'm not using ObservableHQ is that I'm so much slower editing text on it than I am in Emacs. So I continue to use ObservableHQ for some simple projects/prototypes but I don't do a lot with it.

amitp··on Gears
SVG is declarative. You write <circle cx=300 cy=400 r=100 fill=red/> to make a red circle at (300,400) with radius 100. You can then change any of these properties and the system will redraw automatically. Canvas is imperative. You write ctx = canvas.getContext('2d'); ctx.fillStyle = "red"; ctx.beginPath(); ctx.arc(300, 400, 100, 0, 2 * Math.PI); ctx.fill(); and the system will draw that circle. You handle redraw yourself by redrawing everything on that canvas, so you need to keep track of it all. The DOM helpers (React, Vue, etc.) help you with SVG but not with Canvas.

I usually mock visualizations on paper! I'm interested in using WYSIWIG interactive diagram tools like http://aprt.us/ but I never seem to get into them. When I started, making the visualizations was the largest part of the work, but now I've gotten better at it, and making the explanation is now the part that takes the most time.

After paper, I often use SVG to make a non interactive diagram, either by hand, or in inkscape. One of my guiding principles is that the page should be usable without interaction, so the static diagram is a test of that. If it looks promising I can then gradually transform it into an interactive diagram. For example if I had the circle above, and I am using vue.js, I can change it to <circle :cx=x :cy=y r=100 fill=red/> (note the ":" before attributes), and then vue will fill those values in from the object I give it. I can give it {x: 300, y: 400}, and any time I change x or y, it will automatically redraw. I can then hook up x or y to a slider to try out the interactivity. This allows me to start with a static diagram, gradually add interactivity, and then build reusable abstractions that I can apply to multiple diagrams. ObservableHQ and React/JSX allow something similar, with slightly different syntax.

I'd love to see an article about regexes with interactive diagrams. There's a standalone diagram tool https://regexper.com/ and an interactive tutorial https://regexone.com/ but neither is an essay in the style of the Gears article. If you're pursuing this, let me know at redblobgames@gmail.com and I can send over more resources.

amitp··on Gears
Having been down this road, yes, it does take time, but you can save some time by using SVG and some DOM library. Although canvas is faster, most diagrams don't really need it, so I use SVG unless I really need to switch to canvas. SVG also adjusts for screen dpi automatically.

The things I like:

1. Reactivity (ObservableHQ, Vue.js, hyperactiv.js, etc.). There's usually some underlying data and then a corresponding visualization. These reactive systems let you modify the underlying data and then the visualization updates automatically. You don't have to figure out which diagrams to update when. Even easier: just redraw everything every time you change anything.

2. Some easier way to write the DOM (d3.js, jsx, vue, lit-html, etc.). Since I'm writing a blog post with html, I usually prefer writing my js-in-html (vue) rather than html-in-js (jsx) but try both directions and see which you prefer.

3. No build step. This is especially important when I want to update a page years later and don't want to figure out which build tools I was using in 1997 or 2007 or 2017. I want my pages to last for decades, and I still update my pages from 25 years ago.

I tried recreating one of the gear page diagrams in ObservableHQ https://observablehq.com/@redblobgames/unwind-circle-example . It's not a lot of code. There's a slider, there's a loop to generate the lines, and there's the output svg. Whenever you move the slider it recalculates the output.

I admit that I'm not using ObservableHQ much for my own projects because I want more of a "hand-written" style. I used d3.js for my older pages and vue.js for my newer pages. Vue's reactivity and templates save me probably a factor of 2 or 3 over d3.js.

amitp··on Gears
Really great interactivity and visualizations on this blog. Check out the other posts too: https://ciechanow.ski/archives/
amitp··on What's Wrong with This Snowflake?
Re: color — it's not just restaurants. Board games, card games, Google/Microsoft/other logos, etc. also use 4 colors. Why?

Opponent-process theory (https://psyc.ucalgary.ca/PACE/VA-Lab/colourperceptionweb/the...) says that the eye converts the three wavelength inputs into six orthogonal axes (dark-bright, yellow-blue, red-green). From these axes we get the four primary colors: red, yellow, green, blue. Of course things are never so simple. There are various attempts to measure the perception of color (https://www.handprint.com/HP/WCL/vismixmap.html#ncs), and none of them place red-yellow-green-blue exactly along the axes.

amitp··on Azgaar’s Fantasy Map Generator (2018)
That amazing blog is one of the inspirations for Azgaar's map generator: https://azgaar.wordpress.com/2017/03/30/first-post/
amitp··on Azgaar’s Fantasy Map Generator (2018)
Code-wise, it's mostly using d3.js to generate SVG. You can browse it at https://github.com/Azgaar/Fantasy-Map-Generator .

Algorithm-wise, it's built on Delaunay+Voronoi: https://azgaar.wordpress.com/2017/03/30/voronoi-graph/

The project started after Azgaar was inspired by Mewo2's map article and Scott Turner's amazing map blog: https://azgaar.wordpress.com/2017/03/30/first-post/

amitp··on Azgaar’s Fantasy Map Generator (2018)
Even better, the cities on Azgaar's maps link to Oleg's (watabou's) maps! Click on a city name and then click the "folded map" icon. It will create a city that matches the environment on Azgaar's maps (e.g. port city vs inland, rivers, etc.).
amitp··on At Dynamicland, the Building Is the Computer
I've been to Dynamicland a few times, and from what I saw, it is not designed to build "robust large-scale systems". It's exploring a different side of computing.

Things that get in the way of robustness: state is based on the physical world. You knock something over, the state has changed. To change the state, you need to move a physical object, which typically means you need a human to do it; the programs can't change state officially. They get around this by storing state anyway, which leads to some weird behavior at times. They've experimented with using magnets to have the system be able to change the physical state, but it's a hard limitation to get around. Also, you want to make a backup of the data? No can do, because we don't have a way to clone physical objects.

Things that get in the way of scaling: all programs are running in a global shared space. Every program can write anywhere to the display or generate audio etc. It's pretty cool! You can run a program that overwrites all output with rainbows. Even more, every program has access to every other program. There's no security. For example you can put a program down on the table and point it at another program to change the second program's code. Cool stuff!

All of this goes against the things we are taught about modularity and scaling and security.

There's a lot of magical stuff going on at Dynamicland but I think it's not a way to create "software" as we think of it. It's a type of computing that isn't easy to do now. It's kind of like comparing a smartphone to a crystal radio kit. The smartphone does a lot of amazing things, and it does it at scale, but the crystal radio kit lets you and your friends tinker and make new things. Apples and oranges.

Dynamicland makes me think of Morpheus's line, "Unfortunately, no one can be told what The Matrix is. You have to see it for yourself."

amitp··on Emacs 26.3
Thank you for that package!
amitp··on WikiWikiWeb
It was a great online community!

It was weird how shared content (what we think of as a wiki today) and discussion ("talk" pages on wikipedia) were all mixed together, and it somehow worked. The only Wiki I use these days that still does this is EmacsWiki. Google Wave felt like this in reverse, starting with discussion as default but you could edit everything into a document.

Also: hi Sunir!

amitp··on Hexagonal Grids (2013)
Thanks! I'm keeping a list of ideas here: https://trello.com/b/mjOSMtsi/2019 but I'm not working on much at the moment. I needed a break after mapgen4 (2017-2018).
amitp··on Hexagonal Grids (2013)
Thanks! I've found that my best pages are topics from real projects I've worked on, and I haven't worked on many game AI systems. I might have pointers to papers or web sites for you; feel free to email me at redblobgames@gmail.com
amitp··on Hexagonal Grids (2013)
Wow, awesome to hear it!
amitp··on Hexagonal Grids (2013)
Cool! Glad the page helped! On the implementation page the code supports both y-up and y-down, as well as negative coordinates. One of these days I should update the diagrams on the main page to support this too.
amitp··on Hexagonal Grids (2013)
Thanks for your library! I've linked to it from my Hex code implementation guide.

For game related topics, I like http://gameprogrammingpatterns.com/ (book available for purchase, but also freely viewable on the web)

amitp··on Hexagonal Grids (2013)
Thanks! Lots of changes since the last time it showed up (2017 I think): faster page load, less JS, better diagrams, more diagrams, better colors, axes legend, more polish, more interactive parts. I wrote about these http://simblob.blogspot.com/2018/04/april-updates-hex-grid-g... and http://simblob.blogspot.com/2018/04/april-updates-iteration....
amitp··on Hexagonal Grids (2013)
A surprise to see my page on HN! For those of you curious about the tech:

Diagrams are in SVG. Canvas would be faster but SVG is easier for me to work with, especially for attaching mouse events to each hexagon. It also automatically scales to high dpi displays. With SVG and HTML accessed the same way, I can use the same code for updating text/samples as I do for updating diagrams. This includes interpolating values as noted by anchpop.

I don't use a build step for the JS code. It's just <script> tags, like it's 1999! You can View Source and see them all. I realize it'd be better if I minified bundled etc. but I'm lazy and this was easier. The page is implemented differently from a "single page app". For that, you might want something like JSX so that you can stay on the JS side, and output HTML+CSS as needed. For this kind of page, I mostly write HTML+CSS, and I tap into JS when needed using Vue.js. For example, I want the text "w = 2 * size" to be next to the rest of the text for that paragraph, instead of in a separate JS file:

       <p>
          Next we want to put several hexagons together.
          In the {{layout}} orientation, a hexagon 
          has width
          <code v-if="layout === 'flat'">w = 2 * size</code>
          <code v-else="">w = sqrt(3) * size</code>
          …
        </p>
I do use a build step for the HTML+SVG. Although the page works without this step (see pre-index.html), the user experience is a little bit better if I generate it on the server. I use cheesy pre-rendering for this: "$(CHROME) --headless --disable-gpu --dump-dom". It means more bytes :( but having all the HTML/SVG load at once is better for linking to a section, hitting the back button, etc. You don't lose the scroll position. Bonus: the page loads if you have Javascript turned off!

The static SVG on the server doesn't include the interactive parts. I use InteractionObserver to replace the static diagram with an interactive one as soon as you scroll to that section of the page.

I said I don't have a JS build step, but that's not quite true. The core hexagon algorithms were originally implemented in Haxe, compiled to Javascript. At the time (2013), I was curious about Haxe as an alternative to Javascript. Because I was either bored or crazy or both, in 2015 I implemented a code generator that used Haxe macros to parse the algorithms in Haxe-ish syntax[1] and then generate C++, Javascript, Python, and other output. The Javascript output from that is what now powers the page. Well, it's even more convoluted than that. The Haxe code generates Typescript[2], which I turn into Javascript[3]. I don't know what I was thinking! Well, I do — I wanted my readers to be able to use my unit-tested hexagon algorithms even if they were using a different programming language.

I wrote [4] describing the process of making an interactive page like this with D3.js. Check out [5] for a collection of interactive explanations from other people.

It's unlikely that you will print the page, but if you do, it will show endnotes for all the links so that you can see the URLs.[6]

[1] https://www.redblobgames.com/grids/hexagons/codegen/Codegen.... [2] https://www.redblobgames.com/grids/hexagons/codegen/output/l... [3] https://www.redblobgames.com/grids/hexagons/codegen/output/l... [4] https://www.redblobgames.com/making-of/line-drawing/ [5] https://explorabl.es/ [6] https://simblob.blogspot.com/2018/12/printing-my-pages.html

amitp··on An Interactive Introduction to Fourier Transforms
For interactive explanations check out: https://explorabl.es/
amitp··on The Wavefunction Collapse Algorithm Explained
I feel the same way. It is constraint satisfaction with a name that gets people's attention. https://adamsmith.as/papers/wfc_is_constraint_solving_in_the...
amitp··on Taking lessons from the rise and fall of divinity in online games (2014)
I love it when everyone gets XP. Realm of the Mad God (2009) did this too — you don't have to formally join a group to be part of the action, public quests, coop play, everyone gets XP, everyone gets loot, everyone wins.
amitp··on Brain.fm: Music to improve focus, meditation and sleep
I liked these, along with Perfecto Podcast and a few others, but then I found Deep Sunset House and Progressive. I liked it even better, in large part because they don't interrupt the music with talk of their latest show etc.

brain.fm seems to work for me, so I bought a lifetime subscription back when it was available, but the iOS app is flaky enough that I don't use it that often. I don't understand what the "AI" is doing for me, but it makes the experience worse. I'd rather have a static set of music files that are in the app so that I can play them offline (e.g., while traveling). Or even better, not in the app so that I can put them into a music player. The app does have an offline mode but it's awkward.

I recently learned Pzizz (which is nice for sleep) added a focus mode. I should try that sometime. Their app is much more reliable than brain.fm's app. However they don't have a lifetime purchase option, and I almost never sign up for subscription services, so I'm only using the free version.

amitp··on Delaunay and Voronoi on a sphere
See section 8.5 of http://www.cis.upenn.edu/~cis610/convex8.pdf for the analysis showing that the stereographic projection is the projection that preserves the properties needed for Delaunay triangulation. I learned this technique from Philippe Riviere, who uses it in the d3-geo-voronoi library - https://beta.observablehq.com/collection/@fil/voronoi
amitp··on Delaunay and Voronoi on a sphere
If I understand correctly, the stereographic projection does handle Delaunay+Voronoi on a sphere, for all points except the south pole. See section 8.5 of http://www.cis.upenn.edu/~cis610/convex8.pdf
amitp··on Delaunay and Voronoi on a sphere
In the projection, some triangles are rather spread out, and some are even going to cross from -Infinity to +Infinity. I didn't want to handle that wrap-around-infinity case and thought it'd be easier to calculate them on the sphere instead of on the projection.
← PreviousPage 5 of 7Next →