Archive for April, 2010

Vi(m) tip #7: resize vertical split screen

Monday, April 19th, 2010

You can resize vertical split screen windows in vim using the following commands. To make the current window shrink in width (you can precede these with numbers):


<CTRL>+W <

and similarly to grow in width


<CTRL>+W >

To make the current window full width:


<CTRL>+W |

To return to equal widths


<CTRL>+W =

Single image iphone apps now work offline

Monday, April 19th, 2010

iphone image apps

Using a nice little tutorial about cache manifests, I’ve made it possible for my single image apps (and yours) to run offline. Which means if you save them to your home screen on your iphone or ipod touch (or ipad) you can access them even in the deepest subway platform of the seven train in manhattan.

marseille

Sunday, April 18th, 2010

marseille

http://alecjacobson.com/art/digital/
http://alecjacobson.com/art/

Positive ad campaign

Saturday, April 17th, 2010

There is a new ad campaign in the New York City subways. The ads feature sad or serious looking models and dismal color schemes. The text reads something suggestively depressing like, “I thought I was doing my job” or “I though life would be the same”. Then the punch line is “Abortion changes you”.

abortion changes you for the better

The ads expect you to complete the sentence “Abortion changes you for the worse.” But I thought, what would this ad look like if you completed the sentence the other way? So here’s my revision, taking the same words but implying a different meaning with the design.

abortion changes you for the better

Normalize list of vectors in MATLAB

Friday, April 16th, 2010

If a contains a list of row-vectors then you can normalize there lengths using the following:


normalized_a = a./repmat(sqrt(sum(a.^2,2)),1,3);

Erase item from list of pointers in C++ during iterator

Thursday, April 15th, 2010

In a C++ program, I have a std::list (actually std::vector) of pointers to a class Foo:


std::vector my_list;

Maybe I have push a bunch of items onto this list and then selected one (using my UI or whatever). Anyway there is a certain item in the list that points to an instance of Foo that has the is_selected flag flipped to true.

I want to implement a simple deleteSelected() function for this list. Here’s what I came up with (no guarantees, my C++ skills leave a lot to be desired):

bool deleteSelected(){
  bool deleted_some = false;
  std::vector<Foo*>::iterator my_list_iterator = my_list.begin();
  while(my_list_iterator != my_list.end();)
  {
    if((* my_list_iterator)->is_selected){
      // clear the memory of this item
      delete (* my_list_iterator);
      // erase from list, returns next element in iterator
      my_list_iterator = my_list.erase(my_list_iterator);
      deleted_some = true;
    }else{
      // otherwise, just increment the iterator
      my_list_iterator ++;
    }
  }
  return deleted_some;
}

Any reason why this isn’t correct?

Note: Erasing this way could lead to an O(N2) running time if many items are selected. How can this be avoided with a std::vector? (Erasing all of the items is trivial, I mean how can I erase a dense general set of items in the list in linear time)

Update: My friend told me that a better way to do this is with a decrementing index. Then when you erase using the index the items behind get moved but you’re already done processing them and since the index is going backwards it’s left in the right position. (This way is also arguably faster at least by a scale factor).

Open .cpp and .h files in vim with split screens

Thursday, April 15th, 2010

Here’s a little bash script I save in cvim.sh (apologies to chinese vim):


#!/bin/bash
base_name=`echo $1 | sed "s/\.$//g"`
vim -O2 $base_name.h $base_name.cpp

So the if I type:


./cvim.sh foo

vim opens foo.cpp and foo.h in split screen.

skin sample

Tuesday, April 13th, 2010

skin sample

http://alecjacobson.com/art/digital/
http://alecjacobson.com/art/

who’s got the crack

Monday, April 12th, 2010

who's got the crack

http://alecjacobson.com/art/digital/
http://alecjacobson.com/art/

Simple MATLAB slerp

Monday, April 12th, 2010

Interpolating between two vectors can catch you off guard. If you just linearly interpolate (x,y,z) values you could end up with a vanishing interpolated vector. Just imagine interpolating a 2-D vector from [-1,0] to [1,0]. Halfway you’ve got [0,0].

vector interpolation

One way to do this a little better is to interpolate a rotation between the vectors. The natural path to take is the shortest one which happens to also be the shortest path (of two unit vectors) of their respect points along the unit sphere. This is called spherical linear interpolation or slerp.

slerp

There’s more complicated ways to do this but in MATLAB I can simply do:


function [c] = slerp(a,b,t)
  angle = acos( dot(a,b) );
  % easy degenerate case
  if(0==angle)
    c = a;
  % hard case
  elseif(pi==angle) 
    error('SLERP: angle between vectors cannot be exactly PI...');
  else
    c = (sin((1.0-t)*angle)/sin(angle))*a + (sin(t*angle)/sin(angle))*b; 
  end
end

Note: that slerping is not well defined for opposite parallel vectors. This makes sense geometrically because their respective points on the unit sphere have infinitely many, all equally minimal paths between them. E.g. the north pole has infinitely many shortest paths along the earth to the south pole.

In the end, I lerp the magnitudes of the two vectors then use that to scale the slerp of their unit vectors:


c = ( (1.0-t) * norm(a) + t* norm(b) ) * slerp( a./norm(a) , b./norm(b) , t);

where t is your interpolation parameter.

Slightly more efficiently:


mag_a = norm(a); mag_b = norm(b); c = ((1.0-t)*mag_a + t*mag_b) * slerp(a./mag_a,b./mag_b,t);

Note: Careful using norm it is not vectorized as you might think. I.e. it doesn’t return a row vector of scalars if you pass it a list of vectors (instead the matrix norm of that list treated as a matrix).