Archive for November, 2011

eddie o’dowd

Saturday, November 26th, 2011

eddie o'dowd

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

Self-compiling .cpp file

Thursday, November 17th, 2011

I often put compilation notes in the comments at the top of small .cpp programs. These are just reminders to me of the flags I need to set in g++ to compile the program. For bigger programs I use Xcode or Makefiles, but often if I’m just testing a small idea I don’t want that overhead. I had a funny idea today that my .cpp file could act as both a bash script and as C++ code. Then I could execute the .cpp file (as a bash script) which would set up the compiler and then compile itself. Here’s a proof of concept, save this in main.cpp

#!/bin/bash
//usr/bin/tail -n +2 $0 | g++ -o main -x c++ - && exit
#include <cstdio>
int main(int argc,char * argv[])
{
  printf("Hello, world\n");
  return 0;
}

Make it executable with chmod +x main.cpp

To compile just execute the cpp file:

./main.cpp

This creates the real binary of the program which you can execute with:

./main

Update: If you don’t like the hassle of making the binary you can just run the binary right after you compile it, then delete it immediately. Do this by changing the second line to:

#!/bin/bash
//usr/bin/tail -n +2 $0 | g++ -o main -x c++ - && ./main && rm main && exit
#include <cstdio>
int main(int argc,char * argv[])
{
  printf("Hello, world\n");
  return 0;
}

Update: With an additional hack you can have a full fledged bash script at the top of your .cpp file:

#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT
printf "//" | cat - $0 | g++ -o .main -x c++ - && ./.main $@
rm -f .main
# END BASH SCRIPT
exit
*/
#include <cstdio>
int main(int argc,char * argv[])
{
  printf("Hello, world\n");
  return 0;
}

Update: Here’s another one I found especially useful. This allows me to pipe the output to colormake to get colorized terminal compiler output.

#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT 
export PS4=""
set -o xtrace       
printf "//" | cat - $0 | g++ -o .main -x c++ - && ./.main $@
rm -f .main         
# END BASH SCRIPT
exit
*/
#include <cstdio>
int main(int argc,char * argv[])
{
  printf("Hello, world\n");
  return 0;
}

Then I pipe the output to colormake using:

./main.cpp 2>&1 | colormake.pl

Update: Yet another one. This time works with the debugger.

TEMP=”$0.cpp” printf “//” | cat – $0 >$TEMP

#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT 
source ~/.profile
export PS4=""
set -o xtrace       
printf "//" | cat - $0 | 
g++ -g -O0 -std=c++11 -o .main $TEMP && \ 
/Applications/Xcode.app/Contents/Developer/usr/bin/lldb -b -o r ./main -- "$@"
rm -f .main         
# END BASH SCRIPT
exit
*/
#include <cstdio>
int main(int argc,char * argv[])
{
  printf("Hello, world\n");
  return 0;
}

Update: I edited the above to include source ~/.profile. Seems with El Capitan Mac OS 10.11 the DYLD_FALLBACK_LIBRARY_PATH setting is not persistent when call a script from vim.

max schmeling overcome

Thursday, November 17th, 2011

max schmeling overcome

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

2D rotation matrix plus another 2D rotation matrix is a similarity matrix (scaled 2D rotation)

Wednesday, November 16th, 2011

Consider we have two rotation matrices:


R1 = / cos(θ1) -sin(θ1) \
     \ sin(θ1)  cos(θ1) /

R2 = / cos(θ2) -sin(θ2) \
     \ sin(θ2)  cos(θ2) /

Then we can show that:


R1 + R2 = s * R3

where s is a scalar and R3 is another 2D rotation.

First we just add the components to get:


R1 + R2 = / cos(θ1)+cos(θ2)   -(sin(θ1)+sin(θ2)) \
          \ sin(θ1)+sin(θ2)    cos(θ1)+cos(θ2)   /

Notice we already have the right pattern:


R1 + R2 =  / A -B \
           \ B  A /

we just need to show that we can pull out a common scaling term and angle from A and B.

We can use trigonometric identities to turn the sums of cosines and the sums of sines into products, namely:


cos(θ1)+cos(θ2) = 2*cos((θ12)/2)*cos((θ12)/2)
sin(θ1)+sin(θ2) = 2*sin((θ12)/2)*cos((θ12)/2)

Now we declare that:


s = 2*cos((θ12)/2)
θ3 = (θ12)/2

Then it follows that:


R1 + R2
  =
  / s*cos((θ12)/2)  -s*sin((θ12)/2) \
  \ s*sin((θ12)/2)   s*cos((θ12)/2) /
  =
  s * / cos(θ3)  -sin(θ3) \
      \ sin(θ3)   cos(θ3) /
  = 
  s * R3

More useful ease curves

Wednesday, November 16th, 2011

The simplest ease function and the easiest to remember is a cubic:


3*t.^2-2*t.^3

For even better continuity at the corners we could use a fifth order:


10*t.^3 - 15*t.^4 + 6*t.^5

Of course we could always just compose smooth, ease functions to get higher order ones. For example composing the cubic gives:


3*(3*t.^2-2*t.^3).^2-2*(3*t.^2-2*t.^3).^3

So far the ease curves have been symmetric on either side of t=0.5, a useful asymmetric curve is half of a uniform biplane basis function rescaled to fit in the unit square. This one is a piecewise cubic:


2*t.^3                 .* (t<0.5) + ...
(1-6*t+12*t.^2-6*t.^3) .* (t>=0.5)

Notice how I use multiplication against a logical to construct piecewise functions in matlab.

To see them in action use:


t = linspace(0,1,100);
plot( ...
  t,3*t.^2-2*t.^3, ...
  t,10*t.^3 - 15*t.^4 + 6*t.^5, ...
  t,3*(3*t.^2-2*t.^3).^2-2*(3*t.^2-2*t.^3).^3, ...
  t,2*t.^3                 .* (t<0.5) + ...
    (1-6*t+12*t.^2-6*t.^3) .* (t>=0.5), ...
  'LineWidth',2 ...
);

third, fifth and ninth order ease curves and half a uniform bspline basis function

The nice legend is created with:


nl = @(s) strrep(s,'\n',char(10));
legend({ ...
  '3t^2-2t^3', ...
  '10t^3-15t^4+6t^5', ...
  nl('3u^2-2u^3\nu = 3t^2-2t^3'), ...
  nl('2t^3                           t<0.5\n1-6t+12d^2-6t^3     t>=0')}, ...
  'FontName','FixedWidth', ...
  'Location','NorthWest', ...
  'FontSize',11);

An earlier post about ease curves

New lines in matlab, figure legends and elsewhere

Wednesday, November 16th, 2011

I tried naively to use \n in a matlab string hoping that it would come out as the newline character:


a = 'first\nsecond'

But you just get literally the 2 characters, \ and n in your string.


a =

first\nsecond

You code filter your string through sprintf:


b = sprintf('first\nsecond')

which gives you the newline:


b =

first
second

But this would cause problems if your string happened to contain any of the other sprintf symbols, like %, resulting in missing characters or errors:


sprintf('percentage\n90%')

Puts in the newline but removes the % sign:


ans =

percentage
90

Instead, it’s best to use the character code for the new line directly:


c = ['first' char(10) 'second'];

Concatenating strings in matlab is clunky but the newline shows up correctly without any side effects:


c =

first
second

You could easily make a simple replacement function that finds any \n sequences and replaces them with char(10)s with the following:


nl = @(s) strrep(s,'\n',char(10));

Then use your new function nl on your original string with \n to get the newline without worrying about concatenating:


d = nl('first\nsecond');

producing


d =

first
second

Re-sort using second output of sort in Matlab

Tuesday, November 15th, 2011

Matlab’s sort function gives you a secondary output which can be used to resort your matrix. If you’re sorting each row of an m by n matrix V then:


[SV,I] = sort(V,2);

gives you the m by n indexing matrix I which for each rows tell the ordering of V needed to produce the corresponding row in SV

To reproduce the sort of the entire matrix again you can use


reSV = V(sub2ind(size(V),repmat(1:size(V,1),size(V,2),1)',I));

united states of puerto rico

Monday, November 14th, 2011

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

List of United States, list of European Union states ordered by descending population

Monday, November 14th, 2011
California
Texas
New York
Florida
Illinois
Pennsylvania
Ohio
Michigan
Georgia
North Carolina
New Jersey
Virginia
Washington
Massachusetts
Indiana
Arizona
Tennessee
Missouri
Maryland
Wisconsin
Minnesota
Colorado
Alabama
South Carolina
Louisiana
Kentucky
Oregon
Oklahoma
Puerto Rico
Connecticut
Iowa
Mississippi
Arkansas
Kansas
Utah
Nevada
New Mexico
West Virginia
Nebraska
Idaho
Hawaii
Maine
New Hampshire
Rhode Island
Montana
Delaware
South Dakota
Alaska
North Dakota
Vermont
Washington, DC
Wyoming
Germany
France
United Kingdom
Italy
Spain
Poland
Romania
Netherlands
Portugal
Greece
Belgium
Czech Republic
Hungary
Sweden
Austria
Bulgaria
Denmark
Slovakia
Finland
Ireland
Lithuania
Latvia
Slovenia
Estonia
Cyprus
Luxembourg
Malta

detrás

Friday, November 11th, 2011

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