Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
Ephphatha
Posts: 625
Joined: Sat Sep 02, 2006 9:03 am UTC
Location: Bathurst, NSW, Australia

Re: Coding: Fleeting Thoughts

Postby Ephphatha » Tue Jul 13, 2010 4:56 pm UTC

I was going to post this in the IT DOESN'T WORK thread, but it works. I just want to understand why. Skip to the last paragraph if you want to ignore the boring bits. Yes, I know using this-> is unnecessary, but I find it's a helpful reminder of what variables are member functions and is cleaner than naming everything m_*.

---------

Can someone edumacate me on the intricacies of emulating a camera in OpenGL? Every example I've found says "Just use gluLookAt()" or "Just store rotation angles around certain axis' and call glRotate3f(xRot, 1.0, 0.0, 0.0); etc.". I found the glh library and ripped their glhLookAt function to see what it was doing inside then figured I'd do the same basic thing, so I have this camera class.

Code: Select all

class Camera
{
public:
    Render();

    CalculateView();

    //Snip

protected:
    Vector3 position, up, right, forward;
    glFloat view[16];
};

Camera::Render()
{
    glMultMatrixf(view);
    glTranslate(-position.x, -position.y, -position.z);
}

Camera::CalculateView()
{
    this->forward.Normalise();
    this->right = this->forward.Cross(this->up);
    this->right.Normalise();
    this->up = this->right.Cross(this->forward);
    this->up.Normalise();

    this->matrix[0] = this->right.x;
    this->matrix[4] = this->right.y;
    this->matrix[8] = this->right.z;
    this->matrix[12] = 0.0f;
    //------------------
    this->matrix[1] = this->up.x;
    this->matrix[5] = this->up.y;
    this->matrix[9] = this->up.z;
    this->matrix[13] = 0.0f;
    //------------------
    this->matrix[2] = -(this->forward.x);   // Why is this negated?
    this->matrix[6] = -(this->forward.y);
    this->matrix[10] = -(this->forward.z);
    this->matrix[14] = 0.0f;
    //------------------
    this->matrix[3] = this->matrix[7] = this->matrix[11] = 0.0f;
    this->matrix[15] = 1.0f;

    return;
}


So I understand that in order to emulate moving the camera away from an object, I move the object away from the camera (hence the translate by -position). I don't understand what I should actually be doing with the view matrix. Assume at the moment that I want to look down the -z axis, with +y up and +x right (which is a edit: right hand co-ordinate system and is what OpenGL uses, right?). When the camera is created, forward = (0, 0, -1), up = (0, 1, 0), and right = (1, 0, 0) (then gets set to that again after the orthonormalisation process). From just doing a simple test all movement is correct, and Pitch/Yaw works fine (don't have roll control programed/couldn't be fucked adding it). But why is the forward vector, and only the forward vector negated?

Edit: Because it is. An identity matrix in OpenGL represents a camera with the above axes, so the forward vector needs to be negated in order to yield that output from the input.
Last edited by Ephphatha on Thu Jul 15, 2010 11:53 am UTC, edited 2 times in total.
I'm not lazy, I'm just getting in early for Christmas is all...

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jul 13, 2010 5:43 pm UTC

Is there any convenient way of configuring C and/or C++ (gcc and g++) to use a foreign newline convention? Say if I'm writing network code on a Linux machine, then native newline convention says that std::endl and "\n" = 0x0a but almost all network protocols has "\n" = 0x0d 0x0a. And "\r\n" is a lot of meaningless work.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Tue Jul 13, 2010 11:30 pm UTC

Sort of. Newline conventions are left as implementation-defined by the standard. On Windows for example, C++ IO streams which are opened in text mode will usually automatically convert "\n" to "\r\n". std::endl will also insert "\r\n" instead of just "\n". You can set binary mode when opening your stream to prevent this.

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Re: Coding: Fleeting Thoughts

Postby elminster » Wed Jul 14, 2010 7:16 am UTC

I fking love regular expressions.
They make replacing crappy* copy/pasted code bearable and 100x faster.

*By crappy I mean, brain meltingly horrible. Although I'm not the best at writing regex, it works just fine for this purpose but far from optimal:

Code: Select all

(Done in visual studio) Find all "if:b*\(\(msX:b*\>=*:b*sX:b*\+:b*{[^)]+}\):b*&&:b*\(msX:b*\<=*:b*sX:b*\+:b*{[^)]+}\):b*&&:b*\(msY:b*\>=*:b*sY:b*\+:b*{[^)]+}\):b*&&:b*\(msY:b*\<=*:b*sY:b*\+:b*{[^)]+}\)\)", Regular expressions, Subfolders,"Entire Solution"
...
Matching lines: 430
//Matches code like: if ((msX > sX + 35) && (msX < sX + 220) && (msY > sY + 95) && (msY < sY + 120))

Yes, seriously... they did every mouse position check in the game I'm working on (Originally made circa 2000) like that. What's worse is that for every button they did it once in the draw function and once in the click handler.
Image

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Wed Jul 14, 2010 10:42 am UTC

I don't get how something as difficult to program as a PC game can still be plagued by people with that level of ineptitude.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
Rippy
Posts: 2101
Joined: Sun Jul 22, 2007 11:27 pm UTC
Location: Ontario, Can o' Duh

Re: Coding: Fleeting Thoughts

Postby Rippy » Wed Jul 14, 2010 1:38 pm UTC

So if I've got a union of pointers, and one of them points to allocated memory, and I then want to free that memory, what's the best approach? I feel like there must be a better way than coding a case for each possible possible value of the union (which is what I've got right now).

User avatar
TNorthover
Posts: 191
Joined: Wed May 06, 2009 7:11 am UTC
Location: Cambridge, UK

Re: Coding: Fleeting Thoughts

Postby TNorthover » Wed Jul 14, 2010 2:06 pm UTC

Rippy wrote:So if I've got a union of pointers, and one of them points to allocated memory, and I then want to free that memory, what's the best approach? I feel like there must be a better way than coding a case for each possible possible value of the union (which is what I've got right now).

In C you can probably just free one of them and it will work for the other cases. There may be restrictions if you're under some weird (ancient?) system with near and far pointers, but otherwise all free gets is a void* anyway and the standard probably guarantees that unions of pointers are fairly sane.

Under C++ the right destructor has to be called. The best solution is probably some refactoring so that a union isn't involved, but exactly how depends on the details.

User avatar
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Wed Jul 14, 2010 11:32 pm UTC

Assuming all your pointed-to-objects are PODs, you can just call delete[] or free in C++ too, and it'll probably work. You're deep in the lands of undefined behaviour either way.

User avatar
Pesto
Posts: 737
Joined: Wed Sep 05, 2007 5:33 pm UTC
Location: Berkeley, CA

Re: Coding: Fleeting Thoughts

Postby Pesto » Wed Jul 14, 2010 11:56 pm UTC

I'm able to listen to and comprehend podcasts while coding, but not while writing or reading emails.

Similarly, I'm able to listen to and comprehend podcasts while doing sudoku, but not crosswords.

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Re: Coding: Fleeting Thoughts

Postby elminster » Thu Jul 15, 2010 12:39 am UTC

I've said this before but, more monitor space would be so nice for coding. I'd expect it's one of those things that really benefit from dual monitor setups. Wonder what 2 vertically aligned 1080p monitors would be like.

I don't suppose anyone happens to know if there's a way to pass a member function pointer that takes 2 or more arguments? Isn't really important but I done the following which works only 1 argument, but can't find any one that would take an arbitrary number of arguments:

Code: Select all

std::bind1st(std::mem_fun(&SomeClass::MemberFunct), this)
//pass and stored as
std::tr1::function<void (/*argument type*/)>


headprogrammingczar wrote:I don't get how something as difficult to program as a PC game can still be plagued by people with that level of ineptitude.

Trust me, it's worst than you imagine.

Spoiler:
Let me put it another, despite having a fully made game which at it's peak at several thousand player online at once, they had code that had things like using goto as break and continue replacements. The network data is put together using cast char pointers iterated over the buffers by manual calculations(i.e. a char pointer, cast to the data type wanted, then data assigned, then char pointer incremented that data size), which are sent using manually added totals for size. (See below)

Most of the code is in a single god class; Lots of code to cover problems rather than just fixing them; Completely unrelated classes for different things; mostly done with C style constructs and ways; the function that actually deals with a basic attack is over 2000 lines long with at least 60 variables declared at the top of it; mixing unsigned/signed types incorrectly; the list goes on

I've seen people able to do better within a few weeks of learning. Somehow it actually works as a playable game.

Sample of how network data is done (cp being pointer to the buffer):

Code: Select all

       sp = (short *)cp;
      *sp = (short)sV7;
      cp += 2;

      sp = (short *)cp;
      *sp = (short)sV8;
      cp += 2;

      sp = (short *)cp;
      *sp = (short)sV9;
      cp += 2;

      if (pString != NULL) memcpy(cp, pString, 20);
      cp += 20;

      if (pString2 != NULL) memcpy(cp, pString2, 20);
      cp += 20;

      iRet = m_pClientList[iToH]->m_pXSock->iSendMsg(cData, 64);
Image

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Thu Jul 15, 2010 12:48 am UTC

elminster wrote:I've said this before but, more monitor space would be so nice for coding. I'd expect it's one of those things that really benefit from dual monitor setups. Wonder what 2 vertically aligned 1080p monitors would be like.


I used to have a 1280x1920 24" next to a 1280x1024 21". It was occasionally convenient, but most of the time, I felt the second monitor wasn't really being used, so I ended up putting it away to save desk space. Given a more dual-screen friendly WM, a more dual-screen friendly IDE, and more dual-screen friendly habits, it could probably have worked. But meh.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
b.i.o
Green is the loneliest number
Posts: 2519
Joined: Fri Jul 27, 2007 4:38 pm UTC
Location: Hong Kong

Re: Coding: Fleeting Thoughts

Postby b.i.o » Thu Jul 15, 2010 2:34 am UTC

You, sir, name? wrote:
elminster wrote:I've said this before but, more monitor space would be so nice for coding. I'd expect it's one of those things that really benefit from dual monitor setups. Wonder what 2 vertically aligned 1080p monitors would be like.


I used to have a 1280x1920 24" next to a 1280x1024 21". It was occasionally convenient, but most of the time, I felt the second monitor wasn't really being used, so I ended up putting it away to save desk space. Given a more dual-screen friendly WM, a more dual-screen friendly IDE, and more dual-screen friendly habits, it could probably have worked. But meh.

I use two 1680x1050 monitors next to each other when I'm doing work. I find it to be extremely useful. For just coding, documentation/chat windows go on one screen, and Vim + a terminal or two on the other. For web design/web work, the web browser goes on one screen, and Vim/terminals on the other. I *can* work on one monitor, but it's much nicer to have two. Unfortunately one of them is attached to my laptop and the other doesn't support screen rotation, so I can't have either of them vertical, which would be quite nice.

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Thu Jul 15, 2010 4:32 am UTC

It would be awesome having a multi-column text editor where the text scrolls to the bottom of one column then up from the top of another.

Code: Select all

1...                    | 51...
2...                    | 52...
3...                    | 53...
4...                    | 54...
5...                    | 55...
6...                    | 56...
...                     |
50...                   |


Say goodbye to wasted horizontal wide-screen desktop space and wasted time scrolling.
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

Maelstrom.
Posts: 76
Joined: Tue Oct 21, 2008 12:18 pm UTC

Re: Coding: Fleeting Thoughts

Postby Maelstrom. » Thu Jul 15, 2010 5:55 am UTC

TheChewanater wrote:It would be awesome having a multi-column text editor where the text scrolls to the bottom of one column then up from the top of another.

Say goodbye to wasted horizontal wide-screen desktop space and wasted time scrolling.


I know a few editors including Vim and Notepad++ allow split pane editing, which is kinda similar. You can open the same document in two panes, with two different locations shown, to allow copy+pasting etc easily without scrolling. Unfortunately, it doesn't keep the windows scrolling together, but a vim plugin/Notepad++ macro could be written to do it I am sure.

Vim windows (aka split window/pane) and tabs are extremely handy, and surprisingly few people know about and use them.

User avatar
Ephphatha
Posts: 625
Joined: Sat Sep 02, 2006 9:03 am UTC
Location: Bathurst, NSW, Australia

Re: Coding: Fleeting Thoughts

Postby Ephphatha » Thu Jul 15, 2010 4:03 pm UTC

I feel like I've accomplished something today. I've got a set of cameras written which extend on each others functionality to do different things. A base camera offering Dolly and Pan operations (with helpers to Pitch/Yaw/Roll, Surge/Sway/Heave, MoveTo/LookAt a point), An abstract DynamicCamera class (extending Camera) that provides an Update(float) function, then an ElasticCamera (extends DynamicCamera) which moves along a B-Spline, a ThirdPersonCamera (extends DynamicCamera) which constantly looks at a point, and an ElasticThirdPersonCamera (extends ElasticCamera, ThirdPersonCamera) which combines both into one class. Apart from a compiler warning (C2450, from a bit of looking around I can ignore it) everything actually works! (Except the view is a bit shaky.)
I'm not lazy, I'm just getting in early for Christmas is all...

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Thu Jul 15, 2010 8:23 pm UTC

Awesome! All of those are very useful behaviors.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

0xBADFEED
Posts: 687
Joined: Mon May 05, 2008 2:14 am UTC

Re: Coding: Fleeting Thoughts

Postby 0xBADFEED » Thu Jul 15, 2010 11:46 pm UTC

elminster wrote:I don't suppose anyone happens to know if there's a way to pass a member function pointer that takes 2 or more arguments? Isn't really important but I done the following which works only 1 argument, but can't find any one that would take an arbitrary number of arguments:

Code: Select all

std::bind1st(std::mem_fun(&SomeClass::MemberFunct), this)
//pass and stored as
std::tr1::function<void (/*argument type*/)>


Do you really want to pass the member-pointer or do you want to do something more like you're doing here and pass a member-pointer that's been bound to an instance? If you wanted to pass a bound-member (i.e. a pointer-to-member-function bound to a specific instance that accepts the rest of its arguments) to an n-ary method you can use the generalized 'bind' function. It's in tr1 (which it seems you have) and there's an implementation in Boost.
Example:

Code: Select all

struct MyStruct
{
    int foo(int arg1, int arg2) {
        return arg1 + arg2;
    }
};

MyStruct s;

function<int(int,int)> bar = bind(&MyStruct::foo, &s, _1, _2);

//You can even use it to bind general function-objects
int x = 1, y = 2;

function<int(int)> baz = bind(bar, x, _1);
function<int()> bax = bind(baz, y);

assert(s.foo(x,y) == bar(x,y) == baz(y) == bax());

//Note: I didn't compile this but it should be correct

This tends to be more convenient than passing a straight pointer-to-member.

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Re: Coding: Fleeting Thoughts

Postby elminster » Fri Jul 16, 2010 1:49 am UTC

I have a 1680x1050 monitor, which is reasonable for coding, but often I find that too much room is taken up to view enough things. Maybe a single 30" would do, or even just a 1080p, but constantly I find myself having to adjust views to make them large enough.
0xBADFEED wrote:Do you really want to pass the member-pointer or do you want to do something more like you're doing here and pass a member-pointer that's been bound to an instance? If you wanted to pass a bound-member (i.e. a pointer-to-member-function bound to a specific instance that accepts the rest of its arguments) to an n-ary method you can use the generalized 'bind' function. It's in tr1 (which it seems you have) and there's an implementation in Boost.
[snip]
Well basically, I was passing it bound to an instance because it was being called from the main class(non-static) and passed to instances of a class designed to hold UI elements to be used as handlers(which are in the main class). From what I've read you can't do that without binding to an instance. I was just trying to work around what's already there, since the main class is so long and heavily bound together.
Of course, I could be going the wrong way about this entirely.
Image

User avatar
Rippy
Posts: 2101
Joined: Sun Jul 22, 2007 11:27 pm UTC
Location: Ontario, Can o' Duh

Re: Coding: Fleeting Thoughts

Postby Rippy » Fri Jul 16, 2010 5:17 am UTC

Ok my reference image struct is driving me nuts. It contains ints for width, height, color type and bit depth, and then a union containing pointers to all the possible types of "pixels". I can see how replacing that union with a catch-all void * wouldn't be pretty, but when I need 5+ if's every time I need to access that pointer, it seems ridiculous.

I'm considering using a void * and just manually calculating all the pointer arithmetic, unless there's something I'm missing (at nearly 2AM, this is very likely).

User avatar
phlip
Restorer of Worlds
Posts: 7572
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Fri Jul 16, 2010 6:44 am UTC

But wouldn't you need all those if's/switch's/etc anyway, even if you dropped the union in favour of void*? After all, you'd still need to be able to tell what type to cast the pointer to before you can use it... the only exception I can think of is when it's free'd... and one single extra switch then isn't going to kill you.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Rippy
Posts: 2101
Joined: Sun Jul 22, 2007 11:27 pm UTC
Location: Ontario, Can o' Duh

Re: Coding: Fleeting Thoughts

Postby Rippy » Fri Jul 16, 2010 11:12 am UTC

Not necessarily. If instead of depth and colour type elements in the struct, I just had a pixel_size variable (1, 2, 4, 8, 16, and 24 and 48 for 8-bit and 16-bit RGB), then that could be used by the function(s) that deal with writing to the array to manually calculate the pointer arithmetic. It sounds really awful, but I'm thinking the end result would be more readable than blocks of switch/cases everywhere.

User avatar
Xanthir
My HERO!!!
Posts: 5412
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Fri Jul 16, 2010 4:07 pm UTC

It's really not that awful. HTML's <canvas> element, frex, exposes its data as a flat array of subpixel values. It's easy to work with. (You just see a bunch of *4's being thrown around, since a pixel is made of 4 subpixels.)
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
Xanthir
My HERO!!!
Posts: 5412
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Fri Jul 16, 2010 4:27 pm UTC

FT: ARHASD;FJKA;GHA;SDLF; I HATE FLOATING POINT (IN)ACCURACY.

To help with a discussion of exactly how we should standardize CSS's shadow properties, I wrote a quick <canvas> app to do a true gaussian blur so I can conduct measurements easily. Got some errors right away, but that's all right, it was minor and didn't jump out of the tolerance value I'd set. Started bumping up sigma, and got worse and worse results when blurring white. At 30 sigma (producing a blur roughly 110px wide), the errors were so bad that blurring *pure white* (an operation which, obviously, should result in pure white) was producing an even 95% gray, which is easy to tell apart from white with the naked eye.

Blurring black didn't have the same issues, because it had more accuracy to start with (working with numbers at or near 0, rather than at or near 255, gives me 6 or 7 extra bits to work with), and also because having a value get small enough to fall off the significand doesn't matter much when the number you're adding it to is near 0 anyway.

I eventually hacked around the issue by just inverting the colors when I was on the "white half" of the picture to do math on, then inverting them again to store them. That gave me the same accuracy as the "black half". Still errors, but not as bad, and the errors are symmetrical now, which is more important to me.

(I can see why no one does true gaussian blurs now!)
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
Cosmologicon
Posts: 1806
Joined: Sat Nov 25, 2006 9:47 am UTC
Location: Cambridge MA USA
Contact:

Re: Coding: Fleeting Thoughts

Postby Cosmologicon » Fri Jul 16, 2010 4:33 pm UTC

That makes it sound like you have other issues besides floating-point precision issues. Gaussian blur isn't that hard. Would you be interested in posting your code?

User avatar
Xanthir
My HERO!!!
Posts: 5412
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Fri Jul 16, 2010 4:59 pm UTC

Source code of http://www.xanthir.com/etc/blurplay.

Edit: If you want to try it *without* the inversion contortion I'm doing, download the page locally and change the main loop to this:

Code: Select all

      for(var y = 0; y < h; y++) {
         for(var x = 0; x < w; x++) {
            outputdata[(y*w+x)*4+3] = 255; // set all pixels to fully opaque
            for(var p = 0; p < 3; p++) { // subpixel offset - I only care about the rgb, not the a
               var i = (y*w+x)*4+p; // calculate the offset into data
               for(var j = -kernel.length + 1; j < kernel.length; j++) {
                  if( x+j < 0 ) continue; // falling off the row, do nothing
                  if( x+j >= w ) { outputdata[i] += 255 * kernel[Math.abs(j)]; continue; }
                  outputdata[i] += inputdata[i + j*4] * kernel[Math.abs(j)]; // gaussian!
               }
               outputdata[i] = Math.max(0,Math.min(255,outputdata[i])); // convert it back to an integer in [0,255]
            }
            if( outputdata[i] <= min || outputdata[i] >= max ) { // if the pixel was unchanged, mark it with red
               outputdata[i-2] = 255; outputdata[i-1] = 0; outputdata[i] = 0;
            }
         }
         // Mark the halfway line
         var half = (y*w + w/2)*4;
         outputdata[half] = 255;
         outputdata[half+1] = 255;
         outputdata[half+2] = 0;
      }
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
Cosmologicon
Posts: 1806
Joined: Sat Nov 25, 2006 9:47 am UTC
Location: Cambridge MA USA
Contact:

Re: Coding: Fleeting Thoughts

Postby Cosmologicon » Fri Jul 16, 2010 6:51 pm UTC

Hey neat! Well, it took me a while to figure out what the issue is, but I got it now. I guess this is a quirk of the way the canvas element takes care of its data. Every time you're assigning to outputdata[i], it's getting coerced to an integer. Since you're summing up a bunch of floating-point values, it screws up by repeated flooring. This is especially evident when you increase sigma and you're dealing with lots of very little values.

Anyway, I was able to fix it by adding an intermediate variable "pixval" for the calculation, which remains a float throughout the sum:

Code: Select all

            for(var p = 0; p < 3; p++) { // subpixel offset - I only care about the rgb, not the a
               var i = (y*w+x)*4+p; // calculate the offset into data
               pixval = 0
               for(var j = -kernel.length + 1; j < kernel.length; j++) {
                  if( x+j < 0 ) continue; // falling off the row, do nothing
                  if( x+j >= w ) { pixval += 255 * kernel[Math.abs(j)]; continue; }
                  pixval += inputdata[i + j*4] * kernel[Math.abs(j)]; // gaussian!
               }
               outputdata[i] = Math.max(0,Math.min(255,pixval)); // convert it back to an integer in [0,255]
            }


Incidentally, it's easy to fix the edge effect that happens at the right end by normalizing pixval in terms of how much of the kernel you actually sampled. Your method of setting those to imaginary white pixels works too, but this is a little more general:

Code: Select all

            for(var p = 0; p < 3; p++) { // subpixel offset - I only care about the rgb, not the a
               var i = (y*w+x)*4+p; // calculate the offset into data
               pixval = 0
               kernelsum = 0
               for(var j = -kernel.length + 1; j < kernel.length; j++) {
                  if( x+j < 0 ) continue; // falling off the row, do nothing
                  if( x+j >= w ) continue;
                  pixval += inputdata[i + j*4] * kernel[Math.abs(j)]; // gaussian!
                  kernelsum += kernel[Math.abs(j)]
               }
               pixval /= kernelsum
               outputdata[i] = Math.max(0,Math.min(255,pixval)); // convert it back to an integer in [0,255]
            }

User avatar
Xanthir
My HERO!!!
Posts: 5412
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Fri Jul 16, 2010 7:19 pm UTC

Cosmologicon wrote:Hey neat! Well, it took me a while to figure out what the issue is, but I got it now. I guess this is a quirk of the way the canvas element takes care of its data. Every time you're assigning to outputdata[i], it's getting coerced to an integer. Since you're summing up a bunch of floating-point values, it screws up by repeated flooring. This is especially evident when you increase sigma and you're dealing with lots of very little values.

Oh. Huh. I didn't realize it was flooring intermediate values. That makes a lot of sense. Checking the spec, I see that the setter for CanvasPixelArray takes an octet, not a number.

Cosmologicon wrote:Incidentally, it's easy to fix the edge effect that happens at the right end by normalizing pixval in terms of how much of the kernel you actually sampled. Your method of setting those to imaginary white pixels works too, but this is a little more general:

Yes, I'd done renormalization earlier, but killed it on suspicion that it was contributing to the errors.

And, upon changing over to using a number, it works much better! I removed the inverting, and it's almost perfectly symmetrical. Excellent!

Thanks, Cosmo.

(Interestingly, now that I'm not getting rounding errors, the relationship between sigma and length looks trivial. Excellent.)

Edit: ...huh. Switching back to renormalizing makes the relationship even more precise. That's... weird. The length to the 2% cutoff point is *exactly* twice the sigma all the way up to 100sigma. Checking 200 shows that the relationship doesn't hold forever (whew), but still. That's crazy.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Tue Jul 20, 2010 7:55 am UTC

FT:
I wonder what this assignment in my textbook is supposed to mean.

3.12) Write a while loop that makes sure the user enters a positive ineger value.


Huh? Is this what it wants?

Code: Select all

while (test_value = 0; test_value != INT_MAX; test_value --)
  if (entered_value == test_value) return false;
return true;


This book is silly.
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Tue Jul 20, 2010 7:59 am UTC

Code: Select all

#include <iostream>

using namespace std;

int main()
{
    int num;
    while(cin >> num)
    {
        if(num > 0)
            break;
        cout << "Please enter a positive integer." << std::endl;
    }
}


This is a common idiom for checking inputs (in C++ at least).

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Tue Jul 20, 2010 8:08 am UTC

Actually, this is Java (despite my use of INT_MAX). I get what you mean, though.
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
Rippy
Posts: 2101
Joined: Sun Jul 22, 2007 11:27 pm UTC
Location: Ontario, Can o' Duh

Re: Coding: Fleeting Thoughts

Postby Rippy » Wed Jul 21, 2010 1:19 pm UTC

Woo for coding ingenuity! I have to go through a 600-some spreadsheet which needs a column of e-mail addresses filled, which can only be done by searching this gigantic lotus notes database and opening up the occasional document to root around for an e-mail (I love my job...). But after a half-hour of scripting AutoHotkey, I have everything but the actual document-opening automated. The database searches typically take >30 seconds each, so I just have it re-focus firefox and I can read up on programming in between :).

(By the way, if anyone knows a shortcut for returning to the top of a list in Lotus Notes, that would cut out even more user intervention :P. Ctrl+PgUp doesn't seem to work.)

The png manipulation is going not so great though. I gave up on writing it all myself once I got to the compression, realized there's no way I'm rewriting that, and figured if I'm using zlib I might as well use libpng. So then I wrote some code for that, but now I cannot figure out how to convert my own data structure into a png_struct for writing. The only examples I've found deal with reading a png, making changes and writing it again, not with generating a new PNG. And libpng is complicated enough that I can't figure it out from the documentation, let alone find the definition of their png_struct so I can fill it out myself.

So now I'm looking into OpenIL in the hopes that it will actually be somewhat programmer-friendly to implement.

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Wed Jul 21, 2010 4:25 pm UTC

The Home key won't work?
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
Vault
Posts: 169
Joined: Mon Nov 10, 2008 5:00 pm UTC
Location: Just past the event horizon
Contact:

Re: Coding: Fleeting Thoughts

Postby Vault » Wed Jul 21, 2010 10:09 pm UTC

Today I realized what's so special about closures! I mean, I knew what they were and what they let me do, but I just realized why exactly that's special.

It's something that I think seems obvious when you're not paying attention, but when you think about it, it's actually not obvious, and far more powerful than you'd think at first.

qbg
Posts: 586
Joined: Tue Dec 18, 2007 3:37 pm UTC

Re: Coding: Fleeting Thoughts

Postby qbg » Wed Jul 21, 2010 11:54 pm UTC

Vault wrote:Today I realized what's so special about closures!

What led you to this realization?

User avatar
Vault
Posts: 169
Joined: Mon Nov 10, 2008 5:00 pm UTC
Location: Just past the event horizon
Contact:

Re: Coding: Fleeting Thoughts

Postby Vault » Thu Jul 22, 2010 1:49 am UTC

Oddly enough, teaching myself Lua.

User avatar
Berengal
Superabacus Mystic of the First Rank
Posts: 2707
Joined: Thu May 24, 2007 5:51 am UTC
Location: Bergen, Norway
Contact:

Re: Coding: Fleeting Thoughts

Postby Berengal » Thu Jul 22, 2010 7:03 pm UTC

We all know that short functions/classes/modules/units of code are a good thing, but is it cargo cult to deliberately try to make them so?

I've been reading some horrible code lately and I've noticed that even short parts are crap. Sometimes it's very easy to see that it's short because it was made so just for shortness' own sake, which immediately made me think of make-believe airports and voodoo dolls.
It is practically impossible to teach good programming to students who are motivated by money: As potential programmers they are mentally mutilated beyond hope of regeneration.

User avatar
Xanthir
My HERO!!!
Posts: 5412
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Thu Jul 22, 2010 7:15 pm UTC

It's cargo cult to do anything for the sake of doing it, rather than for the original reason it was recommended. That's the definition of "cargo cult".
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
Berengal
Superabacus Mystic of the First Rank
Posts: 2707
Joined: Thu May 24, 2007 5:51 am UTC
Location: Bergen, Norway
Contact:

Re: Coding: Fleeting Thoughts

Postby Berengal » Thu Jul 22, 2010 8:24 pm UTC

Xanthir wrote:It's cargo cult to do anything for the sake of doing it, rather than for the original reason it was recommended. That's the definition of "cargo cult".
Screamingly obvious now it's coming from someone else...
It is practically impossible to teach good programming to students who are motivated by money: As potential programmers they are mentally mutilated beyond hope of regeneration.

User avatar
Rippy
Posts: 2101
Joined: Sun Jul 22, 2007 11:27 pm UTC
Location: Ontario, Can o' Duh

Re: Coding: Fleeting Thoughts

Postby Rippy » Sun Jul 25, 2010 6:26 pm UTC

I'm pretty satisfied with my map generator I must say:
procgen.gif
procgen.gif (10.05 KiB) Viewed 5112 times

It can be customized like crazy, and I'm actually pretty proud of the code (except for main(). The modular functions are great, main() is just horrid).

Time to clean up the code a bit and move on to the next project. (gotta fit them in now while I'm working and not having 2 weekly CS assignments...)

User avatar
b.i.o
Green is the loneliest number
Posts: 2519
Joined: Fri Jul 27, 2007 4:38 pm UTC
Location: Hong Kong

Re: Coding: Fleeting Thoughts

Postby b.i.o » Mon Jul 26, 2010 1:34 am UTC

That's pretty cool. What's the algorithm like/is the code up somewhere?


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 6 guests