Schweet! got it.
Here's the source code for the "Squig" class.
Uhh, the only API specific thing is the draw function. I used SDL for the demo, but DGDK could be used incredibly easily. In the following snippet, I just replaced all the "line" commands with "dbLine"... I think that would work in DGDK.
Squig.h
#ifndef SQUIG_H
#define SQUIG_H
#include <stdlib.h>
#include "vector2.h"
class Squig
{
//---------------------3-------
//------/\-------\____/\____/--
//-----/1-\-------\3-/--\2-/---
//--1-/____\-2-----\/-4--\/----
//---/\-4--/\-----2-\____/-1---
//--/2-\--/3-\-------\1-/------
//-/____\/____\-------\/-------
//------3----------------------
private:
static vector2 drawposfrom;
static vector2 drawposto;
static bool isDrawing;
vector2 p1; //vertice next to sub triangle 1
vector2 p2; //vertice next to sub triangle 2
vector2 p3; //vertice next to sub triangle 3
Squig* subNodes;
Squig* superNode;
int subnum;
int sidefrom;
int sideto;
int cellfrom;
int cellto;
int getRandCellTouchingSide(int sidenum);
int getStartCellEndSide();
int getEndCellStartSide();
int getNextCellTo();
int div_Node(int startcell);
vector2 getsubp1(int node);
vector2 getsubp2(int node);
vector2 getsubp3(int node);
vector2 getAvg();
public:
Squig();
~Squig();
Squig(vector2 vert1,vector2 vert2, vector2 vert3);
Squig(vector2 vert1,vector2 vert2, vector2 vert3,Squig* superNode,int sidefrom, int sideto);
void refine();
void drawSquig();
};
#endif // SQUIG_H
Squig.cpp
#include "Squig.h"
void console_out(int n);
vector2 Squig::drawposfrom=vector2(0,0);
vector2 Squig::drawposto=vector2(0,0);
bool Squig::isDrawing=false;
Squig::Squig(){}
Squig::~Squig()
{
delete[] subNodes;
}
Squig::Squig(vector2 vert1,vector2 vert2, vector2 vert3)
{
p1=vert1; p2=vert2; p3=vert3;
superNode=NULL;
subNodes=NULL;
subnum=0;
sidefrom=floor(((rand()*1.0)/(RAND_MAX+1))*3)+1;
int way=(rand()/2)>RAND_MAX/2?1:-1;
sideto=sidefrom+way;
if(sideto==0)
sideto=3;
if(sideto==4)
sideto=1;
cellfrom=-1;
cellto=-1;
}
Squig::Squig(vector2 vert1,vector2 vert2, vector2 vert3,Squig* superNode,int sidefrom, int sideto)
{
p1=vert1; p2=vert2; p3=vert3;
this->superNode=superNode;
subNodes=NULL;
subnum=0;
this->sidefrom=sidefrom;
this->sideto=sideto;
cellfrom=-1;
cellto=-1;
}
int Squig::div_Node(int startcell)
{
if(subnum>0)
{
int newstartcell=startcell;
for(int x=0;x<subnum;x++)
newstartcell=subNodes[x].div_Node(newstartcell);
return newstartcell;
}
else
{
if(startcell==-1)
{
startcell=getRandCellTouchingSide(sidefrom);
}
int endcell=getRandCellTouchingSide(sideto);
cellfrom=startcell;
cellto=endcell;
if(startcell==endcell)
{
subNodes=new Squig[1];
subNodes[0]=Squig(getsubp1(startcell),getsubp2(startcell),getsubp3(startcell),this,sidefrom,sideto);
subnum=1;
}
else
{
subnum=3;
subNodes=new Squig[3];
subNodes[0]=Squig(getsubp1(startcell),getsubp2(startcell),getsubp3(startcell),this,sidefrom,getStartCellEndSide());
subNodes[1]=Squig(getsubp1(4), getsubp2(4), getsubp3(4), this,getStartCellEndSide(),getEndCellStartSide());
subNodes[2]=Squig(getsubp1(endcell), getsubp2(endcell), getsubp3(endcell), this,getEndCellStartSide(),sideto);
}
return getNextCellTo();
}
}
vector2 Squig::getsubp1(int node)
{
switch(node)
{
case 1:
return p1;
case 2:
return (p1+p2)/2;
case 3:
return (p1+p3)/2;
case 4:
return (p2+p3)/2;
}
return vector2(-1000,-1000);
}
vector2 Squig::getsubp2(int node)
{
switch(node)
{
case 1:
return (p1+p2)/2;
case 2:
return p2;
case 3:
return (p2+p3)/2;
case 4:
return (p1+p3)/2;
}
return vector2(-1000,-1000);
}
vector2 Squig::getsubp3(int node)
{
switch(node)
{
case 1:
return (p1+p3)/2;
case 2:
return (p2+p3)/2;
case 3:
return p3;
case 4:
return (p1+p2)/2;
}
return vector2(-1000,-1000);
}
vector2 Squig::getAvg()
{
return (p1+p2+p3)/3.0;
}
void Squig::refine()
{
div_Node(-1);
}
void Squig::drawSquig(SDL_Surface* drawto)
{
if(subnum==0)
{
SDL_Color mycol={0,0,255};
line(p1.x,p1.y,p2.x,p2.y,mycol,drawto);
line(p2.x,p2.y,p3.x,p3.y,mycol,drawto);
line(p3.x,p3.y,p1.x,p1.y,mycol,drawto);
if(isDrawing)
{
drawposto=getAvg();
//line(drawposfrom.x,drawposfrom.y,drawposto.x,drawposto.y,mycol,drawto);
drawposfrom=drawposto;
} else {
isDrawing=true;
drawposfrom=getAvg();
}
} else {
for(int x=0;x<subnum;x++)
subNodes[x].drawSquig(drawto);
}
if(superNode==NULL)
{
isDrawing=false;
}
}
int Squig::getNextCellTo()
{
switch(cellto)
{
case 1:
return sideto==1?2:3;
case 2:
return sideto==1?1:3;
case 3:
return sideto==2?1:2;
}
return 0;
}
int Squig::getRandCellTouchingSide(int sidenum)
{
bool n=(rand()%2)==1?true:false;
switch(sidenum)
{
case 1:
return n?1:2;
case 2:
return n?3:1;
case 3:
return n?2:3;
}
return 0;
}
int Squig::getStartCellEndSide()
{
switch(cellfrom)
{
case 1:
return 3;
case 2:
return 2;
case 3:
return 1;
}
return 0;
}
int Squig::getEndCellStartSide()
{
switch(cellto)
{
case 1:
return 3;
case 2:
return 2;
case 3:
return 1;
}
return 0;
}
Aaaand the vector class I use is as follows:
vector2.h
#ifndef VECTOR2_H
#define VECTOR2_H
#include <iostream>
class vector2
{
public:
float x;
float y;
vector2();
vector2(const float& a,const float& b);
vector2 operator+ (const vector2& b) const; //vector addition
vector2& operator+= (const vector2& b);
vector2 operator- (const vector2& b) const; //vector subtraction
vector2& operator-= (const vector2& b);
vector2 operator* (const float& b) const; //vector scalar multiplication
vector2& operator*= (const float& b);
vector2 operator/ (const float& b) const; //vector scalar division
vector2& operator/= (const float& b);
float operator* (const vector2& b) const; //dot product
void normalize();
void normalize(const float& dist);
vector2 normalized() const;
vector2 normalized(const float& dist) const;
float length() const;
};
vector2 operator* (const float& b, const vector2& c);
std::ostream& operator<<(std::ostream& out, const vector2& c);
vector2 lerp(double t,const vector2& vec1,const vector2& vec2);
vector2 qerp(double t,const vector2& vec0,const vector2& vec1,const vector2& vec2,const vector2& vec3);
#endif // VECTOR2_H
vector2.cpp
#include "vector2.h"
#include <math.h>
#include <iostream>
vector2::vector2()
{
x = y = 0.0f;
}
vector2::vector2(const float& a,const float& b)
{
x=a;
y=b;
}
vector2 vector2::operator+ (const vector2& b) const
{
vector2 temp;
temp.x=x+b.x;
temp.y=y+b.y;
return temp;
}
vector2& vector2::operator+= (const vector2& b)
{
if(this!=&b)
{
x=x+b.x;
y=y+b.y;
}
return *this;
}
vector2 vector2::operator-(const vector2& b) const
{
vector2 temp;
temp.x=x-b.x;
temp.y=y-b.y;
return temp;
}
vector2& vector2::operator-=(const vector2& b)
{
if(this!=&b)
{
x=x-b.x;
y=y-b.y;
}
return *this;
}
float vector2::operator* (const vector2& b) const
{
return (x*b.x+y*b.y);
}
vector2 vector2::operator* (const float& b) const
{
vector2 temp;
temp.x=x*b;
temp.y=y*b;
return temp;
}
vector2& vector2::operator*= (const float& b)
{
x=x*b;
y=y*b;
return *this;
}
vector2 vector2::operator/ (const float& b) const
{
vector2 temp=vector2(0.0f,0.0f);
if(b>0)
{
temp.x=x/b;
temp.y=y/b;
}
return temp;
}
vector2& vector2::operator/= (const float& b)
{
if(b>0)
{
x=x/b;
y=y/b;
}
return *this;
}
void vector2::normalize()
{
float dist = sqrt(x*x+y*y);
x/=dist;
y/=dist;
}
void vector2::normalize(const float& dist)
{
x/=dist;
y/=dist;
}
vector2 vector2::normalized() const
{
float dist = sqrt(x*x+y*y);
return vector2(x/dist,y/dist);
}
vector2 vector2::normalized(const float& dist) const
{
return vector2(x/dist,y/dist);
}
float vector2::length() const
{
return sqrt(x*x+y*y);
}
std::ostream& operator<<(std::ostream& out, const vector2& c)
{
out << '(' << c.x << ',' << c.y << ')' ;
return out;
}
vector2 operator* (const float& b, const vector2& c)
{
vector2 temp;
temp.x=c.x*b;
temp.y=c.y*b;
return temp;
}
vector2 lerp(double t,const vector2& vec1,const vector2& vec2)
{
return (vec2-vec1)*t+vec1;
}
vector2 qerp(double t,const vector2& vec0,const vector2& vec1,const vector2& vec2,const vector2& vec3)
{
double t2=t*t;
vector2 a0=vec3-vec2-vec0+vec1;
vector2 a1=vec0-vec1-a0;
vector2 a2=vec2-vec0;
return a0*t*t2+a1*t2+a2*t+vec1;
}
[edit]
Oh, and of course, the download link to the compiled program. Press "0" to iterate.
http://www.neurofuzzydev.com/downloads/C++/squig.rar