|
|
|
|
|
10 Jun, 2009 - 12:11 PM
|
Taking a moment out of my usual project development blogs to bash/praise Linux. Don't get used to me using the blog for personal opinions though. I leave that to the other bloggers. Yeah, I'm looking at you Martyr2.
Since I managed to use a USB to serial conversion cable to set up my printer to work with my laptop, my old desktop has since been left gathering dust. I figured, why not put install a Linux distro onto it to make it at least run more efficiently than Windows. Its a Compaq Presario 5000 series, specifcally model 5BW175 if you're curious as to its specifications I'm sure Google will turn them up for you. Quick overview is a 700 MHz Intel processor and 128 MB RAM with a 20 something Gig harddrive. Not the most powerful PC on the planet. A friend managed to snag me an extra 128 MB of RAM kicking it up to 256 MB. Bad@$$. Anyways, I must've downloaded about 20 different distros. Here are the ones I remember:
Ubuntu Xubuntu Mandriva Vector Linux Damn Small Linux Knoppix Debian MEPIS Poseidon Linux GNOME (the LiveCD available at their site) Crunch Bang Linux
Needless to say you can go nuts looking at all the different distros. I know I'm slightly madder for it. Some of these couldn't load the LiveCD, wouldn't complete the install, etc. (I've also discovered that apparently my DVD drive can no longer read DVDs and only CDs for no apparent reason). A lot of them the desktops, like GNOME and KDE were just too taxing on the RAM, so I opted not to use them. I had settled on Debian, given its availability of packages and that I could install it with the LXDE desktop environment. However, Debian failed to properly set up my sound card, and after hours of trying to fix the problem I just gave up. I went with Knoppix that uses LXDE as well (and from what I've read online Knoppix is THE distro in terms of hardware detection and setup). Why? Well because using the Synaptic package manager I somehow managed to fatally harm my LXDE desktop attempting to modify the ALSA package so that it would redetect my sound card and hopefully get audio working. Not my brightest move, but ehh, such is the way of the Grim Pirate.
What I wanted to gripe about is the fact that it seems that most of the Linux documentation fails to take into account the fact that there are users who've never used a Linux distribution before. So if errors happen, you're sometimes caught :: blinking glassy-eyed :: I realize that Linux is perhaps oriented towards the uber computer savvy, and honestly I think that while at times its a good thing, its also one of Linux's shortcomings. I was trying my best to decrypt how to troubleshoot the sound card issue and they're just like check some file and check some other file and run something and module-app this and that. Seriously, my brain is kinda mildly warm right now.
In any case, Knoppix gave me an idiot proofing solution. So in terms of distros I'm giving my Knoppix my seal of approval. Screw all the others.
| |
|
|
|
|
|
|
|
22 Apr, 2009 - 10:02 PM
|
ok so I've been having some permission issues due to my lack of familiarity with Linux servers on my 110mb host. Apparently when I use my CPanel or FTP I'm given a different owner ID then when a PHP script executes. Whereupon created files by the PHP script are given the owner ID that is in fact my group ID. Its caused me quite a bit of headache. However, it also lead me to the conclusion that stipulating file permissions within the Mimesis class itself is a waste of time. The logic behind this?
Windows doesn't care about file permissions, so chmod is irrelevant on Windows systems. On a Unix/Linux system if you can't alter the umask (as I can't do in my server) then the file should most likely be created with default with permissions (set by your server) that you can likely alter via a chmod. Therefore, there's no need to include this intrinsically into Mimesis.
Therefore, this newest version simply does away with specifying permission settings. I'm planning on explaining this in the Usability Notes (assuming I ever get them done), and revising tutorials to show what needs to be done on *nix systems. Either chmodding or umasking.
Finally, I am also going through each of the tutorials again as a disgruntled visitor remarked that none of them worked. I grant you he didn't say which ones, nor what exactly his issues were, and he was rude, but the man had a point. I've already found that the first two tutorials, Ad Rotator and File Inclusion were not functioning. I have fixed those and updated them to the newest version.
The Quick Function Reference and Complete Function Reference have also been updated. I kept getting some error when I attempted to upload them so I simply uploaded them to FileFront and Stashbox and provided the links. This also helps me save on bandwidth, not that its much, but I'm a hoarder like that.
| |
|
|
|
|
|
|
|
20 Mar, 2009 - 08:38 PM
|
Ahh the final entry where we put everything together into a non-language specific algorithm. Well let's get to it then: CODE Given x: an integer value that defines the horizontal position of a pixel within a grid Given y: an integer value that defines the vertical position of a pixel within a grid Given red: an integer ranging from 0 to 255 that specifies the red channel of a 32 bit color Given green: an integer ranging from 0 to 255 that specifies the green channel of a 32 bit color Given blue: an integer ranging from 0 to 255 that specifies the blue channel of a 32 bit color Given alpha: an integer ranging from 0 to 255 that specifies the alpha channel of a 32 bit color Given intensity: a float value ranging from 0 to 1 that defines the brightness/intensity of a 32 bit color We define a procedure setPixel wherein Defined prevRed: the red channel of the pixel atop which we are placing a new pixel at coordinates (x, y) Defined prevGreen: the green channel of the pixel atop which we are placing a new pixel at coordinates (x, y) Defined prevBlue: the blue channel of the pixel atop which we are placing a new pixel at coordinates (x, y) Defined prevAlpha: the alpha channel of the pixel atop which we are placing a new pixel at coordinates (x, y) Which sets a pixel to a particular 32 bit color using the following methodology pixel located at (x, y)'s red channel = prevRed * (1 - intensity) + red * intensity pixel located at (x, y)'s green channel = prevGreen * (1 - intensity) + green * intensity pixel located at (x, y)'s blue channel = prevBlue * (1 - intensity) + blue * intensity pixel located at (x, y)'s alpha channel = prevAlpha * (1 - intensity) + alpha * intensity End procedure
CODE Given x: a float value that defines the horizontal position of a pixel within a grid Given y: a float value that defines the vertical position of a pixel within a grid Given red: an integer ranging from 0 to 255 that specifies the red channel of a 32 bit color Given green: an integer ranging from 0 to 255 that specifies the green channel of a 32 bit color Given blue: an integer ranging from 0 to 255 that specifies the blue channel of a 32 bit color Given alpha: an integer ranging from 0 to 255 that specifies the alpha channel of a 32 bit color We define a procedure antiAlias which uses setPixel wherein x = x + 0.5 y = y + 0.5 Compute centerX, centerY as the truncated value of x and y respectively Where truncate refers to taking solely the integer part of a float value Compute gridX, gridY as the rounded value of x and y respectively Where rounding refers to approximation to an integer value determined by floats whos fractional part is greater than or equal to 0.5 Compute deltaX, deltaY as the offsets from gridX, gridY to centerX, centerY respectively Compute largeArea = (0.5 + |deltaX|) * (0.5 + |deltaY|) Compute smallArea = (0.5 - |deltaX|) * (0.5 - |deltaY|) Compute verticalArea = (0.5 - |deltaX|) * (0.5 + |deltaY|) Compute horizontalArea = (0.5 + |deltaX|) * (0.5 - |deltaY|) Determine coordinates for four pixels dependent upon the orientation of the offset vector <deltaX, deltaY> as coordX, coordY setPixel(centerX, centerY, red, green, blue, alpha, largeArea) setPixel(coordX, centerY, red, green, blue, alpha, verticalArea) setPixel(centerX, coordY, red, green, blue, alpha, horizontalArea) setPixel(coordX, coordY, red, green, blue, alpha, smallArea) End procedure
In closing I hope this tutorial has been of help to you. If you have any questions feel free to ask. What I've provided here is not an algorithm that takes into account optimizations. Its just a head on direct approach without regard for computing speed. Building on this pixel drawing it is possible to draw any sort of antialiased object, be it a line, curve, or filled shape of some sort. In the near future I may expand on how to draw a line using this procedure as the building block.
| |
|
|
|
|
|
|
|
20 Mar, 2009 - 04:01 PM
|
And so the journey continues. For the following tidbit, we'll take a look at an actual pixel coordinate (0.4, 0.6) with both grids overlayed.  That figure highlights all the previous concepts plus two extra pieces of information. One, it shows a red arrow (which represents a vector) extending from the corner of a pixel boundary (the blue grid) closest to the actual center of the pixel. Two, it shows us how the pixel is subdivided into four unequal areas. These two concepts are the essential cornerstone of antialiasing a pixel because the quantities produced from them are what determine the colors of the pixels we create for the approximation. Now comes the good part. How do we arrive at these numbers and how do we make use of them? Well here goes. By determining which pixel boundary corner is closest to the center we can compute two offsets, one in the vertical direction and one in the horizontal direction (this is where the red vector comes from, and the delta values are the offsets in the respective x and y direction). These offsets are crucial because they tell us how to divide the pixel into constituent areas. The areas the we divide a pixel into tell us how much shading to apply. How come? Well it should be obvious that wherever MOST of a pixel ends up is where it should be darker, and where the LEAST ends up, it should be lightest, and that the sum of its constituent areas should be equal to 1 (a pixel has dimensions of 1 by 1, therefore its total area is also 1). Nifty, but still confusing right? ok let's look at just the pixel for a moment with the boundary grid overlayed atop it.  I've taken out the red arrow and the orange grid as they're not necessary for this explanation. That's our black pixel right? Good. Following is a list of things that will always be true about this blue grid and the pixel it overlays: - In the case where the blue grid is not intersecting the pixel somewhere, the pixel itself is in fact located by two integer coordinates - If the grid intersects the pixel somehow, then it will either be divided into two areas, or four areas - Two areas is simply a special case of four areas, where two of the four areas are equal to zero (these refer to the special horizontal and vertical cases listed previously where only one coordinate is an integer) - In the case of four areas, there will always be one area larger than the others, and one area smaller than the others, the larger area will always be in the direction of the offset vector, the small area will always be in the direction opposite the offset vector These previous statements are ALWAYS true, there's absolutely no deviation from them. The formulas for each of the four areas are given as follows: - largeArea = (0.5 + |deltaX|) * (0.5 + |deltaY|) - smallArea = (0.5 - |deltaX|) * (0.5 - |deltaY|) - verticalArea = (0.5 - |deltaX|) * (0.5 + |deltaY|) - horizontalArea = (0.5 + |deltaX|) * (0.5 - |deltaY|) In the case of our pixel the large area is the one on the lower left, the small area is to the upper right, the vertical area is to the right of the large area, and the horizontal area is directly above the large area. These numbers represent the amount of area of the pixel that is present in one of the four pixels its touching. So why is it we either add or substract the deltas from 0.5? This is because the grid will always be located somewhere between one of the corners of the pixel and its center, or directly atop them. In the case of the center the areas are all equal. In the case of a corner only the large area is present. When the grid crosses the threshold of the center of the pixel, the pixel has now crossed over into another region and therefore the antialiasing would occur at other locations. The areas themselves also gives represent something more, a scaling factor so to speak. This scaling factor is known as brightness or intensity. Let's assume you looked at only the red channel of a color, going from 0 to 255. If we wanted it to be 80% of its brightness, we would multiply 255 by 0.8 which would give us 204. That's why these areas are important, because they tell us the amount of the original color that we want to use. However we also have to remember that we're drawing these pixels atop another color, so how do we determine what brightness to set that color at so as to blend the two? Well its the same, we multiply the color underneath but instead of by 0.8 we multiply it by (1 - 0.8) and then we add the two numbers together. So let's look at an example using two colors: red and blue which are represented as 0xff0000ff and 0x0000ffff respectively. We're drawing red on top of blue and let's assume we wanted only 60% of the red to appear, well we'd take each channel of the red and multiply it by 60% and take each channel of the blue and multiply it by (1-60%) and then add the channels together. Here's how it goes: Red: [0xff * 0.6][0x00 * 0.6][0x00 * 0.6][0xff * 0.6] = 0x99000099 Blue: [0x00 * (1 - 0.6)][0x00 * (1 - 0.6)][0xff * (1 - 0.6)][0xff * (1 - 0.6)] = 0x00006666 Adding the resultant red and blue we arrive at a color that is somewhat purplish = 0x990066ff. If you want to see this for yourself take a graphics program that supports transparency in layers, then draw a fully blue color underneath a fully red color, and then change the transparency of the layer to 60%. Then check the resultant color and you'll see it will have the very same hex code. So what's left? Well now that you can compute the offset vector and the four areas and now how to use them to modify colors all you have to do is locate where you're going to place the pixels that approximate the pixel we wish to antialias. That's the job of the offset vector. Vectors indicate direction. So does the offset vector in these computations. So if you know the direction of the offset vector you know where to place the other four pixels. In case its not obvious you always place the large area pixel first as that one corresponds to the closest approximation of the actual pixel, then place the other three pixels relative to that one. In the next and final entry I will post the algorithm that highlights all these steps.
| |
|
|
|
|
|
|
|
19 Mar, 2009 - 02:52 PM
|
So now we have some periphery knowledge of colors, and of how our pixels colors will change based on their position, and how these positions translate from stuff with decimal points to just whole numbers. Good. However, we're still missing a couple of concepts. Of important note is how exactly we will mathematically compute certain distances, and how exactly our unknown user would define where he/she wishes to place his/her pixel on the screen. I am providing the following grid with an overlayed grid as a reference.  The orange grid represents the coordinates that your computer utilizes in order to place a pixel (i.e. its center point). The blue grid represent the actual pixel boundaries of the screen and these are the grid coordinates that we'll use for our computations. This is important because we need to understand that if a user wants to locate the pixel at (0.5, 0) we know that he wants its center to be in between pixel 0 and pixel 1 of the first row of pixels. Remember, orange represents pixel coordinates, blue represents pixel boundaries. The "equation" at the bottom of the grid shows how to relate the two.
| |
|
|
|
|
|
|
|
18 Mar, 2009 - 03:23 PM
|
So now we know that in order to approximate an "analog" position of a pixel on the screen we will in fact color in the pixels that it would touch on the "digital" computer screen. However, will it always be four pixels? The answer is no. In fact there are (as I see it) 3 different "states" that an "analog" pixel can assume on a "digital" screen. One of them is obvious, as in the pixel is actually placed at an integer location such as (1,2),(3,4),(88,3) etc. This will always produce one pixel and the pixel will be the exact color that is given for it (no change necessary because this doesn't qualify for antialiasing). The other two states are as follows:    The latter images represent the same state, but just rotated by 90 degrees from one another. The first picture highlights that when a pixel is placed at two analog coordinates (using a double/float number) such as (3.3333, 1.5), (1.101, 3.1415), etc. We will have to color in at least 4 pixels if two analog coordinates are given. The next two pictures highlight the situation where a pixel is placed at one analog and one digital coordinate (using a double/float and an integer) such as (1, 1.345), (2.033, 5), etc. If the x coordinate is the integer then the approximation of its position will occur between only two vertical pixels. If the y coordinate is the integer then the approximation of its position will occur between only two horizontal pixels. The state not shown where both coordinates are digital (integer numbers), and thusly the pixel is drawn where it actually corresponds on the screen and no approximations are necessary.
| |
|
|
|
|
|
|
|
17 Mar, 2009 - 04:17 PM
|
So how does one apply antialiasing? Can it only be applied to lines or color boundaries or overlayed colors? Antialiasing doens't only refer to the blending of colors on a computer screen at boundaries/layers. In fact, the smallest unit that can be antialiased is in fact a pixel, the fundamental stuffs of computer graphics as it were. One can assume that antialiasing cannot be applied to a pixel as it cannot be broken down into anything less than 1 pixel width by 1 pixel height. However, that's not entirely true (if you adopt a different perspective about colors on a monitor). So let's talk about how we're going to represent colors. The color format we'll be using is stored in a 32 bit integer. Specifically, one composed of 4 channels, a red channel, a green channel, a blue channel, and a transparency channel. So let's say we wanted to represent some simple colors: 0x 000000ff : 100% opaque black 0x 00000000 : 100% transparent black 0x ffffffff : 100% opaque white 0x ffffff00 : 100% transparent white 0x ff000080 : 50% opaque red 0x 0000ff80 : 50% opaque blue As you can see representing any number is just a matter of sliding each one of the 8 bits that represent a particular channel to get the color you want. This is the same way that colors in CSS and HTML tags work to change text color on webpages (minus the transparency channel). Now, we know a computer screen can ONLY place a pixel at integer locations. For example, (0, 0), (0, 1), (0, y), (x, y)... where x and y represent the coordinates of the pixel on the computer's screen, but it also applies a color to the pixel. So let's assume we were drawing black pixels. Any time we give an integer location the computer would place a perfectly black pixel on that location of the monitor. We represent black as 0x000000ff. So every time we placed this black pixel the computer would make the value of the pixel at that location 0x000000ff. But what if we wanted to place a pixel at somewhere like (0.5, 0.5). The computer would do the following, it would either round or truncate the coordinate to its nearest integer value resulting in either (0, 0), or (1, 1) depending on the procedure your computer chooses to use, or it may just return an error, OR it may not even place the pixels on screen since its expecting an integer and instead received a float value. There's no way to be sure what your hardware might do, but we know what we want it do, to place a black pixel at (0.5, 0.5). Let's look at a diagram to illustrated the idea:  The blue lines represent the boundaries of the physical pixels on your screen, the black pixel is obviously where we wish we could put our pixel. Since the screen can't draw there it would either return an error, not do anything at all, or slam the pixel into one of the four adjacent pixels that it is touching. None of these are options we want. In fact, what we'd like is for the screen pixels that our black pixel is touching to approximate its position by using color differences. So let's see what the "idealized" approximation result we want would look like.  You may be saying, but grim now the pixel is twice as big and twice as long, how is that any sort of approximation? Well if you look closely at the first picture and at the second picture you can notice that there is in fact a difference between the colors of the pixels. The one pixel in the first pictures has a color code of 0x000000ff, however, the pixels in the second image all have a color code of 0xc0c0c0ff. So what is it I did there? Essentially what I did was approximate the black pixel's position by filling the pixels that are bordering it with a blend of the pixel color and the background we're drawing on. Think that's a poor approximation? Well let's look at the real world size and you tell me how terrible an approximation it is.  I don't think your eye can readily discern that that's four pixels as opposed to one, but if it can well then may I suggest another line of work, perhaps some sort of travelling appraiser? But I digress.
| |
|
|
|
|
|
|
|
14 Mar, 2009 - 03:16 PM
|
The first hurdle of my PNG library for PHP was figuring out the file format of a PNG. That wasn't too bad considering the specification is made available by the W3C (I'll discuss that in another entry). The next most obvious step is to add a pixel to the image, which I did. Second is to make a line. That was done also. However, more and more research has shown that quality graphics can't be created so easily. In order to make graphics that look appealing to the human eye a technique known as antialiasing is required. There is an explanation on it in Wikipedia (which I don't readily understand). So, for the sake of my own reference I will describe antialiasing in the way that makes sense to me and I hope to anyone who reads this. So let's just talk about the concept in general terms. The human eye sees lots of colors, and we take it for granted that when two different colors are side by side, our eye does a little bit of blending i.e. it takes the average of the two colors within the areas where they touch. Its the exact same thing that happens when you take a photograph and why you can't PRECISELY tell where one object starts and one object ends. Think of a person standing in front of a green screen and then using the magic wand to select that person, some little trace elements of green would be left on the outline of the person (unless you modified this by adjusting the tolerance or removing them or darkening them somehow). Its more noticeable when you zoom in closely. Here's an example of this:  At its normal resolution it seems just fine. However if you zoom in anywhere along this young lady's profile you'll see that she's in fact blending (however slightly with the green background). Is this antialiasing? No, we don't call what our eye or camera does antialiasing. We call the procedure by which we approximate what the human eye does when drawing on a computer screen (in this case a PNG image) antialiasing. In other words getting the computer to blend colors in a way that's more natural to the human eye so as to eliminate what are typically called "jaggies". Let's show an example to get a better idea.  Visually you can tell the difference. The lines on the left look more choppy/jagged, while the ones on the right somehow seem less choppy/jagged. The difference is subtle, but noticeable, this is because the lines on the right that are tilted at an angle also have subtle shades of gray along their perimeter that blend them with the white background. Hopefully, you now have a better understanding if any of antialiasing. To create more elegant computer graphics it is necessary to antialias, because our eyes don't see things in a rectangular grid (your computer screen is just a bunch of square pixels) nor do they distinguish between colors as discretely as each pixel on a computer screen does. With this powerful idea in our toolbelts we now provide ourselves with an illusion that can fool the eye into thinking its seeing something more analog/continuous as opposed to something more digital/discrete.
| |
|
|
|
|
|
|
|
10 Jan, 2009 - 12:46 AM
|
I may have written about this previously somewhere, but whatever the case I realized that my pando search engine site had actually been used for something recently, but it was producing some errors. So I revamped the look of the site and now instead of using the XML documents provided by the Pando web developer api, I cache the results into a Mimesis database (updating them if they've gone past the expiration date of the package). I still haven't reimplemented the search, but submitting and browsing of Pando packages is currently working. Hopefully, people who use Pando for distributing their files will find some use out of the site. I for one am fascinated by the fact that Pando operates on a modified torrent protocol along with its own servers to speed up delivery of content. Anyways, if I did mention the site before, then I hope you enjoy the new look.
| |
|
|
|
|
|
|
|
3 Jan, 2009 - 12:16 PM
|
Et tu Dreame? I've been developing some websites recently and realized that I've been using that latin filler text that begins with "Lorem Ipsum" frequently in order to help with layout and such. I've since gotten bored of seeing the same text over and over so I figured, why not make my own random generator of latin text? So I did. I used Mimesis as the database backend to store the word list and then just a simple script to generate the number of paragraphs I want. Check it out here.
| |
|
|
|
|
|
|
|
27 Nov, 2008 - 09:22 PM
|
Just wanted to let folks know that I made the code available for the shoutbox I've been using on the Mimesis site. Also, while chatting around in the IRC channel it occurred to me that DIC doesn't keep a log of the chats. So I created an IRC Chat Logger bot that uses a Mimesis database to track all public conversations within the channel  . Of course it requires fsockopen to be enabled so chances are you'd have to run it off your local server.
| |
|
|
|
|
|
|
|
21 Nov, 2008 - 02:32 PM
|
Sweet, now I've got a cooler looking URL for my Mimesis site. It's http://mimesys.co.cc/. Sadly, mimesis.co.cc was $3 as opposed to mimesys which was free. Since I'm a cheap pirate I'll deal with the incongruency. So all due credit to co.cc for giving away free domain names. Does that mean I'll be renaming to software? Quite possibly.
| |
|
|
|
|
|
|
|
19 Nov, 2008 - 12:05 AM
|
Interestingly enough I was written an e-mail recently in regards to a very old site I had up on the net. Namely, Grim's Hex Paper. Basically, I had played Dungeons and Dragons with some friends of mine. I've since grown weary of the RIDICULOUS amount of rules in it. However, I was intrigued by the fact that with all the rules they used a square grid for movement. To me the logical choice for a more realistic feel of combat (given radial distances) is a hexagonal map. I looked online and found some sites that actually created PDFs of hexagonal grids. Like this one. I was impressed by all the different grids you could create on that one site, but found the hexagonal lacking. Specifically, because I wanted something that would generate map-esque hexagonal grids. That's where Grim's Hex Paper True Type Font came in. I had big plans for it, all sorts of different tiles and everything, but never actually finished the font. However, the writer of said e-mail did point out to me that the link on the old site for the download was broken. So I managed to find it again and reupped it to the site. To any paper and pencil game enthusiasts out there feel free to help yourself to it. It's not complete but I think it's got quite a fair bit of neat stuff on it. For instance: - Grass tiles
- Water tiles
- Cobblestone tiles
- Brick tiles
- 3 different grid line styles
So it gives you room to generate some cool maps. It also has some stuff for creating walls and doorways (simplistic I grant you). Furthermore, the cobblestone and brick tiles are also provided as outlines so as to save on ink. I actually posted on here once about it, but I was inquiring about a technical issue of the font itself that I couldn't solve (and still haven't).
| |
|
|
|
|
|
|
|
3 Sep, 2008 - 03:10 PM
|
Well if you visited my page recently you may have noticed that I was trying to work an AJAX ShoutBox onto my Contact page (of my own design of course). When I tested locally on my computer everything worked fine and dandy. However, on the net it kept tossing errors. I somehow came to the conclusion that it was a problem with the asynchronous javascript requests so I said screw it I'm not gonna waste more time trying to figure out the gawbawge that is JavaScript. I loathe it anyways. So I just slammed an iframe in there which does the job far more elegantly and relies solely on PHP. Of course iframe isn't XHTML 1.0 Strict so I had to use the object tag instead. Post some shouts peoplez.
| |
|
|
|
|
|
|
|
20 Aug, 2008 - 06:33 PM
|
Added a geolocation tutorial to the Mimesis site. Check it out if you want to know who's visiting your site from where.
| |
|
|
|
| |
|