Inverse of common ease curves

July 13th, 2016

Awkwardly I ended up needing the inverse of an ease curve (or S-curve) used in tweening animations. For trigonometric ease curves, this is easy. For example, if your ease filter is:

f = 0.5-cos(x*pi)*0.5;

then the inverse is:

x = acos(-2*(f-0.5))/pi

But if you’re using the famous cubic ease curve,

f = 3.*x.^2 - 2.*x.^3

then the relevant inverse is a complex function (involving the i = sqrt(-1)) that produces real values for f in [0,1]:

x = -1./4.*(1-2.*f+2.*(f.^2-f).^(1./2)).^(1./3)-1./4./(1-2.*f+2.*(f.^2-f).^(1./2)).^(1./3)+1./2-1./2.*i.*3.^(1./2).*(1./2.*(1-2.*f+2.*(f.^2-f).^(1./2)).^(1./3)-1./2./(1-2.*f+2.*(f.^2-f).^(1./2)).^(1./3));

I haven’t bothered to see if this can be simplified into something tidy. It’d be great to get rid of the i.

MAC Address Spoofing on Mac OS X for unlimited free hour passes on xfinitywifi and CableWiFi networks

July 8th, 2016

From what I gather, xfinity charges people to “rent” wifi routers and then uses that hardware to host pay-per-use public wifi networks. These networks are usually named xfinitywifi or CableWiFi. Every 24 hours each MAC Address is granted a “$0.00 Complimentary Free Pass”:

  1. CLICK I am not an XFINITY customer
  2. CLICK Sign Up
  3. CHOOSE $0.00 for a Complimentary Hour Pass
  4. CLICK Start Session

To “spoof” a new wifi MAC Address on MAC OS X, one can issue:

ifconfig en0 | grep ether

This will spit out a number like: 70:51:81:c1:3f:6e. Record this number. To set your MAC address to a random yet valid address use:

sudo ifconfig en0 ether `openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//'`

Then, later, if you want to return to your old address issue:

ifconfig en0 ether 70:51:81:c1:3f:6e

It seems that System Preferences > Network > Advanced > Hardware will reveal your original MAC address in case you forget it.

You can also place these commands as aliases in your ~/.profile:

alias random_mac="ifconfig en0 ether \`openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//'\`"
alias reset_mac="ifconfig en0 ether 70:56:81:c0:3f:6d"
alias sudo='sudo '

This all assumes en0 is your wifi location. It might be en1 on other macs.

Baran & Lehtinen’s “Notes on inflating curves” 2009

June 29th, 2016

Notes on inflating curves

Ilya Baran has permitted me to host online his and Jaakko Lehtinen’s technical report from 2009, Notes on Inflating Curves.

The clever “trick” in this approach is rather than to set the height as the solution to a Poisson equation, to set the square of the height to the solution to a Poisson equation. This ensures that the surface normals are in plane at the boundary so the inflated surface may be glued to itself and turned into a closed “pillow” surface. This idea was leveraged and expanded upon in Ink-and-Ray: Bas-Relief Meshes for Adding Global Illumination Effects to Hand-Drawn Characters.

You could cite this note as:

  author = {Baran, Ilya and Lehtinen, Jaakko},
  title = {Notes on inflating curves},
  institution = {MIT},
  year = {2009},

Javascript bookmarklet to delete first publication from CCV web form

June 17th, 2016

The Canadian Common CV webform failed to upload my publications correctly. But it doesn’t allow batch deletion of items so to delete each one at a time I’d have to click the little trash can and click “Yes” and then the page reloads. To avoid this I wrote a little javascript bookmarklet:

eval($("img[alt^=Delete]")[0].getAttribute('onclick').replace('preventBubbling(event);askDeleteBefore','processSubmit').replace('return false;',''))

Adding libigl as a submodule

June 9th, 2016

If you’re adding libigl as a submodule to your project, you should add it recursively so that all of its submodules are also pulled in:

git submodule add
git submodule update --init --recursive

A simple, cheapskate super resolution implementation in pure matlab

May 26th, 2016

As a proof of concept, I implemented a very simple image upsampling/super resolution algorithm. This method uses local self-examples: it replaces each pixel with a 2×2 block of pixels interpolated between blocks from the same image. The blocks are identified based on matching the local regions around.

If the window radius =1, then I first create a point in Wij in R9 for every pixel (i,j) so that W22 = [I11,I12,I13,I21,I22,I23,I31,I32,I33], where Iij is the color at pixel ij.

Then for every 2×2 block Dij centered at the bottom right corner of pixel (i,j) I create a point in R9, so that D22 = [0.25(I00 + I01 + I10 + I11), 0.25(I02 + I03 + I12 + I13), … , 0.25*(I44 + I45 + I54 + I55)]. So the points Dij represent downsampled blocks.

The above, treats all coordinates (neighboring pixel values) equally. I found that it’s best to weight the influence by a Gaussian so that the center pixel/block is worth more.

Then for each Wij I identify the closest K Dij using knnsearch. I replace the pixel (i,j) with an interpolation of the K blocks. This is done using Shepard interpolation with distances measured in the weighted R9 space.

Flipping around through the literature, this seems in spirit with 2000-era Freeman-type super-resolution algorithms. And the results are comparable. But by no means are these as good as state of the art heavy-learning based techniques around today.

Find the code for imupsample in gptoolbox.

Here’re some examples:

nearest neighbor, imresize, imupsample and ground-truth

And here’s a bigger example:

hans hass imupsample

There’s still a bathroom window effect happening, but with more local samples to choose from, up sampling bigger images seems to work better.

Trouble building opencv_contrib extras, can’t find unsupported/Eigen

May 23rd, 2016

I ran into a problem compiling the opencv_contrib modules.

Just running a vanilla cmake then make:

cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules ..

produced the error:

/Users/ajx/Downloads/opencv/opencv_contrib/modules/rgbd/src/odometry.cpp:41:10: fatal error: 'unsupported/Eigen/MatrixFunctions' file not found
#include <unsupported/Eigen/MatrixFunctions>

It seems the problem is that cmake was finding Eigen in /Library/Frameworks/Eigen.Framework/. I don’t even know how that Eigen got installed. Homebrew? Does it ship with Mac OS X now? In any case, I fixed the issue by pointing cmake directly to my homebrew’s Eigen installation:

cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules -DEIGEN_INCLUDE_PATH=/usr/local/include/eigen3/ ..

Adding zero to sparse matrix in matlab results in dense matrix

May 20th, 2016

Here’s a little gotcha I stepped into today:


returns false (and therefore takes a long time). This is consistent in the sense that sparse + dense in matlab returns dense, but definitely goes against my expectation in this specific case.

Apache rewrite rule to send all urls from site A to analogous url on siteB

May 19th, 2016

Here’s the rewrite rule I’m putting on my site’s .htaccess file to redirect everything to my new site:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^$ [NC]
RewriteRule ^(.*)$$1 [R=301,L]

Now, not only does redirect to, but so do more complicated urls: –>

This also works for <img src= tags:


Debugging .htaccess commands is made especially tedious because browsers like Google Chrome and Safari cache old .htaccess files. So it’s easy to be tricked into thinking your rewrite rules aren’t working. Remember to clear your cache between attempts (or use incognito windows each time).

Linker error on freshly brewed python install

May 18th, 2016
from PIL import Image
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/PIL/", line 119, in <module>
    import io
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 51, in <module>
    import _io
ImportError: dlopen(/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/, 2): Symbol not found: __PyCodecInfo_GetIncrementalDecoder
  Referenced from: /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/
  Expected in: flat namespace
 in /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/

Apparently this is happening because bash was still confused about which python to use after brew install python. I issued:

hash -r python

to fix the problem. But just using a new shell would also work.