Skip navigation

Category Archives: misc

Funky Inheritance

Or functor-based inheritance

Funky inheritance is my name for when you allow attachment of functors to specify behavior instead of always just subclassing.

This came up recently in some UI event handling code that I was writing. Buttons come and go, dialogs appear and get dismissed. Each dialog dismissal button (okButton) needs something specific to happen, but that same functionality is extremely unlikely to be reused in another dialog.

Normally, to write an object type that has customizable behavior (by a subclass), you would write a base class like this:

class Dialog
{
  virtual void onDismiss() = 0 ;
};

So, when you subclass Dialog, you override onDismiss to provide custom behavior that occurs when the dialog is dismissed (assume onDismiss would be invoked by a window manager).

class FileOpenDialog : public Dialog
{
  virtual void onDismiss()
  {
    // stuff to do when the FileOpenDialog is dismissed..
  }
};

So, that’s the regular (classical) inheritance pattern. Every time you want different functionality onDismiss(), you’d write a new subclass of Dialog. Another way to get custom code to run onDismiss is to allow onDismiss() to accept a functor that can be invoked …

class FileOpenDialog : public Dialog
{
  virtual void onDismiss( function <void ()> runThisAfter )
  {
    // stuff to do when the FileOpenDialog is dismissed..
    // then..
    runThisAfter() ;
  }
};

OR

You could write onDismiss as a functor in base class Dialog instead of using classical inheritance here:

class Dialog
{
  function< void (Dialog* that) > onDismiss ;
};

Now onDismiss is a functor (that may or may not be set).

So then customized behavior is by instance, not by class. Creating a FileOpenDialog object would then be like:

Dialog fileOpenDialog ;
fileOpenDialog.onDismiss = [](Dialog* that) {
  // Do something with `that`, which acts as `this`
  // if this were a member function ;)
} ;

When the window object handler finds out a dialog has been dismissed, it invokes the onDismiss handler if it has been set.

// It is detected that fileOpenDialog needs to be closed:
if( fileOpenDialog.onDismiss )
  fileOpenDialog.onDismiss( fileOpenDialog ) ;

// Above line manually passes `this`.
// If I am not mistaken, this is considered "Pythonic" (just kidding,
// but Python does require passing of self in a similarly visible fashion)

This may come across to you as very JavaScripty- or follow a prototypal inheritance pattern. But it actually isn’t prototypal inheritance, because objects do not inherit from other objects. Each instance of Dialog has its own behavior, that is not repeated by any other instance of Dialog.

Of course, this would need some more detail and fleshing out to really work. But this is the jist of funky inheritance. Regular inheritance is class-wide customization. Funky inheritance is instance-wide customization. Funky inheritance is great for when you need to define custom behavior (often one-off, for a button or a widget) without having to define an entire subclass.

Drawbacks of Funky Inheritance

Functors are unable to persist their own internal running state except as static variables. However statics inside a functor are inaccessible from outside the functor. This means modification of a functor’s internal values is difficult/impossible from outside the functor. So, that kind of sucks sometimes.

One way you can modify a functor’s internal state variables is to capture a pointer before entering the functor:

Object * someObject = new Object() ;
functor = [ someObject ]() {
  // now if someObject is modified outside the functor,
  // I will use "the most up to date" version of someObject.
} ;

Functors seem to be best used to send global state messages or somehow modify global state. For example, if a FileOpenDialog is modal, it may flip off the `modal` flag inside your window manager when it is dismissed. Functors are also useful to modify the object running the functor’s state as well.

GameCenter isn’t easy to work with. For one it’s networking, and networking errors are hard to debug because there’s no natural UI. debug print messages is all you’ve got. It doesn’t help that GC is none too detailed on what you did wrong, and sometimes weird errors can occur if you use the API incorrectly.

1. A match request by name can take up to 2 minutes to reach the remote device. Unprepared for this I’d just sit there trying the request again and again, wondering why it wasn’t working.

2. The iOS simulator doesn’t seem to work for GKMatchmaker requests. I don’t know why this is, but the iOS simulator cannot even startBrowsingForNearbyPlayersWithReachableHandler.

3.

I created an xml file with my newest XCode C++ theme.

It looks like this:

So, gray background, white text, all numeric constants and defines are kinda blue, classes are purple, and C preprocessor macros are red.

The factory pattern is most useful when an object type cannot and should not be used independently of some master managing class.

An analogy would be if you have a Theater as the "Master class" (factory) and the objects that are created in the factory are Tickets. So you have to ask the Master Theater class for a new Ticket() whenever you want one. The Master class can now remember that it has sold you a Ticket and that there is one additional Ticket in the system. Tickets aren’t useful at all if the ticket issuer disappeared. Notice this is much better than having a system where Tickets are created with no reference to a Theater, but then are registered to a theater after creation. That would be like "counterfeit your ticket, then call us and tell us you have a ticket to our Theater".

And so the factory pattern makes perfect sense here.

Objects make the most sense in the context of encapsulating code that:

  • Has some mandatory startup that must run (constructors), otherwise the related functions won’t work
  • Has a family of related functions, but not all of them should be called by the class user (private)
  • Has some cleanup routines that should be called when the user is done (destructor)

An example of this is my SecKeyHelper.h file I wrote today. That file is just C functions, but there is some code that must be called before any of the related functions work. On top of that, only 2 functions should really be called by the class user.

Public key loading, private key loading, it’s all very easy with OpenSSL on Linux. You must link the libcrypto.dylib library in XCode for this to work.

XCode 4.6 project download here

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
#include <openssl/pem.h>
 
// I'm not using BIO for base64 encoding/decoding.  It is difficult to use.
// Using superwills' Nibble And A Half instead 
// https://github.com/superwills/NibbleAndAHalf/blob/master/NibbleAndAHalf/base64.h
#include "base64.h"
 
// The PADDING parameter means RSA will pad your data for you
// if it is not exactly the right size
//#define PADDING RSA_PKCS1_OAEP_PADDING
#define PADDING RSA_PKCS1_PADDING
//#define PADDING RSA_NO_PADDING
 
RSA* loadPUBLICKeyFromString( const char* publicKeyStr )
{
  // A BIO is an I/O abstraction (Byte I/O?)
  
  // BIO_new_mem_buf: Create a read-only bio buf with data
  // in string passed. -1 means string is null terminated,
  // so BIO_new_mem_buf can find the dataLen itself.
  // Since BIO_new_mem_buf will be READ ONLY, it's fine that publicKeyStr is const.
  BIO* bio = BIO_new_mem_buf( (void*)publicKeyStr, -1 ) ; // -1: assume string is null terminated
  
  BIO_set_flags( bio, BIO_FLAGS_BASE64_NO_NL ) ; // NO NL
  
  // Load the RSA key from the BIO
  RSA* rsaPubKey = PEM_read_bio_RSA_PUBKEY( bio, NULL, NULL, NULL ) ;
  if( !rsaPubKey )
    printf( "ERROR: Could not load PUBLIC KEY!  PEM_read_bio_RSA_PUBKEY FAILED: %s\n", ERR_error_string( ERR_get_error(), NULL ) ) ;
  
  BIO_free( bio ) ;
  return rsaPubKey ;
}
 
RSA* loadPRIVATEKeyFromString( const char* privateKeyStr )
{
  BIO *bio = BIO_new_mem_buf( (void*)privateKeyStr, -1 );
  //BIO_set_flags( bio, BIO_FLAGS_BASE64_NO_NL ) ; // NO NL
  RSA* rsaPrivKey = PEM_read_bio_RSAPrivateKey( bio, NULL, NULL, NULL ) ;
  
  if ( !rsaPrivKey )
    printf("ERROR: Could not load PRIVATE KEY!  PEM_read_bio_RSAPrivateKey FAILED: %s\n", ERR_error_string(ERR_get_error(), NULL));
  
  BIO_free( bio ) ;
  return rsaPrivKey ;
}
 
unsigned char* rsaEncrypt( RSA *pubKey, const unsigned char* str, int dataSize, int *resultLen )
{
  int rsaLen = RSA_size( pubKey ) ;
  unsigned char* ed = (unsigned char*)malloc( rsaLen ) ;
  
  // RSA_public_encrypt() returns the size of the encrypted data
  // (i.e., RSA_size(rsa)). RSA_private_decrypt() 
  // returns the size of the recovered plaintext.
  *resultLen = RSA_public_encrypt( dataSize, (const unsigned char*)str, ed, pubKey, PADDING ) ; 
  if( *resultLen == -1 )
    printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
 
  return ed ;
}
 
unsigned char* rsaDecrypt( RSA *privKey, const unsigned char* encryptedData, int *resultLen )
{
  int rsaLen = RSA_size( privKey ) ; // That's how many bytes the decrypted data would be
  
  unsigned char *decryptedBin = (unsigned char*)malloc( rsaLen ) ;
  *resultLen = RSA_private_decrypt( RSA_size(privKey), encryptedData, decryptedBin, privKey, PADDING ) ;
  if( *resultLen == -1 )
    printf( "ERROR: RSA_private_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL) ) ;
    
  return decryptedBin ;
}
 
unsigned char* makeAlphaString( int dataSize )
{
  unsigned char* s = (unsigned char*) malloc( dataSize ) ;
  
  int i;
  for( i = 0 ; i < dataSize ; i++ )
    s[i] = 65 + i ;
  s[i-1]=0;//NULL TERMINATOR ;)
  
  return s ;
}
 
// You may need to encrypt several blocks of binary data (each has a maximum size
// limited by pubKey).  You shoudn't try to encrypt more than
// RSA_LEN( pubKey ) bytes into some packet.
// returns base64( rsa encrypt( <<binary data>> ) )
// base64OfRsaEncrypted()
// base64StringOfRSAEncrypted
// rsaEncryptThenBase64
char* rsaEncryptThenBase64( RSA *pubKey, unsigned char* binaryData, int binaryDataLen, int *outLen )
{
  int encryptedDataLen ;
  
  // RSA encryption with public key
  unsigned char* encrypted = rsaEncrypt( pubKey, binaryData, binaryDataLen, &encryptedDataLen ) ;
  
  // To base 64
  int asciiBase64EncLen ;
  char* asciiBase64Enc = base64( encrypted, encryptedDataLen, &asciiBase64EncLen ) ;
  
  // Destroy the encrypted data (we are using the base64 version of it)
  free( encrypted ) ;
  
  // Return the base64 version of the encrypted data
  return asciiBase64Enc ;
}
 
// rsaDecryptOfUnbase64()
// rsaDecryptBase64String()
// unbase64ThenRSADecrypt()
// rsaDecryptThisBase64()
unsigned char* rsaDecryptThisBase64( RSA *privKey, char* base64String, int *outLen )
{
  int encBinLen ;
  unsigned char* encBin = unbase64( base64String, (int)strlen( base64String ), &encBinLen ) ;
  
  // rsaDecrypt assumes length of encBin based on privKey
  unsigned char *decryptedBin = rsaDecrypt( privKey, encBin, outLen ) ;
  free( encBin ) ;
  
  return decryptedBin ;
}
  
 
 
int main( int argc, const char* argv[] )
{
  ERR_load_crypto_strings();  
  
  puts( "We are going to: rsa_decrypt( unbase64( base64( rsa_encrypt( <<binary data>> ) ) ) )" );
  // public key
  // http://srdevspot.blogspot.ca/2011/08/openssl-error0906d064pem.html
  //1. The file must contain:
  //-----BEGIN CERTIFICATE-----
  //on a separate line (i.e. it must be terminated with a newline).
  //2. Each line of "gibberish" must be 64 characters wide.
  //3. The file must end with:
  //-----END CERTIFICATE-----
  // YOUR PUBLIC KEY MUST CONTAIN NEWLINES.  If it doesn't (ie if you generated it with
  // something like
  // ssh-keygen -t rsa -C "you@example.com"
  // ) THEN YOU MUST INSERT NEWLINES EVERY 64 CHRS (just line it up with how I have it here
  // or with how the ssh-keygen private key is formatted by default)
  const char *b64_pKey = "-----BEGIN PUBLIC KEY-----\n"
  "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp2w+8HUdECo8V5yuKYrWJmUbL\n"
  "tD6nSyVifN543axXvNSFzQfWNOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6\n"
  "hsZA81AblAOOXKaUaxvFC+ZKRJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68Epn\n"
  "aOLepTZw+GLTnusQgwIDAQAB\n"
  "-----END PUBLIC KEY-----\n";
  
  // private key
  const char *b64priv_key = "-----BEGIN RSA PRIVATE KEY-----\n"
  "MIICXAIBAAKBgQCp2w+8HUdECo8V5yuKYrWJmUbLtD6nSyVifN543axXvNSFzQfW\n"
  "NOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6hsZA81AblAOOXKaUaxvFC+ZK\n"
  "RJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68EpnaOLepTZw+GLTnusQgwIDAQAB\n"
  "AoGBAKDuq3PikblH/9YS11AgwjwC++7ZcltzeZJdGTSPY1El2n6Dip9ML0hUjeSM\n"
  "ROIWtac/nsNcJCnvOnUjK/c3NIAaGJcfRPiH/S0Ga6ROiDfFj2UXAmk/v4wRRUzr\n"
  "5lsA0jgEt5qcq2Xr/JPQVGB4wUgL/yQK0dDhW0EdrJ707e3BAkEA1aIHbmcVfCP8\n"
  "Y/uWuK0lvWxrIWfR5MlHhI8tD9lvkot2kyXiV+jB6/gktwk1QaFsy7dCXn7w03+k\n"
  "xrjEGGN+kQJBAMuKf55lDtU9K2Js3YSStTZAXP+Hz7XpoLxmbWFyGvBx806WjgAD\n"
  "624irwS+0tBxkERbRcisfb2cXmAx8earT9MCQDZuVCpjBWxd1t66qYpgQ29iAmG+\n"
  "jBIY3qn9uOOC6RSTiCCx1FvFqDMxRFmGdRVFxeyZwsVE3qNksF0Zko0MPKECQCEe\n"
  "oDV97DP2iCCz5je0R5hUUM2jo8DOC0GcyR+aGZgWcqjPBrwp5x08t43mHxeb4wW8\n"
  "dFZ6+trnntO4TMxkA9ECQB+yCPgO1zisJWYuD46KISoesYhwHe5C1BQElQgi9bio\n"
  "U39fFo88w1pok23a2CZBEXguSvCvexeB68OggdDXvy0=\n"
  "-----END RSA PRIVATE KEY-----\n";
 
  // String to encrypt, INCLUDING NULL TERMINATOR:
  int dataSize=37 ; // 128 for NO PADDING, __ANY SIZE UNDER 128 B__ for RSA_PKCS1_PADDING
  unsigned char *str = makeAlphaString( dataSize ) ;
  printf( "\nThe original data is:\n%s\n\n", (char*)str ) ;
  
  // LOAD PUBLIC KEY
  RSA *pubKey = loadPUBLICKeyFromString( b64_pKey ) ;
  
  int asciiB64ELen ;
  char* asciiB64E = rsaEncryptThenBase64( pubKey, str, dataSize, &asciiB64ELen ) ;
   
  RSA_free( pubKey ) ; // free the public key when you are done all your encryption
  
  printf( "Sending base64_encoded ( rsa_encrypted ( <<binary data>> ) ):\n%s\n", asciiB64E ) ;
  puts( "<<----------------  SENDING DATA ACROSS INTERWEBS  ---------------->>" ) ;
  
  char* rxOverHTTP = asciiB64E ; // Simulate Internet connection by a pointer reference
  printf( "\nRECEIVED some base64 string:\n%s\n", rxOverHTTP ) ;
  puts( "\n * * * What could it be?" ) ;
  
  // Now decrypt this very string with the private key
  RSA *privKey = loadPRIVATEKeyFromString( b64priv_key ) ;
  
  // Now we got the data at the server.  Time to decrypt it.
  int rBinLen ;
  unsigned char* rBin = rsaDecryptThisBase64( privKey, rxOverHTTP, &rBinLen ) ;
  printf("Decrypted %d bytes, the recovered data is:\n%.*s\n\n", rBinLen, rBinLen, rBin ) ; // rBin is not necessarily NULL
  // terminated, so we only print rBinLen chrs
  
  RSA_free(privKey) ;
  
  bool allEq = true ;
  for( int i = 0 ; i < dataSize ; i++ )
    allEq &= (str[i] == rBin[i]) ;
  
  if( allEq ) puts( "DATA TRANSFERRED INTACT!" ) ;
  else puts( "ERROR, recovered binary does not match sent binary" ) ;
  free( str ) ; 
  free( asciiB64E ) ; // rxOverHTTP  
  free( rBin ) ;
  ERR_free_strings();
}

Rae Johnston posts about an experience in a Starbucks’ involving a Bioshock Infinite t-shirt.

I am not sticking up for that guy. He sounds like a loser. But I want to explain what I think is behind that behavior.

First of all reading her top tweets you can see she gets a lot of flack for being a girl gamer. That brings us to the first point:

Any guys that give girl gamers flack for being a girl are sexist guys period. They’re losers. The girl is on “their turf” so they subject her to bad treatment. Only losers do that and there’s no excuse for it.

Second is the encounter with that guy that got almost 10k retweets. The thing there is, there is already a bunch of internet memes about gamer girls who pretend to like games, only to get guys’ attention.

Also you have to keep in mind the shock value of hot girl gamers. Although this might not be true nerdy guys immediately think they have a shot at the nerdy hot girl. Because! Finally! A hot chick who digs the things I do. We’re on the same page! Blah blah blah.

He did a stupid thing calling you out rudely for the shirt. He was a moron. But these are just thoughts on what is going through nerds’ heads.

I can never find this when I’m looking for it, so I dedicated a whole blog post to it.

Here.

The easiest way I’ve found to generate a random alphanumeric string involves RAND(), SHA(), and TO_BASE64()

select LEFT( TO_BASE64( SHA(rand()) ), 6 ) ;

You need MySQL 5.6 to execute.

Alternatively some MYSQL Procedures magic

DELIMITER //

drop function if exists randChr //
create function randChr()
returns char
BEGIN
  IF RAND() <= 0.5 THEN -- Lowercase
	return CHAR( 97 + 25*rand() ) ;
  ELSE -- uc
    return CHAR( 65 + 25*rand() ) ;
  END IF;
END //

drop function if exists randString //
create function randString( len int )
returns varchar(255)
BEGIN
  SET @n = 0;
  SET @res = '' ;
  REPEAT
    SET @res = concat( @res, randChr() ) ;
    set @n = @n + 1 ;
  UNTIL @n >= len END REPEAT;
  return @res ;
END //

DELIMITER ;

select randString( 5 );

Starting from my previous program (Windows), connecting in Mac OS X is even EASIER, only there are a couple’a gotchas.

To code with MYSQL in Mac OS X, just install MySQL normally. In fact it comes with the `/include` and `/lib` folders when you installed it. They are in `/usr/local/mysql` (which is a link to the specific version you have).

Ok, now that’s done, here’s your C++ program:

#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/mysql/include/mysql.h"

MYSQL mysql;    // MYSQL global
MYSQL * conn ;  // represents connection to database

int main()
{
  mysql_init( &mysql ) ;
  
  //   http://dev.mysql.com/doc/refman/5.0/en/mysql-real-connect.html
  conn = mysql_real_connect(  &mysql,
                              "localhost",// synonymous with 127.0.0.1
                              "root",     // connect as user="root".  Uh, bad security here..
                              "",         // my root password is blank.  REALLY bad security :)
                              "mysql",    // connect to the 'mysql' _database_ within MySQL itself.
                               0, 0, 0 ) ;
  
  // Check if connection succeeded.
  if( !conn )
  {
    printf( "Couldn't connect to MySQL database server!\n" ) ;
    printf( "Error: %s\n", mysql_error( &mysql ) ) ;
    return 1 ;
  }
  //else  puts( "Connect success" ) ;
  
  // Here, we are connected.
  // form a sql string to execute.
  if( mysql_query( conn, "select * from user" ) )
  {
    printf("Whoops!  The query failed.  Error:  %s\n", mysql_error( conn ) );
    return 1 ;
  }

  // here, query succeeded, so we can proceed to pull out results.
  MYSQL_RES * resultset ;
  MYSQL_ROW row;  // MYSQL_ROW is #defined as (char **)
  // Data ALWAYS comes back from MySQL as
  // an array of strings.  To convert it
  // to ints or whatever is YOUR JOB as the programmer.

  // mysql_store_result basically fetches
  // the entire array of results and dumps them
  // into our local program memory space (all
  // in the resultset variable.
  resultset = mysql_store_result( conn );

  // How many rows will there be?
  my_ulonglong numRows = mysql_num_rows( resultset ) ;
  printf( "There are %llu ROWS (records) of data\n", numRows ) ;
  
  // Now tell me what columns there are
  // in the result set.
  int numFields = mysql_num_fields( resultset ) ;
  printf( "There are %d FIELDS (columns) of data\n", numFields ) ;

  // Print all those column by name
  MYSQL_FIELD * fields = mysql_fetch_fields( resultset ) ;
  for( int i = 0 ; i < numFields ; i++ )
  {
    printf( "%25s", fields[i].name ) ;
  }

  printf( "\n" ) ;
  // print all results
  while( (row = mysql_fetch_row( resultset )) )
  {
    // row is 2d array of char
    // underlying type is char **
    for ( int i = 0; i < numFields ; i++ )
      printf( "%5s", row[ i ] ) ;
    
    puts( "" ) ;    // next row
  }
  
  mysql_free_result( resultset );  // Now free the result
  mysql_close( conn ) ;  // And close down.
  return 0;
}


GOTCHA #1: An easy one, but you need to link up your TARGET with the libmysqlclient.a library file. So goto your TARGETS / BUILD PHASES tab, under “Link Binary With Libraries” go select “libmysqlclient.a” from /usr/local/mysql/lib.
GOTCHA #2: This is the stupid one, COPY /usr/local/mysql/lib/libmysqlclient.18.dylib to /usr/lib/. ISN’T THAT DUMB??? Well it’s the eq of copying a DLL to C:\Windows\System32 on Windows. Just something you have to do.

If you don’t copy the .dylib you’ll get Library not loaded: libmysqlclient.16.dylib reason: image not found.

The easiest.

1. Mac OS X

sudo apachectl start

Make sure cgi is enabled in your Apache settings

sudo vi /etc/apache2/httpd.conf

Create and build the following:

#include <stdio.h>

int main(int argc, const char * argv[])
{
  //puts( "HTTP/1.1 200 OK" ) ;
  puts( "Content-Type: text/plain; charset=UTF-8" ) ;
  puts( "Status: 200 OK" ) ;
  puts( "" ) ;
  puts( "HELLO INTERNET" ) ;
}

The default folder Xcode 4.6 dumps the exec in is

/Users/YOURUSERNAME/Library/Developer/Xcode/DerivedData/PROJECTNAME-andabunchofrandomcharacters/Build/Products/Debug/PROJECTNAME

Take the exec (called PROJECTNAME) and drop it into:

/Library/WebServer/CGI-Executables/

hit http://localhost/cgi-bin/YOUREXECNAME

It should say HELLO INTERNET.

You are on your way to C++ internet freedom

I simulated some game results. In the sim, Player 2 was so bad, he was 0 for 680. The ranking algorithm ranked him first though, because he sucked so bad, he kept on losing increasingly large quantities of negative points for each match he lost.

It is possible! This table shows it as a sort of nested table.

All you have to do to achieve glow in pixelmator:

1) Take an image

2) Duplicate the layer (Make sure View/Show Layers is on, then Right click/Duplicate)

3) View / Show Effects must be on. From the little Effects window, choose Gaussian Blur. Make it something like 10-15px of blur radius. Your duplicate layer should look like that:

4) Under Blending in your Layers dialog select LINEAR DODGE, then drag the opacity to get your desired level of glow. Make sure the blurred texture appears ON TOP of the original.

5) The result should look something like that

You could compute them using factorials, but this is far more efficient.

// Computes n CHOOSE k
// ( n )
// ( k )
int binomial( int n, int k )
{
  // must accumulate nums/dens separately
  // to avoid roundoff error
  int nums = 1;
  int dens = 1;
  for( int i = 1 ; i <= k ; i++ )
  {
    nums *= ( n - k + i ) ;
    dens *= i ;
  }
  return nums/dens ;
}

//test
int p=7;
for( int i = 0  ; i <= p ; i++ )
  printf( "%dx^%d +", binomial(p, i), p-i ) ;
puts("");

Delegate: A person sent or authorized to represent others
Delegation

First, DELEGATE is problematic. It’s not a common word, and most people don’t know what it means, and beyond that it’s NOT CLEAR what it means in a software context. It’s a bad metaphor.

The use of the word DELEGATE is different than in C#. A delegate in C# is just a function pointer. A DELEGATE in Objective-C is an OBJECT that implements a bunch of functions (very similar to overriding methods in inheritance), BUT THESE FUNCTIONS AREN’T OVERRIDING FUNCTIONS IN A BASE CLASS. Instead, they are implementing A “PROTOCOL” (not a C++ programming concept, its an objective-c concept). OC PROTOCOLS are like C++ INTERFACES (abstract base classes), only weirder. Delegate classes contain just a bunch of stubs of functionality that would get called by the default Apple UIApplication object, if that object respondsToSelector, for example.

Some Foundation Framework classes are like big assholes, like UIApplication for example. They go about their business in a VERY routine way, and WHEN THEY FEEL LIKE IT, they “delegate” little tasks out to YOUR DELEGATE OBJECT. When you program with Foundation classes, you provide that itty-bitty, gopher-boy, go-do-what-I-said, shoe-shine, lackey-boy, I-have-no-money-please-help-me-sir object (called a DELEGATE). The big king UIApplication Foundation class WILL CALL YOUR DELEGATE WHEN THE TIME COMES.

So your little shitty delegate just implements willDoStep3 here, and arguments may be passed by Framework object. UIApplication has a bunch of points at which it “needs” a delegate to call: applicationDidFinishLaunching, applicationWillResignActive, etc.

So app delegation is like fake inheritance. In normal inheritance, you would OVERRIDE applicationDidFinishLaunching, and provide your own method stub. In Objective C, you “provide a delegate object that implements a protocol”. It is conceptually almost the same thing.

I don’t understand why Apple decided to invent this new language and concepts of protocols and delegates, when C++’s concepts of interfaces and inheritance do just fine.


As an example of implementing a delegate protocol, let’s implement GKMatchDelegate. All the information you need is in the documentation there.

// SFMatchDelegate : inherits from NSObject< Implements GKMatchDelegate protocol >
@interface SFMatchDelegate : NSObject< GKMatchDelegate >
{
}

// any @property here

@end



// Usually in another file:
@implementation SFMatchDelegate

//any @synthesize statements

// "override"/implement protocol "Tasks"

//Receiving Data from Other Players
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
}

//Receiving State Notifications About Other Players
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state
{
}

//Handling Errors
- (void)match:(GKMatch *)match didFailWithError:(NSError *)error
{
}

//Reinviting a Player
- (BOOL)match:(GKMatch *)match shouldReinvitePlayer:(NSString *)playerID
{
  return YES ;
}

@end

They play a game of odds.  ”If we sell lots of shitty product at a cheap price, with 1/5 dead, then we make money b/c 1/5 will buy the dead product and customers won’t want to pay $15 to return a $20 item.”

 

 

Here is my ray sphere intersection code. Pay special attention to the __6__ possible results for the ray’s situation wrt the sphere.

bool Sphere::intersectExact( const Ray& ray, Intersection* intn )
{
  // an important override

  //If E is the starting point of the ray,
  //.. and L is the end point of the ray,
  //.. and C is the center of sphere you're testing against
  //.. and r is the radius of that sphere

  // Compute:
  //    d = L - E ; // Direction vector of ray, from start to end
  //    f = E - C ; // Vector from center sphere to ray start
  const Vector &d = ray.direction ;
  Vector f = ray.startPos - this->pos ;

  real a = d • d ;  // a is nonnegative, this is actually always 1.0
  real b = 2*(f • d) ;
  real c = f • f - radius*radius ;

  real discriminant = b*b-4*a*c;
  if( discriminant < 0 )
  {
    return false ;  // no intersections.
    // the geometric meaning of this is
    // the ray totally misses the sphere.
  }
  else
  {
    // ray didn't totally miss sphere,
    // so there is a solution to
    // the equation.

    discriminant = sqrt( discriminant );
    // just t1 here implies t1 VALID (ie 0 ≤ t1 ≤ len)
    // 3x HIT cases:
    //       -o->       --|-->  |            |  --|->
    // Impale(t1,t2), Poke(t1,t2>len), ExitWound(t1<0, t2), 
    
    // 3x MISS cases:
    //       ->  o                     o ->              
    // FallShort (t1>len,t2>len), Past (t1<0,t2<0)
    
    // | -> |
    // CompletelyInside(t1<0, t2>len)

    // You might consider CompletelyInside a HIT, but I consider it a miss here.
    // t1 is always the smaller value, because BOTH discriminant and
    // a are nonnegative.
    real t1 = (-b - discriminant)/(2*a);
    real t2 = (-b + discriminant)/(2*a);

    // Just purely sphere info
    if( BetweenIn(t1,0,ray.length) )
    {
      // t1 is the intersection, and its closer
      // Impale, Poke
      Vector p = ray.at( t1 ) ;
      if( intn )  *intn = Intersection( p, getNormalAt( p ), this ) ;
      return true ;
    }

    // here t1 didn't intersect so we are either started
    // inside the sphere or too 
    if( BetweenIn( t2,0,ray.length ) )
    {
      // ExitWound
      Vector p = ray.at( t2 ) ;

      // We invert the normal because you are inside the sphere.
      if( intn )  *intn = Intersection( p, -getNormalAt( p ), this ) ;
      return true ;
    }

    return false ; // no intn: FallShort, Past, CompletelyInside
  }
}

There is this misleading marketing tactic used by coffee vendors, to sell you _dark_ roasted coffee as “stronger” coffee. Dark coffee is often labelled “robust”. The truth about “dark coffee”, which I’ll admit I didn’t know before:

1) DARK is a reference to HOW COOKED it is. Very dark coffee is very, very burnt.

(image from here)

2) There are tons of varieties of beans, but you can make dark and light coffee from the same original bag of beans. “Dark” coffee does not come from a “darker bean”. (In fact original coffee beans are always green).
3) You need higher quality beans to make and sell a light roast.

Companies like kicking horse coffee, seem to market dark roast as “more hardcore”. “454 horse power”, “Grizzly Claw”, “Hoodoo Jo”, and yes, even “KICK ASS!”, are all dark roasted coffees sold by them. More apt names would be names like “Volcanic”, “Pumice”, “Supernova”, and “Total Destruction”.

In fact, dark roasting burns away some of the caffeine (so there’s less caffeine in dark roasts, NOT more as “KICK ASS!” or “454 horse power” might have you think at first).

So the point is, there’s this misleading notion everywhere (with respect it’s not all coffee vendor’s faults.. but most people just don’t know)

Yes, in my opinion, dark roasting all but destroys the bean. I have started to believe coffee companies just want to sell more bean by selling off the crappy dark roast. Also DARK ROAST MAKES ME TIRED. I drink a lot of coffee and if I have 2 cups of dark roast, I won’t have nearly the same energy I will have if I drink 2 same “strength” cups of light roast.

So you wanna MEL script, do you?

But you don’t want to learn MEL scripting? And you don’t want to read about it??

Fortunately, MAYA is very cleverly built. It turns out that EVERY UI action you do with the mouse, turns into a MEL script command, which MAYA then executes.

So here’s how you can generate your own MEL script for your own tedious task.

1) Open the script editor

Now try something. Select an object with your mouse. You should see pop into that “script editing” dialog a line like:

select -r pSolid1 ;

That, sir, is the MEL script command to “select” an object. Namely, the object that you just clicked on with your mouse.

So, carefully click through ALL the actions that you need to do your tedious task. Copy and paste each MEL script action into your own MEL script.

You may need to tweak it a bit to get it to work in the end, but it is a quick and easy way to LEARN MEL scripting, as well as generate the correct MEL script for the task you want.

The basic steps are:

1) set up your model and textures / scene for baking
2) right click the object to bake, choose baking/assign new bake set…
3) set up the parameters for baking as you like. to re-edit them, right click the object, then select baking/edit attributes/texture…

Baking a texture out WITH alpha is hard. Even though maya lets you select HDR, TIF, and TGA as bake texture formats.. when you go to open the texture in photoshop, the alpha channel is black, not 0 alpha. Even though your resultant texture will have an alpha.. I think there is a flaw in the maya export process. Anyway, so to KEEP the alpha, you go RENDERING (menu) / Lighting/Shading / Batch Bake (mental ray).

The file will be output in whatever format you chose in the Baking Set options in C:\Users\YOURUSERNAME\Documents\maya\projects\default\renderData\mentalray\lightMap, but THAT file will have 0 alpha pixels as BLACK, not 0 alpha. So ignore that file, it is useless. Go to Hypershade/Textures tab, and find the texture starting with baked_.. That is your baked texture. RIGHT CLICK IT AND SELECT TEST TEXTURE. SAVE THAT as PNG.

And that is the only way I found to save the alpha channel in a Maya baked texture.

Just a link to this, probably the best one I’ve seen

This is a makeString() function that works like printf(). Gives you a std::string from a printf()’d one, so you can stop using sprintf() all the time and NEVER use ostringstream!

string makeString( const char *fmt, ... )
{
  va_list args ;
  va_start( args, fmt ) ;
  char msgBuffer[ 4096 ] ; // max len.  Can also use a strlen call to avoid over alloc
  vsprintf( msgBuffer, fmt, args ) ;
  return string( msgBuffer ) ;
}

I want to believe iteration style doesn’t make a difference as much as the next guy, but the fact is, it does.

In order, performance goes

For std::vector:
integer indexing FASTER THAN range based for FASTER THAN traditional iterators

For std::list:
range based for FASTER THAN traditional iterators

You can quote me on that. A test below proves it with a simple example.




#include <stdio.h>
#include <vector>
#include <list>
using namespace std ;

/////#include "Timer.h" // TIMER.h pasted below
#include <sys/time.h>

struct Timer
{
  timeval start ;
  
  Timer() { reset(); }
  
  void reset() {
    gettimeofday( &start, NULL ) ;
  }
  
  double getTime() const {
    timeval end ;
    gettimeofday( &end, NULL ) ;
    
    return end.tv_sec - start.tv_sec + (end.tv_usec - start.tv_usec)/1e6 ;
  }
  
} ;


struct O{
  int a ;
  float b;
  
  O( int ia, float ib ):a(ia),b(ib){}
  
  void print()
  {
    printf( "%d %f\n", a,b ) ;
  }
  
  void doIt()
  {
    a++;
    b++;
  }
} ;

int TESTS = 10000000 ;

int main(int argc, const char * argv[])
{
  vector os ;
  
  os.push_back( O(2, 2.2 ) ) ;
  os.push_back( O(3, 3.3 ) ) ;
  os.push_back( O(4, 4.4 ) ) ;
  
  Timer t ;
  
  t.reset() ;
  for( int i = 0 ; i < TESTS ; i++ )
  {
    for( vector::iterator iter = os.begin() ; iter != os.end(); ++iter )
    {
      iter->doIt();
    }
  }
  printf( "TRADITIONAL ITERATOR : %f\n", t.getTime() ) ; // 0.755 sec
  
  t.reset() ;
  for( int i = 0 ; i < TESTS ; i++ )
  {
    for( O& entry : os ) // note: if you pass by value, it's even faster
    {
      entry.doIt();
    }
  }
  printf( "NEWFANGLED RANGE BASED for : style Time %f\n", t.getTime() ) ; // 0.493 sec
  
  
  t.reset();
  for( int i = 0 ; i < TESTS ; i++ )
  {
    for( int j = 0 ; j < os.size() ; j++ )
    {
      os[j].doIt();
    }
  }
  printf( "INTEGER INDEXING Time %f\n", t.getTime() ) ; // 0.243 sec
  
  
  
  
  
  
  return 0;
}

Edit Mesh / Add Divisions .. will cut a polygonal mesh into uniform squares.

After that, you can triangulate.

Here’s a C++ function:

// Little endian (little end/lsb first)
inline UInt32 RGBA( Byte R, Byte G, Byte B, Byte A )
{
  return A<<(3*8) + B<<(2*8) + G<<(8) + R ; //LE
  //return R<<(3*8) + G<<(2*8) + B<<(8) + A ; //BE
}

What’s wrong with it?. Why doesn’t it return the correct value? Try and guess! No cheating!

Is it the bitshifting being wrong? No, that’s right

Is it that R, G, B, and A are Byte type, and Byte overflows? Nope, they are automatically promoted to int.

So guess what it is? GUESS!

YOU KNEW IT!! OPERATOR PRECEDENCE!

Bitshift has a precedence lower than +. So the shifting is off (and by WAY too much in most cases!)

// Little endian (little end/lsb first)
inline UInt32 RGBA( Byte R, Byte G, Byte B, Byte A )
{
  return (A<<(3*8)) + (B<<(2*8)) + (G<<(8)) + R ; //LE // works
  // You could also change to bitwise OR, which has lower prec than +
  return A<<(3*8) | B<<(2*8) | G<<(8) | R ; //LE // works
}

So you dug out your old webcam. Want to take some pictures of food.

Well guess what. You can’t.

Even if you find the old Dynex CD and install it, Creative Live! center shows you that. (It is plugged in, BTW).

Just buy a new camera. 1.3MP wasn’t that good anyway.

What a stupid dialog.

View / pixel aspect ratio correction should be __unchecked__

You can, but it doesn’t work exactly as you’d expect.

To make the “rotate axis” _keyable_, you do this:

Once it’s keyable, it appears in your channel box

Sure you can now key the rotate axis.. but like I said it doesn’t work as you’d expect. The value I have entered there is 260.. but if you increase it to 300, it automatically changes to -60! How annoying.

there is the hard way, or you can use illustrator format.

Note that if you use too new a version of Illustrator, it doesn’t work. You get:

// Error: Command illustratorCurves failed. Open Script Editor for details.

Just save it as ILLUSTRATOR 3 and it will definitely work. FILE / SAVE AS .. (pick a name), THEN another dialog appears with a dropdown.

In Maya 2009, you can use up to ILLUSTRATOR 8 format, but ILLUSTRATOR 9 doesn’t work (for me anyway).

Well it turns out when you create a Newton field, and try to click the object you want it to affect, then “Fields/Affect selected object(s)” , that didn’t work, for me.

I get:

// Error: Please select the particle objects to be connected for emission or collision, or the particle objects/rigid bodies to be connected to fields.

 

So I solved this by selecting the fluid first, then creating the force via Fields/Newton.  Delete those other bad forces that don’t want to affect selected.

I had this fun problem this morning.  In the Render View:  Options / Test Resolution / Render Settings (and not that “Camera Panel” poison)

Orange lines in Maya mean you have “soft select” on.

Before this happened, you probably remember clicking on something like this:

To get to that dialog go here

Soft select is like “area of effect” select and manipulation. For example, with the curve I have there, scaling a face affects an _area_ of faces around it:

But you probably just want to turn it off! (Click the checkbox beside “Soft select” off)

So easy!

Just follow the instructions here.

All I did was Create / Polygon Primitives / Platonic Solids,

Then select at the right side in the channel box “Icosahedron”

Then Mesh / Smooth to add more polygons

I had this seemingly inane threading bug:

this was a multithreading bug that appeared when the cubemap object got destroyed (early) by another thread.

by the time this thread entered the if statement, the cubeMap variable was gone (set to 0 by another thread in the same object)

If you have 3 vectors, right, up, and forward, you can write a ROW MAJOR change of basis matrix as follows:

  [       right.x     right.y     right.z   ]
  [          up.x        up.y        up.z   ]
  [    -forward.x  -forward.y  -forward.z   ]

The new basis in terms of the original basis are the ROWS of this change-of-basis matrix.

This matrix takes any vector with (1,0,0), (0,1,0), (0,0,1) as its OLD basis vectors, and rotates it so that its new basis vectors ARE right,up,forward as given.

A viewing matrix is the transpose of the change of basis matrix, because a viewing matrix “pushes the world away” from a stationary camera. (The viewing matrix isn’t going to _move the camera_, instead it moves the whole world so that the portion you want to see sits in the canonical viewing volume).

To make this column major

Just transpose it.

Arbitrary axis angle rotation C++ code, ROW MAJOR

/// Arbitrary axis angle rotation
Matrix Matrix::Rotation( const Vector & u, real radians )
{
  real c = cos( radians ) ;
  real l_c = 1 - c ;

  real s = sin( radians ) ;
  
  //ROW MAJOR
  return Matrix(
    u.x*u.x + (1 - u.x*u.x)*c,      u.x*u.y*l_c + u.z*s,        u.x*u.z*l_c - u.y*s,  0,
          u.x*u.y*l_c - u.z*s,  u.y*u.y+(1 - u.y*u.y)*c,        u.y*u.z*l_c + u.x*s,  0,
          u.x*u.z*l_c + u.y*s,      u.y*u.z*l_c - u.x*s,  u.z*u.z + (1 - u.z*u.z)*c,  0,
                            0,                        0,                          0,  1
  ) ;
}

Arbitrary axis angle rotation C++ code, __COLUMN__ MAJOR

/// Arbitrary axis angle rotation
Matrix Matrix::Rotation( const Vector & u, real radians )
{
  real c = cos( radians ) ;
  real l_c = 1 - c ;

  real s = sin( radians ) ;
  
  //COLUMN MAJOR
  return Matrix(
    u.x*u.x + (1 - u.x*u.x)*c,      u.x*u.y*l_c - u.z*s,        u.x*u.z*l_c + u.y*s,  0,
          u.x*u.y*l_c + u.z*s,  u.y*u.y+(1 - u.y*u.y)*c,        u.y*u.z*l_c - u.x*s,  0,
          u.x*u.z*l_c - u.y*s,      u.y*u.z*l_c + u.x*s,  u.z*u.z + (1 - u.z*u.z)*c,  0,
                            0,                        0,                          0,  1
  ) ;
}

GPU style: do both, then throw away the one you don’t want.

Overarchitecting is overplanning for things you don’t know the system will need or planning for things you don’t understand that you think the system needs.

When will programmers realize that the over-emphasis (Java-style) on the use of classes, with every variable as a class-level variable, is just moar globals!! ?

* A class is just a mini program
* class-members in a large program with many classes are equivalent to globals in a smaller program (with a single class)
* you still have to use locals correctly
* just because it’s a class doesn’t mean overusing class members is ok

Being a programmer today is like being a diamond in a sea of diamonds. There are so many of us out there.
But finding a good programmer is like finding an IF diamond, where most of us are at least SI-2.


Image from here

Don’t forget to key a std::map, you must overload operator< Maps use binary search and insertion defaults to being in-order!

Friend classes in C++: In C++ a friend is allowed to touch your privates.

C++: public inheritance: everybody knows who your parents are. private inheritance: You are ashamed of your parents so nobody knows that you even have a parent class.

Oct 11 2012 12:49pm

Experimenting is the only way you know your assumptions are wrong.

Oct 15 2012 1:47pm

.push_back() into an STL vector is not necessarily slower than .push_back() into an STL list. Even though you would think it should be ;).

Oct 16 2012 7:26pm

C preprocessor is the original duck typing

static is C’s private

Jan 4 2013

NEVER return references to entries (ie &theAddressOf) in a <vector> of value-types. return &vec[2] and storing that value as a pointer is a no no. If you push_back into the vector, all the references you took earlier may become invalidated. Always use simple integer indices into a <vector>, or better yet use a vector of pointer types (where that makes sense to do).

Jan 26 2013

Overloading is overrated. (Not always, but sometimes). Is having 4 methods named intersects in your mesh class easier to read, or is naming them intersectsSphere, intersectsBounds, intersectsTri better?

Jan 26 2013

Marking a member function const is for when that member function call should have no change on the state of the object, neither now nor further down the line. If a const member function wants to return a pointer to a member inside the object, then that member function should not be labelled const, because that pointer is a key to making changes to the object further down the line.

constify member functions only when the member function being called is a prostitute and the code calling the “prostitute” is a married politician. Neither the caller nor the callee want the rest of society to know what went down in that function, so no record is kept. The prostitute agrees that the politician will have no lasting impact on her internal state (ie she will not talk about the affair). const on a member function means “this call never happened, and nothing changed inside the prostitute, nor will anything _ever_ change inside the prostitute anywhere down the line as a result of the politician’s call”

A bit of a long one, but hey, it involved prostitutes.

Feb 7 2013

If you delete the front node of a <list> while reverse iterating, list.rend() changes. list.rend() is not “one past the end” as list.end() would be.

Mar 3 2013

If I had a dollar every time I realized this. There are 6 cases to consider when doing ray sphere intersections: 1) Fall short 2) Entry 3) Impale 4) COMPLETE CONTAINMENT (which usually is mistakenly counted as a miss) 5) Exit wound 6) Past. Usually ppl only check for Entry,Impale and Exit, but CONTAINMENT must also be considered a “hit” (short ray inside large sphere))

Mar 21 2013

Never use M_2_PI from <math.h>. It is 2/PI, NOT 2*PI like you’d expect.

Mar 21 2013 11:28p

Crazy numbers like 8589934592 are almost certainly OOB problems.
Can you spot the potential OOB problem in the line below?

for( int i = 0 ; i < pts.size(); i++ )
  nextPts.push_back( pts[i+i].pos + Matrix3f::rotation( alongLine, angle )*perpLine*r ) ;

The i+i was supposed to be i+1! Oops!

Mar 26 2013 11:58a

The ternary operator precedence level is VERY low!

int a = 5 + 1 ? 2 : 3 ;

The result for a is always 2. Why? because evaluation is happening as:

int a = (5 + 1) ? 2 : 3 ;

5+1=6 turns into TRUE, then the result is 2.

To make it evaluate properly, you would need

int a = 5 + (1 ? 2 : 3) ;

Mar 30 2013 11:32p

When naming multiple variables that have to do with the same thing, with similar names, such as playerVel for the player’s velocity and enemyVel for the enemy’s velocity, always put the different part first, not last. So never use a naming convention like velPlayer and velEnemy. It makes it far too easy to interchange the variables, especially when the similar string is long (for example, rollAccel and rollAccelRadar. I know of this rule and I just mistakenly used rollAccel where I wanted to use rollAccelRadar).

Apr 1 2013 3:26p

acos and asin on Mac are different than on PC.
acos( 1.0 + 1e-38 ) is nan on Mac because the arg is OOB strict domain of acos [-1,1]
This is not an April Fool’s joke.

Apr 10 2013 1:19a

Never use Google App Engine. Always use Amazon EC2 + RDS AWS instead.

Apr 24 2013 11:41p

Why encapsulate? It’s IMPOSSIBLE to remember all the implementation details of how a cohesive bunch of code works — even if you wrote it 3 weeks ago. THAT’S the reason for encapsulation. It says “Don’t fuck with this, it’s self managing”.

Apr 25 2013 1:19a

The factory pattern is most useful when an object type cannot and should not be used independently of some master managing class.

Fri May 3 2013 9:27p

Avoid remove_if for std::vector. It is rat poison, not syntactic sugar.

Use the following idiom for removal from a std::vector instead

for( vector<TYPE>::iterator iter = vec.begin() ; iter != vec.end() ; )
if( iter->shouldRemove )
  iter = vec.erase( iter ) ; // advances iter
else
  ++iter ; // don't remove

UI is 90% of a game.


Bobobobo’s links to non-bobobobo boboboboisms

8 things web designers should keep in mind

Wacom replacement nibs are actually hard to find at reasonable prices in Canada.

For one, most of the dealers are in the US, so there’s really high shipping costs.

Anyway, I’ve found one of the best places to buy wacom tablet nibs is DIRECTCANADA. The secret to buying there is BUY OVER $50 OF GOODS AND YOU GET FREE SHIPPING.

So for example, here I’ve filled my cart with $50.09 of nibs. Magically, the shipping cost goes down from $20 to $0.00.

The best nibs for the 12WX and 21UX (the pens that come with both of those devices use the same nibs) are:

I learned this from this guy, but this is just a super short, clean simple bare class that loads a single file (called “explode1.caf”). Adapt it to your needs.

// SoundMan.h
@interface SoundMan : NSObject

- (void) loadSound: (NSString*) name ;
- (void) genTestSound ;
- (void) playSound ;

@end

// SoundMan.mm
@implementation SoundMan

  ALCcontext *alC ;
  ALCdevice *alD ;
  NSUInteger sourceId ;
  NSUInteger soundBufferId ;
  
  - (id) init
  {
    if( self = [super init] )
    {
      // initializes openal
      alD = alcOpenDevice(NULL);
      if( alD )
      {
        alC = alcCreateContext( alD, NULL ) ;
        alcMakeContextCurrent( alC ) ;
        
        // Generate a test sound
        [self genTestSound] ;
      }
    }
    
    return self ;
  }
  
  - (void) genTestSound
  {
    alGenSources( 1, &sourceId );
    
    // Load explode1.caf
    NSString *path = [[NSBundle mainBundle] pathForResource:@"explode1" ofType:@"caf" ];

    AudioFileID fileID ;
    NSURL *afUrl = [NSURL fileURLWithPath:path];
    
    // NON zero means err
    if( AudioFileOpenURL((__bridge CFURLRef)afUrl, kAudioFileReadPermission, 0, &fileID) )
      printf( "cannot open file: %s", [path UTF8String] ) ;
      
    UInt32 fileSize = [self audioDataSize:fileID];
    unsigned char *outData = (unsigned char*)malloc(fileSize);
    if( AudioFileReadBytes(fileID, FALSE, 0, &fileSize, outData) )
    {
      printf( "Cannot load sound %s", [path UTF8String] );
      return;
    }
    AudioFileClose(fileID);
    	
    alGenBuffers(1, &soundBufferId);
    alBufferData( soundBufferId, AL_FORMAT_STEREO16, outData, fileSize, 44100 );
    
    free( outData ) ;
  }
  
  - (void) playSound
  {
    // set source
    alSourcei( sourceId, AL_BUFFER, soundBufferId ) ;
    
    alSourcef( sourceId, AL_PITCH, 1 ) ;
    alSourcef( sourceId, AL_GAIN, 1 ) ;
    alSourcei( sourceId, AL_LOOPING, AL_FALSE ) ;
    
    ALenum err = alGetError();
    if( err ) // 0 means no error
      printf( "ERROR SoundManager: %d", err ) ;
    else
      alSourcePlay( sourceId );
  }
  
  - (UInt32) audioDataSize:(AudioFileID)fileId {
    UInt64 dataSize = 0;  // dataSize
    UInt32 ps = sizeof(UInt64); // property size
    if( AudioFileGetProperty(fileId, 
        kAudioFilePropertyAudioDataByteCount, &ps, &dataSize) )
      puts( "error retriving data chunk size" );
    return dataSize ;
  }
  

@end


Here is how you draw in latex in 3d using tikz




\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,3d}
\begin{document}

\section{3d picture}

\begin{tikzpicture}
% style of faces
\tikzset{facestyle/.style={fill=lightgray,draw=red,very thin,line join=round}}
% how to draw a polygon
\draw[fill=green,draw=orange,opacity=1.0,thin,line join=round]
 (0,0,0) -- 
 (1,0,0) --
 (1,1,0) --
 (0,1,0) -- cycle ;

\draw[fill=blue,draw=orange,opacity=1.0,thin,line join=round]
 (0,0,0) -- 
 (0,0,1) --
 (0,1,1) --
 (0,1,0) -- cycle ;

\draw[fill=red,draw=orange,opacity=1.0,thin,line join=round]
 (0,0,0) -- 
 (1,0,0) --
 (1,0,1) --
 (0,0,1) -- cycle ;

\draw[fill=purple,draw=orange,opacity=1.0,thin,line join=round]
 (1,0,0) -- 
 (1,0,1) --
 (0,1,1) --
 (0,1,0) -- cycle ;
\end{tikzpicture}


\end{document}




You must not insert additional returns. Extra newlines will ruin the table. If you need a space use

%

on the line (so it becomes a comment, not just a newline)

\usepackage{ctable}

\ctable[cap = {TABLE CAPTION},caption = {ninny},label={idiottable},]{cc}
{
  % You specify table footnotes here.
  \tnote[$\ast$]{DA FOOTNOTE 1}
  \tnote[$\dagger$]{dat other footnote}
  \tnote[b]{mistakes are possible (you must match these up yourself)}
}{
\FL % FLORIDA (just kidding, means "first line")
COL 1\tmark[a] & COL 2\tmark[$\ast$]
\ML % middle line
6.920e+00\tmark[$\dagger$]     &   0.09781\\
97     &   2000
\LL % last line
}

These are things that I tend to forget between times I use

3ds max

– To rotate the view, ALT+Middle Mouse. If it isn’t working as you expect, your camera pivot is probably too far
– Move tool: W, Rotate Tool: E, Scale Tool: R, if they aren’t working as you expect (manipulator looks wrong), PRESS X to fix it.
– To zoom in and out use []

Blender
– To select an object, RIGHT click
– Middle mouse rotates view, Ctrl+Middle Mouse zooms
– Z toggles wireframe

Maya
– CTRL+A shows the attribute editor

So, this post talks about cosine weighted hemisphere sampling.

Really its simple.

There are 2 ways to do this, both are outlined in Philip Dutre’s “Total Compedium”

Way #1
– generate points on the disk
– project points upward

Way #2
– Use these explicit formulae.

//generate 2 random floats, each between 0 and 1
RANDOM_NUMBER_1 = randFloat() ; 
RANDOM_NUMBER_2 = randFloat() ; 

PHI(aziumthal angle) = 2*PI*RANDOM_NUMBER_1 ;
THETA (elevation angle) = acos( sqrt( RANDOM_NUMBER_2 ) ) ;

That’s it! This is what you get:

I didn’t initialize the filename member:

GetOpenFileName fails if you do _not_ write a blank string to ofn.lpstrFile

Be sure to

 

sprintf( ofn.lpstrFile, “” ) ;

 

before calling OpenFileName

A simple template, to find the minimum of 3 numbers.

Can you find the bug in this code?

  template<typename T> inline T min3( const T& a, const T& b, const T& c )
  {
    if( a < b && a < c )  return a ;
    else if( b < a && b < c ) return b ;
    else return c ;
  }

Hint: Actually I’m not going to give you any hints. But it is possible for the above function to return the incorrect value.

Sibernik Cathedral

(Download links dead), now available on web archive: .max | 3ds | lp

SPONZA ATRIUM

I got an AMD FX-8150 chip in a new PC build.

_It sucks._ It’s no better than the AMD 1090T, which incidentally was taken _off_ the market by AMD. Now I know why. The 1090T performs very similarly (with no overclocking at all, either chip) to the “new” AMD 8 core.

I was already using an AMD 1090T to do parallel raytraces. I thought I’d get a second machine as a workhorse. Built one for $500. Shoulda gone with Intel. I’m running the same raytrace in parallel, one on this machine (which I’m also using to write this post) and I’m leaving the FX 8150 alone. The FX 8150 spawned 8 threads to raytrace on (7 for raytracing and 1 for the UI) because 8 cores were detected, here on the 1090T only 5 raytracing threads are running, +1 for the UI thread.

So far they are neck and neck, even though I am using this machine to write this post. The FX 8150 machine has completed 119/300 jobs (each “job” is 2 800 pixel long rows), this machine 117/300 jobs. Totally terrible. I expected _some sort_ of improvement, with a 400 MHz faster clock speed and 2 extra cores, but you get absolutely nothing.

It’s the SAME core as the 1090T, far as I’m concerned.

Further proof

So, there’s always this question of “what’s the difference between rotate THEN translate VS translate THEN rotate”?

DOES TRANSLATION VS ROTATION ORDER MATTER?

__YES IT DOES__.

If you do ROTATE THEN TRANSLATE, the effect is __spinning in place__, because ROTATE about axis first (we are still @ origin), then translate OUT to some point in space.

ROTATE THEN TRANSLATE, produces SPINNING effect


If you do TRANSLATE THEN ROTATE, the effect is __ORBITING__ around an axis, because it translates you OUT FIRST, away from the origin, then you rotate that new further point about the origin:

TRANSLATE THEN ROTATE, produces ORBITING effect


Follow

Get every new post delivered to your Inbox.

Join 34 other followers