//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "nedodefs.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define FLOAT int
#define SQRTFIXK 256L
#define FIXK (SQRTFIXK*SQRTFIXK)
#define spheres 2
FLOAT cx[spheres] = {
(FLOAT)(-30*FIXK/100), (FLOAT)(90*FIXK/100)
};
FLOAT cy[spheres] = {
(FLOAT)(-80*FIXK/100), (FLOAT)(-110*FIXK/100)
};
FLOAT cz[spheres] = {
(FLOAT)(300*FIXK/100), (FLOAT)(200*FIXK/100)
};
FLOAT r[spheres] = {(FLOAT)(60*FIXK/100), (FLOAT)(20*FIXK/100)};
FLOAT q[spheres];
FLOAT projx[spheres];
FLOAT projy[spheres];
FLOAT projr[spheres];
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
FLOAT umul(FLOAT a,FLOAT b)
{
RETURN ((a>>8) * (b>>8));
}
FLOAT mul(FLOAT a,FLOAT b)
{
FLOAT res;
FLOAT ia;
FLOAT ib;
ia = a;
ib = b;
IF (ia < 0 /*>= 0x80000000L*/) {ia = -ia;};
IF (ib < 0 /*>= 0x80000000L*/) {ib = -ib;};
res = umul(ia, ib);
IF ((a^b) < 0 /*>= 0x80000000L*/) {res = -res;};
RETURN res;
}
FLOAT udiv(FLOAT a,FLOAT b)
{
FLOAT ib;
ib = b>>8;///SQRTFIXK;
if (ib == 0L) {
ib = 1L;
};
RETURN ((a / ib)<<8/**SQRTFIXK*/);
}
FLOAT idiv(FLOAT a,FLOAT b)
{
FLOAT res;
FLOAT ia;
FLOAT ib;
ia = a;
ib = b;
IF (ia < 0 /*>= 0x80000000L*/) {ia = -ia;};
IF (ib < 0 /*>= 0x80000000L*/) {ib = -ib;};
res = udiv(ia, ib);
IF ((a^b) < 0 /*>= 0x80000000L*/) {res = -res;};
RETURN res;
}
FLOAT add(FLOAT a,FLOAT b)
{
RETURN (a + b);
}
FLOAT mul2(FLOAT a)
{
RETURN add(a,a);
}
FLOAT sub(FLOAT a,FLOAT b)
{
RETURN (a - b);
}
FLOAT neg(FLOAT a)
{
RETURN (-a);
}
UINT lsqrt(FLOAT arg)
{
BYTE count=0x10;
UINT res=0;
UINT tmp=0;
IF (arg!=0L) {
/* IF (!(arg&0xFF000000L)) {
arg = arg<<8;
count-=4;
};*/
res = 1;
WHILE ((tmp<1)&&(count!=0x00)){
DEC count;
IF (arg&0x80000000L) {tmp|=2;};
IF (arg&0x40000000L) {tmp|=1;};
arg = arg << 2L;
};//яюшёъ яхЁтющ 1-√
DEC tmp;
WHILE (count!=0x00) {
tmp = tmp << 2;
res = res + res; //res << 1;
DEC count;
IF (arg&0x80000000L) {tmp = tmp | 2;};
IF (arg&0x40000000L) {tmp = tmp | 1;};
arg = arg << 2L;
IF (tmp >= ((res<<1)|1)) {
tmp = tmp - ((res<<1)|1);
res = res | 1;
};
};
};
RETURN res;
}
FLOAT root(FLOAT a)
{
RETURN ((FLOAT)lsqrt(a)*SQRTFIXK);
}
FLOAT fract(FLOAT a)
{
RETURN ( a & (FIXK/2) /*!= 0L*/ );
}
BOOL positive(FLOAT a)
{
RETURN (a >= 0 /*< 0x80000000L*/);
}
BOOL less(FLOAT a, FLOAT b)
{
RETURN ((unsigned int)a < (unsigned int)b);
}
void TForm1::prhex(AnsiString name, int a)
{
AnsiString s = "";
AnsiString sc = " ";
char c;
for (int i = 0; i < 8; i++) {
c = (a & 0x0f) + '0';
if (c>=('0'+10)) c = c+'a'-('0'+10);
sc[1] = c;
s = sc + s;
a = a >> 4;
};
Memo1->Lines->Add(name+s);
}
PROC TForm1::tracepixel(int i,int j)
{
BYTE n;
BYTE k;
FLOAT s;
FLOAT px;
FLOAT py;
FLOAT pz;
FLOAT sc;
FLOAT aa;
FLOAT bb;
FLOAT pp;
FLOAT nx;
FLOAT ny;
FLOAT nz;
FLOAT nn;
FLOAT u;
FLOAT v;
FLOAT l;
FLOAT x;
FLOAT y;
FLOAT z;
FLOAT dx;
FLOAT dy;
FLOAT dz;
FLOAT dd;
#define GROUND 0xfe
#define SKY 0xff
#define EYEX (FLOAT)(30*FIXK/100)
#define EYEY (FLOAT)(-50*FIXK/100)
#define EYEZ (FLOAT)(0*FIXK/100)
x = EYEX;
y = EYEY;
z = EYEZ;
#define KVECTOR 64L
// dx = (FLOAT)((FLOAT)(j-128)*FIXK/KVECTOR);
// dy = (FLOAT)((FLOAT)(88-i)*FIXK/KVECTOR);
// dz = (FLOAT)((FLOAT)(300)*FIXK/KVECTOR);
#define MULVECTOR 0x0400L
dx = mul(((FLOAT)(j)-(FLOAT)(128))*FIXK, MULVECTOR);
dy = mul(((FLOAT)(88)-(FLOAT)(i))*FIXK, MULVECTOR);
dz = mul((FLOAT)(256)*FIXK, MULVECTOR);
//prhex("dx=",dx);
//prhex("dy=",dy);
//prhex("dz=",dz);
dd = add(mul(dx,dx),add(mul(dy,dy),mul(dz,dz))); //dx*dx+dy*dy+dz*dz;
//prhex("dx*dx=",mul(dx,dx));
//prhex("dy*dy=",mul(dy,dy));
//prhex("dz*dz=",mul(dz,dz));
//prhex("dd=",dd);
L100:
IF (positive(y) || !positive(dy)) {
n = SKY;
s = 0x7fffffffL;
}ELSE {
n = GROUND;
s = neg(idiv(y, dy)); //-y/dy; //???
};
//prhex("s=",s);
k = 0x00;
REPEAT { //ш∙хь ёЇхЁє, эр ъюЄюЁє■ ёьюЄЁшь (хёыш хёЄ№)
px = sub(cx[k], x); //c[k][0]-x;
//prhex("px=",px);
py = sub(cy[k], y); //c[k][1]-y;
//prhex("py=",py);
pz = sub(cz[k], z); //c[k][2]-z;
//prhex("pz=",pz);
#define FIXX 256
#define SCRX (((FLOAT)(j)-(FLOAT)(128))*FIXX)
#define SCRY (((FLOAT)(88)-(FLOAT)(i))*FIXX)
IF (!(
(SCRX >= sub(projx[k],projr[k]))
&&(SCRX < add(projx[k],projr[k]))
&&(SCRY >= sub(projy[k],projr[k]))
&&(SCRY < add(projy[k],projr[k]))
// &&((i^j)&1)
)) {
//Image1->Canvas->Pixels[j][175-i] = 0xff7fff;
goto L200; //эх Єр ёЇхЁр
//goto RETURNME;
};
pp = add(mul(px,px),add(mul(py,py),mul(pz,pz))); //px*px+py*py+pz*pz;
//prhex("px*px=",mul(px,px));
//prhex("py*py=",mul(py,py));
//prhex("pz*pz=",mul(pz,pz));
//prhex("pp=",pp);
sc = add(mul(px,dx),add(mul(py,dy),mul(pz,dz))); //px*dx+py*dy+pz*dz;
//prhex("sc=",sc);
IF (!positive(sc)) {
goto L200; //эх Єр ёЇхЁр
};
bb = idiv(mul(sc,sc),dd); //sc*sc/dd;
//prhex("bb=",bb);
aa = q[k]-pp+bb; //add(sub(q[k],pp),bb); //q[k]-pp+bb;
//prhex("aa=",aa);
IF (!positive(aa)) {
goto L200; //эх Єр ёЇхЁр
};
sc = idiv(sub(root(bb),root(aa)),root(dd)); //(sqrt(bb)-sqrt(aa))/sqrt(dd);
//prhex("scp=",sub(root(bb),root(aa)));
//prhex("scq=",root(dd));
//prhex("sc=",sc);
// IF (less(sc,s) /*|| (n >= 0x80)*/) { //эр°ыш ёЇхЁє
n = k;
s = sc;
goto LFOUND;
// };
L200:
INC k;
}UNTIL (k == spheres);
IF (n == SKY) {goto RETURNME;}; //эхсю
LFOUND:
// Image1->Canvas->Pixels[j][175-i] = 0x007fff;
// goto RETURNME;
dx = mul(dx,s); //dx*s;
dy = mul(dy,s); //dy*s;
dz = mul(dz,s); //dz*s;
//prhex("dx=",dx);
//prhex("dy=",dy);
//prhex("dz=",dz);
dd = mul(dd,mul(s,s)); //dd*s*s;
//prhex("dd=",dd);
x = add(x,dx); //x+dx;
y = add(y,dy); //y+dy;
z = add(z,dz); //z+dz;
IF (n == GROUND) {goto L300;}; //чхьы
nx = sub(x,cx[n]); //x-c[n][0];
ny = sub(y,cy[n]); //y-c[n][1];
nz = sub(z,cz[n]); //z-c[n][2];
nn = add(mul(nx,nx),add(mul(ny,ny),mul(nz,nz))); //nx*nx+ny*ny+nz*nz;
//prhex("nn=",nn);
l = idiv(mul2(add(mul(dx,nx),add(mul(dy,ny),mul(dz,nz)))),nn); //2*(dx*nx+dy*ny+dz*nz)/nn;
//prhex("l=",l);
dx = sub(dx,mul(nx,l)); //dx-nx*l;
dy = sub(dy,mul(ny,l)); //dy-ny*l;
dz = sub(dz,mul(nz,l)); //dz-nz*l;
//prhex("dx=",dx);
//prhex("dy=",dy);
//prhex("dz=",dz);
goto L100; //юЄЁрцхэшх
L300: //чхьы
k = 0x00;
REPEAT {
u = sub(cx[k],x); //c[k][0]-x;
v = sub(cz[k],z); //c[k][2]-z;
IF (add(mul(u,u),mul(v,v)) <= q[k]) {goto RETURNME;}; //(u*u+v*v)
INC k;
}UNTIL (k == spheres);
IF (fract(x) != fract(z)) {Image1->Canvas->Pixels[j][175-i] = 0xffffff;}; //((x+100)-(int)(x+100)) //(z-(int)(z))
RETURNME:
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
BYTE i;
BYTE j;
BYTE k;
k = 0x00;
REPEAT {
q[k] = mul(r[k],r[k]); //r[k]*r[k];
INC k;
}UNTIL (k == spheres);
k = 0x00;
REPEAT {
projx[k] = idiv(sub(cx[k],EYEX), sub(cz[k],EYEZ));
projy[k] = idiv(sub(cy[k],EYEY), sub(cz[k],EYEZ));
projr[k] = idiv(r[k]*17/16, sub(cz[k],EYEZ)); //сюы№°х, яюЄюьє ўЄю "сюъ" ёЇхЁ√ ЄюЁўшЄ чр яЁюхъЎш■
prhex("projx=",projx[k]);
prhex("projy=",projy[k]);
prhex("projr=",projr[k]);
INC k;
}UNTIL (k == spheres);
i = 0x00;
REPEAT {
j = 0x00;
REPEAT {
Image1->Canvas->Pixels[j][175-i] = 0x000000;
tracepixel(i,j);
INC j;
}UNTIL (j == (BYTE)255);
INC i;
}UNTIL (i == (BYTE)175);
cx[0] = cx[0]+(FLOAT)(10*FIXK/100);
cz[1] = cz[1]+(FLOAT)(30*FIXK/100);
Memo1->Lines->Add(IntToStr(0x100000000000000 >> 16));
}
//---------------------------------------------------------------------------