You Are Here Home > C/C++

C/C++

Animation Curves and Tweening; Understanding Animation Curves

These equations are by Robert Penner, you can find a document here that explains this in much greater detail:
http://www.robertpenner.com/easing/

The correct linear tween function looks like this:

float linear_tween(float t, float start, float end)
{
    if (t > 1.0f) return end;
    return t * end + (1.0f - t) * start;
}

t is the time since the start of animation started and it has to be between 0 and 1, start and end are the values that you want to interpolate between them…

To understand this equation you can so something very simple, assume start is 1 and end is 20, then at timestep 0 you will have:

0 * end + (1 – 0) * start => start

At time step 1 which is the end of your animation you get:

1 * end + (1 – 1) * start => end

And all the values between these are going to be interpolated linearly.

Now quadratic ease in function is where the changes in interpolated value are smaller in the beginning and larger at the end, how can we achieve this? We can do it by faking the time steps, if you we could somehow make it so that the time steps would look smaller to the linear tween function at the start of the animation and larger at the end, then we would achieve this, that way, in the beginning, the time steps look smaller so the function will change the value by just a little bit but at the end, the time steps look larger so the function will change the value by a larger amount.

The way to do this is very easy, the fact that the time step number is clamped to between 0 and 1 will help us in this case and this is the solution:

float quadratic_easein(float t, float start, float end)
{
    if (t > 1.0f) return end;
    return linear_tween(t * t, start, end);
}

When we multiply the time step by itself the numbers that are less than one get smaller, for example if you are at the time step 1/10th of a second:

1/10 * 1/10 => 1/100
2/10 * 2/10 => 4/100 (3/100 change)
3/10 * 3/10 => 9/100 (5/100 change)
4/10 * 4/10 => 16/100 (7/100 change)

8/10 * 8/10 => 64/100
9/10 * 9/10 => 81/100 (17/100 change)

Now let’s look at quadratic_easeout:

float quadratic_easeout(float t, float start, float end)
{
    if (t > 1.0f) return end;
    return linear_tween(2 * t - t * t, start, end);
}

Deriving 2*t – t*t is very easy knowing the fact above; to do this we need to reverse what happens above so we can do something:

t = 1 – t;

Now 1/10 becomes 9/10 so when we do:

t = t * t

The numbers are going to change more at the beginning of the time step but the problem is that now we converted 1/10 to 9/10 and t*t will result in 81/100 and that’s the end of our time step and the animation will play backwards, to fix it we need to do:

t = 1 – t

One more time so then 81/100 becomes 19/100, now let’s simplify this:

1 – t => 1 – t * t => 1 – ((1 – t) * (1 – t)) => 1 – (1 – t – t + t * t) => 2 * t – t * t

I hope this helps :)

Animation Curves and Tweening; Understanding Animation Curves
Comments (1)   Filed under: C Programming,C/C++,Mac,Objective-C,OpenGL   Posted by: Codehead

SQLite And The Problem Of Storing Long Long Integers

Recently, I was trying to store a very large integer value in a SQLite column, it didn’t matter wether I used INTEGER or UNSIGNED BIG INT, SQLite rounded it for me and I was left with an integer value that wasn’t even close to what I needed.

So one solution was to just use a VARCHAR or TEXT or event a BLOB and insert the number with quotes around it but guess what? SQLite did it again!!!

It turns out that SQLite tries to convert your values to ints to give you some benefits with sorting and comparing etc. – in case you didn’t know you really wanted an int rather than a BLOB – and that happens here in one of it’s functions:

/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information.  In other words, if the string
** looks like a number, convert it into a number.  If it does not
** look like a number, leave it alone.
*/
static void applyNumericAffinity(Mem *pRec){
  if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
    double rValue;
    i64 iValue;
    u8 enc = pRec->enc;
    if( (pRec->flags&MEM_Str)==0 ) return;
    if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
    if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
      pRec->u.i = iValue;
      pRec->flags |= MEM_Int;
    }else{
      pRec->r = rValue;
      pRec->flags |= MEM_Real;
    }
  }
}

The solution to this issue is to prepend a 0 to your number and use a BLOB or TEXT type column and insert it like this: ’0THEVERYLARGENUMBER’

Don’t get me wrong, SQLite is a great library that I’ve been using, it’s very well tested and works great, it’s fast and thread safe, I specially like it’s licensee:

/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************

I hope this helps…

SQLite And The Problem Of Storing Long Long Integers

C: Determining Size Of a Malloced C Pointer At Runtime

There is no direct/cross-platform way of doing this but you could do something cool, you could do what malloc does… (Although malloc stores more data than this)

Say you want to allocate a chunk that is 100 bytes and you want to somehow attach this size to it, so you can check the size anytime later on, what you do is this: you allocate 100 bytes + sizeof(size_t) and then store the size of this chunk which is 100 at the beginning of the chunk, then you return the address of the chunk starting right after the 100:

struct chunk_header {
    size_t size;
};
 
 void *my_malloc(size_t size)
{
    size_t header_size = sizeof(struct chunk_header);
    size_t alloc_size = header_size + size;
    void *chunk = malloc(alloc_size);
    struct chunk_header *header;
    if (!chunk)
        return NULL;
    header = (struct chunk_header *) chunk;
    header->size = alloc_size; /* Or just size, it's up to you... */
    return (char *) chunk + header_size; /* char * hack, go look it up... */
}

Later on, you can check the size like so:

size_t header_size = sizeof(struct chunk_header)
void *chunk = (char *) p - header_size;
struct chunk_header *header = (struct chunk_header *) chunk;
printf("This chunk of memory is: %d bytes...\n", (int) header->size);
C: Determining Size Of a Malloced C Pointer At Runtime
Comments (1)   Filed under: C Programming,C/C++   Posted by: Hamid

C: Set An Entire Array Of Pointers To NULL

Apparently you can’t use memset() to do this:

memset(the_pointer, '0', sizeof(the array));

This will set all the bits in the array to zero but 0 is not guaranteed to be the representation of a NULL pointer so this might be true:

if (the_pointer_array[10] != NULL) {}

You must loop through and set them one by one…

C: Set An Entire Array Of Pointers To NULL
Comments (0)   Filed under: C Programming,C/C++   Posted by: Hamid

OpenGL ES: Unbinding Vertex Buffer Objects – VBOs

I couldn’t find this mentioned anywhere online, but the solution is very easy:

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

I hope this helps!

OpenGL ES: Unbinding Vertex Buffer Objects – VBOs
Comments (1)   Filed under: C Programming,C/C++,OpenGL   Posted by: Codehead

A Tiny MySQL++ Tutorial; C++ and MySQL; MySQL++ Example

I wrote a post about how to install MySQL++ and I thought I will write a quick tutorial on how to use it too.

This is a very basic MySQL++ program and it’s very self explanatory:

#include <mysql++.h>
#include <stdlib.h>
 
using namespace std;
using namespace mysqlpp;
 
int main() {
    try {
        Connection conn(false);
        conn.connect("DB NAME", "DB HOST probably localhost", "DB USER", "DB PASS");
        Query query = conn.query();
    } catch (BadQuery er) { // handle any connection or
        // query errors that may come up
        cerr << "Error: " << er.what() << endl;
        return -1;
    } catch (const BadConversion& er) {
        // Handle bad conversions
        cerr << "Conversion error: " << er.what() << endl <<
                "\tretrieved data size: " << er.retrieved <<
                ", actual size: " << er.actual_size << endl;
        return -1;
    } catch (const Exception& er) {
        // Catch-all for any other MySQL++ exceptions
        cerr << "Error: " << er.what() << endl;
        return -1;
    }
 
    return (EXIT_SUCCESS);
}

This will connect to your database and creates a query object ready to go. Save this as test.cpp

To compile this, you will have to create a Makefile in the same folder, so create a file and name it “Makefile” (no quotes) and add these to it:

CXX := g++
CXXFLAGS := -I/usr/include/mysql -I/usr/local/include/mysql++
LDFLAGS := -L/usr/local/lib -lmysqlpp -lmysqlclient -lnsl -lz -lm
EXECUTABLE := main
 
all: test
 
clean:
	rm -f $(EXECUTABLE) *.o

If you get funny errors, make sure there are no extra spaces in this file, and there is only one “tab” behind the line: rm -f $(EXECUTABLE) *.o

Now, you can make and run this by doing:
make
./test

Now, I’m going to show you how to execute some queries and you can go ahead and experiment on your own tables.

Here is a INSERT query followed by a SELECT; this will hopefully cover a lot, because INSERT is a type of query that doesn’t return anything and you need to escape values in order to INSERT.
SELECT on the other hand returns rows, although there are 3 ways that they can be done but here is a simple way that works for me.

#include <mysql++.h>
#include <stdlib.h>
 
using namespace std;
using namespace mysqlpp;
 
int main() {
    try {
        Connection conn(false);
        conn.connect("DB NAME", "DB HOST probably localhost", "DB USER", "DB PASS");
        Query query = conn.query();
 
        /* To insert stuff with escaping */
        query << "INSERT INTO some_table " <<
                     "VALUES (" <<
                     "'', " << /* This is left empty because the column is AUTO_INCREMENT */
                     "\"" << escape << some_var_that_contains_some_value << "\"" <<
                     ");";
        query.execute();
        /* That's it for INSERT */
 
        /* Now SELECT */
        query << "SELECT * FROM biz LIMIT 10";
        StoreQueryResult ares = query.store();
        for (size_t i = 0; i < ares.num_rows(); i++)
           cout << "Name: " << ares[i]["name"] << " - Address: " << ares[i]["address"] << endl;
 
        /* Let's get a count of something */
        query << "SELECT COUNT(*) AS row_count FROM biz";
        StoreQueryResult bres = query.store();
        cout << "Total rows: " << bres[0]["row_count"];
 
    } catch (BadQuery er) { // handle any connection or
        // query errors that may come up
        cerr << "Error: " << er.what() << endl;
        return -1;
    } catch (const BadConversion& er) {
        // Handle bad conversions
        cerr << "Conversion error: " << er.what() << endl <<
                "\tretrieved data size: " << er.retrieved <<
                ", actual size: " << er.actual_size << endl;
        return -1;
    } catch (const Exception& er) {
        // Catch-all for any other MySQL++ exceptions
        cerr << "Error: " << er.what() << endl;
        return -1;
    }
 
    return (EXIT_SUCCESS);
}

Again, whenever you want to run your code do:
make
./test

I wrote this because something like this would help myself a lot.

Good Luck :)

Update

query.reset();

Will reset the query object; this is useful when you are (in your program) generating a MySQL query but must discard it and generate another query (based on some condition).

A Tiny MySQL++ Tutorial; C++ and MySQL; MySQL++ Example
Comments (18)   Filed under: C/C++,MySQL,Programming   Posted by: Codehead

Installing MySQL++; How to install MySQL++ on Linux-CentOS

There is a lack of documentation on how to do this, I guess they assume that you must know a lot IF you are trying to use this library.

But here are step by step instructions on how to do it.

What you need
Root access to your server.
An SSH client, like putty, it’s free.

Let’s do it
1 – Run your SSH client and connect to your server using root.

2 – Do:

cd /

Note: I always make a folder like this

mkdir Tools
cd Tools

Note: This is version 3.0.9 obviously, it’s best if you check this web page and download the latest source code: http://www.tangentsoft.net/mysql++/

wget http://www.tangentsoft.net/mysql++/releases/mysql++-3.0.9.tar.gz
tar xvfz mysql++-3.0.9.tar.gz
cd mysql++-3.0.9
./configure
make
make install

3 – Now, in order for:

#include <mysql++.h>

To work, you will have to add a line to your ld.so.conf; you will find this file (hopefully) in /etc so go to:
/etc
And edit ld.so.conf and add this line to the end of it:
/usr/local/lib

Note: If ld.so.conf is not in /etc you can try “whereis ld.so.conf” (no quotes)

Save it and run:

ldconfig

And you are all set.

Please also note that, this worked on my CentOS and might not work exactly like this on your distribution.

Installing MySQL++; How to install MySQL++ on Linux-CentOS
Comments (4)   Filed under: C/C++,MySQL,Programming   Posted by: Codehead