xoxosvst

dsp blog for xoxos.net

c++ check if 2d line segments cross

leave a comment »

very simple, posting it here is more or less needless. you can check which side of an infinite line a point is on using the cross product. so check to see if the points of segment A are on different sides of the line defined by segment B. if they are, check to see if the points of segment B are on different sides of the line defined by segment A.

this alg isn’t particularly concerned about if the segments are on the same line 🙂

bool segmentscross(point2 point00, point2 point01, point2 point10, point2 point11) {
 bool check0 = 0;
 bool check1 = 0;
 point2 param00 = point00 – point10; point2 param01 = point01 – point10; point2 param11 = point11 – point10;
 if (param00.cross(param11) > 0) check0 = 1;
 if (param01.cross(param11) > 0) check1 = 1;
 if (check0 == check1) return 0;
 check0 = check1 = 0;
 param00 = point10 – point00; param01 = point11 – point00; param11 = point01 – point00;
 if (param00.cross(param11) > 0) check0 = 1;
 if (param01.cross(param11) > 0) check1 = 1;
 if (check0 == check1) return 0;
 return 1;
}

Written by xoxosvst

October 24, 2013 at 4:02 am

Posted in Uncategorized

Tagged with , ,

c++ concise win32 game source

leave a comment »

wordpress isn’t playing friendly right now so this will be a paste dump, soz if the formatting isn’t perfect.

i haven’t seen much open source game/multimedia for win32 that i consider readable, so even though this is new ground for me, i thought i’d share what i’ve got. don’t consider this material authoritative, but it does actually work.

the source is a few short documents – i’m used to c-based, one document programming, with one character variable names – stuff you can read quickly. the intent here is to provide a minimal framework to help other people turn their ideas into applications. apart from the main document which has the win32 stuff, there are five short headers – one for global variables, one for audio (which can be de-commented to produce a 440hz sine), one with a few basic vector algorithms (2d point class, point to line check), 2d vector graphics (aa line and circle/filled circle), and one that does the “game turn”. it’s not optimised because eg. the triangle rotation calcs are performed on each frame regardless of if anything’s moved, but you should be able to skim over them to get an idea of where everything is pretty quickly so you know at least one way to do things.

the app draws an asteroids style ship which can be rotated and thrusted with the arrow keys, and colours each background pixel red and green to indicate which side of the ship it’s on. you’ll probably fly it off the edge of the screen, hit escape to quit.

as said, this is new for me, hopefully it’s solid enough to help others get a foothold and improve on it. you can stop reading unless you want the particulars of the line algorithm.

http://xoxos.net/software/vector.zip

the first aa code i wrote was for a line algorithm. i intended to expand the code for variable thickness, but endpoints are a hassle, so it’s a “1 pixel width only” alg now (you can expand the ‘softness’ of the aa by dropping the ‘margin’ coefficient to give the graphics a different feel and make thicker lines). anyway – my alg has two major differences from Wu – atan() is used to calculate the thickness of the line based on it’s angle (it can be more than the 2 pixels Wu uses) – and a nonlinearity is used to boost the line pigment which reduces stepping. i was pretty happy with it and call it the pothead line algorithm.

yesterday i noticed that there was a bug in one of the endpoint routines that was drawing over pixels in another location so i rewrote it instead of trying to fix it, because i’d used round-down INT conversion. it’s now quite concise and the “line” is drawn from the start to end pixels (endpoints are fractional), which means that the pixels at the ends aren’t aa’ed for their “perpendicular” distance from the line. they’re more intensive the way i do it (fully calculating the distance to each pixel around the ends) and i noticed it was working pretty good without endpoints anyway. i intend to use my aa lines for wireframe/vector style stuff, where lines will often be drawn end to end, so spending all that effort is hardly worth it.

here’s what i can tell you about writing aa line algorithms –

as said, the first one i wrote lazily and passed floats to ints by rounding down. i tested the alg by rotating a radial line around a fixed point. when it passed WNW to WNN there was a slight jump because of this. i figured that wouldn’t be too overt, but it was, kinda, when i put the triangle ship together.

when i wrote the new pothead line algorithm i was prudent about handling the 0.5f “center” of each pixel, but still, this is the pothead line algorithm, so i didn’t want to get too involved with it and did it off head. i have yet to perform the spinning line test with it, having switched to the spinning spaceship triangle. in this case, when the triangle points SE, the front edges kind of get wider for a few degrees. it’s a much smaller artifact, you need to make the ship bigger (say 40 pixels instead of 10) to really see it. given the method i wouldn’t be surprised if it’s due to the floating point. or maybe i need to draw some diagrams or something.

at least you can turn this app quickly into something like pong, where aa isn’t an issue 🙂

Written by xoxosvst

October 11, 2013 at 12:36 am

c++ antialiased circle algorithm

with one comment

i released a very minimal c++ win32 graphics&audio source on the software page at xoxos.net a few days ago with an antialiased line algorithm. i’d read about the wu line and seen the results and decided to do it my way first.. i use more than 2 pixels and a nonlinearity for the edge which is smoother than wu. it looks keen and it’s homemade.. only “feature” is a slight shift when switching from NWN to NWW directions, likely because i didn’t add 0.5 when converting to INT, which is a task for another day as it looks nice otherwise.

got to circles, my method inherits some of the methods i used for lines. this is pretty much a/the brute force algorithm as a sqrt() is performed for every pixel, and an additional sqrt() for every row. the benefit of this is that subpixel centers may be assigned so it can’t be optimised by symmetry.

my antialiasing uses a margin scaling coefficient, eg. once the distance between a pixel and a circle/line is resolved, this distance is then scaled before antialiasing is conducted.. which softens the boundary, or makes it more steppy if the coefficient increases the relative distance… 0.75 looks real nice to me along with the nonlinearity. the distance this affects in pixels is of course the inverse 1/margin, or 1.33 pixels if using 0.75.

circle basics:
radius = sqrt(x*x + y*y)   and so   y = sqrt(radius*radius – x*x) 

my technique is pretty simple – compute an outside circle and an inside circle which are larger/smaller by the inverse margin coefficient (eg. radius +/- 1.33), thereby reducing the amount of pixels that need to be run.

much of the length of this script is actually reading the preexistent pixel colour. once you get the idea, it’s probably easier to write it yourself than untangle my code.

as you may guess, reducing margin to 0.25 fades/blurs graphics by 4 pixels.. 0.001 by 1000 pixels and so forth.. and, once you get the idea, you can easily modify this technique to give the circle thickness. like the line algorithm, i am suggesting that this method be known as the pothead antialiased circle algorithm.

soz for the mess, i am not 1337 wordpresser, code tags put the whole lot on one line..

void circleaa(point2 param, float radius, int bgrr, int bgrg, int bgrb) {
 if (radius <= 0.f) return;
 short int bgb, bgg, bgr;
 float radiuso = radius + margini; // outside radius
 float radiusi = radius – margini;
 float radiusi2 = radiusi * radiusi;
 float radiuso2 = radiuso * radiuso;
 int cxi = floor(param.x); // center int
 int cyi = floor(param.y);
 float cxd = param.x – cxi;
 float cyd = param.y – cyi;
 o = radiuso + margini;
 int lowm = floor(-o); int highm = o;
 for (int dox = lowm; dox <= highm; dox++) {
  int pixx = cxi + dox;
  if (pixx > -1 && pixx < dispx) {
   float dx = dox – cxd; dx *= dx;
   float boy = radiuso2 – dx;
   if (boy > 0) {
    boy = sqrt(boy);
    int lowy = floor(-boy); int highy = boy; highy += 2;
    float biy = radiusi2 – dx;
    if (biy > 0) {
     biy = sqrt(biy);
     int lowi = floor(-biy); int highi = biy; lowi += 2;
     for (int doy = lowy; doy < lowi; doy++) {
      int pixy = cyi + doy;
      if (pixy > -1 && pixy < dispy) {
       float dy = doy – cyd;
       dy = sqrt(dx + dy * dy);
       dy -= radius; if (dy < 0) dy = -dy; dy = 1.f – dy * margin;
       if (dy > 0) {
        dy *= pih; dy = dy – dy * dy * dy * 0.1472725f; float dy0 = 1.f – dy;
        int dopix = (doy + cyi) * dispx + dox + cxi;
        bgb = (byte)framebuf[dopix];
        bgg = (byte)(framebuf[dopix]>>8);
        bgr = (byte)(framebuf[dopix]>>16);
        o = bgrb * dy + bgb * dy0; o < 255.f ? bgb = (int)o : bgb = 255;
        o = bgrg * dy + bgg * dy0; o < 255.f ? bgg = (int)o : bgg = 255;
        o = bgrr * dy + bgr * dy0; o < 255.f ? bgr = (int)o : bgr = 255;
        *(framebuf + dopix) = RGB(bgb,bgg,bgr);
     } } }
     for (int doy = highi; doy < highy; doy++) {
      int pixy = cyi + doy;
      if (pixy > -1 && pixy < dispy) {
       float dy = doy – cyd;
       dy = sqrt(dx + dy * dy);
       dy -= radius; if (dy < 0) dy = -dy; dy = 1.f – dy * margin;
       if (dy > 0) {
        dy *= pih; dy = dy – dy * dy * dy * 0.1472725f; float dy0 = 1.f – dy;
        int dopix = (doy + cyi) * dispx + dox + cxi;
        bgb = (byte)framebuf[dopix];
        bgg = (byte)(framebuf[dopix]>>8);
        bgr = (byte)(framebuf[dopix]>>16);
        o = bgrb * dy + bgb * dy0; o < 255.f ? bgb = (int)o : bgb = 255;
        o = bgrg * dy + bgg * dy0; o < 255.f ? bgg = (int)o : bgg = 255;
        o = bgrr * dy + bgr * dy0; o < 255.f ? bgr = (int)o : bgr = 255;
        *(framebuf + dopix) = RGB(bgb,bgg,bgr);
    } } } }
    else {
     for (int doy = lowy; doy < highy; doy++) {
      int pixy = cyi + doy;
      if (pixy > -1 && pixy < dispy) {
       float dy = doy – cyd;
       dy = sqrt(dx + dy * dy);
       dy -= radius; if (dy < 0) dy = -dy; dy = 1.f – dy * margin;
       if (dy > 0) {
        dy *= pih; dy = dy – dy * dy * dy * 0.1472725f; float dy0 = 1.f – dy;
        int dopix = (doy + cyi) * dispx + dox + cxi;
        bgb = (byte)framebuf[dopix];
        bgg = (byte)(framebuf[dopix]>>8);
        bgr = (byte)(framebuf[dopix]>>16);
        o = bgrb * dy + bgb * dy0; o < 255.f ? bgb = (int)o : bgb = 255;
        o = bgrg * dy + bgg * dy0; o < 255.f ? bgg = (int)o : bgg = 255;
        o = bgrr * dy + bgr * dy0; o < 255.f ? bgr = (int)o : bgr = 255;
        *(framebuf + dopix) = RGB(bgb,bgg,bgr);
} } } } } } } }

 

Written by xoxosvst

October 8, 2013 at 6:06 am

Posted in Uncategorized

Tagged with

fast 2d polygon rotation

leave a comment »

i’m fairly new at 2d vector graphics but haven’t seen this mentioned. the naive approach would be to rotate each vector using brute force..

newx = x * cos(angle) – y * sin(angle);

newy = x * sin(angle) + y * cos(angle);

 

given vector [x,y] you can define four ‘cardinal’ vectors by inverting and swapping the coefficients, eg. the two normals [-y,x] and [y,-x] and the inverse[-x,-y]. a cheaper method than rotating each point would be to rotate one point (say a unit vector), and map the polygon out using a cartesian grid. the four cardinal axes can be extended into space using vector scaling, vector addition and so forth.. eg. 135 degrees off the rotated vector can be achieved by summing a normal and the inverse, then scaling to 0.7071..

using a few such operations, perhaps with linear interpolation, and planning the polygons ahead of time with easily derived positions on a cartesian grid means that points after the first will require addition and multiplication instead of sine and cosine.

Written by xoxosvst

October 6, 2013 at 6:06 am

Posted in Uncategorized

Tagged with

note

with one comment

this is a developer’s blog, and this is a notable experience for a developer.

the vst scene ain’t what it used to be.. in the early 2000’s i could release blaster, or some plugin produced in a couple of hours that availed some simple yet otherwise unavailable process and you’d be guaranteed a party within five minutes of posting.

one of the big learning steps for me was releasing radian – there were a dozen pages of eager praise for the sound demos, the moment i released it everyone went to sleep, except for a few well-respected users.

i wonder, how is that? radian does something nothing else comes close to doing, it isn’t a solution for modeling *all* objects, but it does some things very well.

we’re all aware of the reality of detractive subterfuge in the marketplace, perhaps this was additive subterfuge. “where are my users? don’t people use drum sounds in music any more?” radian, 2011.

i sent out a beta to three people five days ago. understandably, two were too busy, the other told me it makes no sound. i *know* it’s going to make sound on someone’s system, i have yet to receive any intimation that such a thing has occured.

so i posted a public beta over 24 hours ago. at this point, there are over 400 views of the topic and i have garnered two statements of intent for further investigation.

 

which isn’t the same as actual use and verification, let alone the OMG THIS THING IS LIKE NOTHING ELSE EVER that, let’s be honest, the software warrants.

so, you decide for yourself how today, 400 views result in zero feedback, and even a year ago, 400 views would have been two pages of discussion and dozens of pms and other verifications of use.

 

because i’m tired of telling you why that is, and why it is such a consideration in the vst marketplace, and, larger scopes of consideration.

Written by xoxosvst

May 16, 2013 at 6:28 pm

Posted in Uncategorized

the badness of badness

leave a comment »

a few times a year i peep into the samples forum at kvr. while i have a fair (going on 2 decades online) collection, i rarely have them on a machine because i never use samples..

there are few sample products i find much application for besides removing capital from ambitious and inexperienced persons. one is percussion.

and often, as i have today, one encounters a collection of synthetic percussions.

while i am quick to condemn many participants in music software for their depraved cruelty towards living and breathing creatures, i prefer not to judge those who may simply be acting out of the same enthusiasm that such persons seek to exploit, let’s barge ahead anyway.

so: if you are thinking of releasing a pack of synthetic percussion (aah, memories..) allow me to inform you ahead of time that 95% of the content is likely total cack, a waste of everyone’s time (even your experience since you were thinking about how to make other people like things for money the whole time).

most synths do not have envelopes steep enough to use for patching kicks. the exponential contour of analogs simply cannot create an attack and release in one stage.

if you are adamant about this, may i suggest listening to a few vince clarke productions as he has an aged mastery of patching ‘real’ percussion (eg. snares). here’s a big hint if you can’t – think short. big, flabby synth snares with a long tail may sound like a neat synth patch, but the buzzyness you liked is useless as a snare and the attacks aren’t developed enough to truncate. those sounds will *never* be used in anyone’s music.

the hats are useless as well. when patching, you decided the timbre was noisy, and different from white noise, but eg. many are too grainy because of your focus on “interesting noise” when patching.

(then again.. i noticed the other day the 909 oh or crash ROM sounds like the stick hit twice.. never noticed that in the post filtered sound).

if you really don’t have a good idea of what a utilitarian synth percussion patch is like, aim for brevity. that will help you focus on improving what’s there.

same response to just about every synth pack i’ve heard since i released mine (which were only marginally more general purpose ftr) (except for the straight-off-the-box 808909 collection stuff.. they’re applicable but of course it’s straight profiteering and ought never be recompensed).

one of these days i’ll show them all. people rarely comment on percussion in my tracks, it’s probably because they’re patched so well (maybe not so much my kicks). eg. if i go through years of tracks and record all the hihat patches, people would probably think most were processed 909s et c.

i’m thinking of all the times i’ve heard better synthetic cymbals (ok, percussions in general) than mine. none of those times are associated with people who sell samples. the most useful synth hats in these collections are generally the highpassed synced stuff vince et al. use, which is where we get into that depravity thing again. synth1 and such are free.. there’s no need to buy a sample of a highpassed synced osc.

gosh! the extreme rightness of what i say, huh.

Written by xoxosvst

May 4, 2013 at 8:17 pm

Posted in Uncategorized

the goodness of goodness

leave a comment »

given my general character within the marketplace one may anticipate this praise of those who enable. my background has bridged cultures allowing me some face with the requisite academics for dsp. i cannot profess the mathematical rigor my seniors in the field do.

it is good. it is what i say and what you know and what *they* try to hide. hehehe. without the mathematical rigor i apply procedures perhaps “not even worth bothering with”.

it is good recently also. harvested 4 open source zero delay filter algorithms which are augmenting the “stuff i did”, which is under wraps atm, beyond opening a cache of unused methods which i think are kinda neato.

if it wasn’t for the enablers, my stuff would be scantily accoutred, where a platform was found at all.

for all this talk, once i have a free moment i’ll wrap some of the filters as SEMs and document some more stuff. then it will actually be good then.

Written by xoxosvst

April 30, 2013 at 1:00 am

Posted in Uncategorized