Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

2024 Participants: Hannah Ackermans * Sara Alsherif * Leonardo Aranda * Brian Arechiga * Jonathan Armoza * Stephanie E. August * Martin Bartelmus * Patsy Baudoin * Liat Berdugo * David Berry * Jason Boyd * Kevin Brock * Evan Buswell * Claire Carroll * John Cayley * Slavica Ceperkovic * Edmond Chang * Sarah Ciston * Lyr Colin * Daniel Cox * Christina Cuneo * Orla Delaney * Pierre Depaz * Ranjodh Singh Dhaliwal * Koundinya Dhulipalla * Samuel DiBella * Craig Dietrich * Quinn Dombrowski * Kevin Driscoll * Lai-Tze Fan * Max Feinstein * Meredith Finkelstein * Leonardo Flores * Cyril Focht * Gwen Foo * Federica Frabetti * Jordan Freitas * Erika FülöP * Sam Goree * Gulsen Guler * Anthony Hay * SHAWNÉ MICHAELAIN HOLLOWAY * Brendan Howell * Minh Hua * Amira Jarmakani * Dennis Jerz * Joey Jones * Ted Kafala * Titaÿna Kauffmann-Will * Darius Kazemi * andrea kim * Joey King * Ryan Leach * cynthia li * Judy Malloy * Zachary Mann * Marian Mazzone * Chris McGuinness * Yasemin Melek * Pablo Miranda Carranza * Jarah Moesch * Matt Nish-Lapidus * Yoehan Oh * Steven Oscherwitz * Stefano Penge * Marta Pérez-Campos * Jan-Christian Petersen * gripp prime * Rita Raley * Nicholas Raphael * Arpita Rathod * Amit Ray * Thorsten Ries * Abby Rinaldi * Mark Sample * Valérie Schafer * Carly Schnitzler * Arthur Schwarz * Lyle Skains * Rory Solomon * Winnie Soon * Harlin/Hayley Steele * Marylyn Tan * Daniel Temkin * Murielle Sandra Tiako Djomatchoua * Anna Tito * Introna Tommie * Fereshteh Toosi * Paige Treebridge * Lee Tusman * Joris J.van Zundert * Annette Vee * Dan Verständig * Yohanna Waliya * Shu Wan * Peggy WEIL * Jacque Wernimont * Katherine Yang * Zach Whalen * Elea Zhong * TengChao Zhou
CCSWG 2024 is coordinated by Lyr Colin (USC), Andrea Kim (USC), Elea Zhong (USC), Zachary Mann (USC), Jeremy Douglass (UCSB), and Mark C. Marino (USC) . Sponsored by the Humanities and Critical Code Studies Lab (USC), and the Digital Arts and Humanities Commons (UCSB).

Kittler's Raytracer -- Code Critique

Author: Friedrich Kittler
Year: early 1980s-2000s

Hardware: Pentium IV,
x86 family of processors
x87 family of floating point coprocessors
Languages: C and Assembly

/*
v. 3.57
31.07.11
PTRACE.PAS (c't 1 / 93,167ff.) Extended
Super ellipsoid, rotational body and procedural textures from povray3
DOS version no longer supported

compile:
Normal: xgraf xsuptrace ray.s matrices.s
// Option -DNEWFRESNEL: simplified Fresnel light from povray3
Option -DJITTER: fuzzy (and time-consuming) shadows
Option -DGAMMA: gamma correction
SVGALIB or DGA: picture.i ".equ XWINDOW, 1" change!

RUNTIME:
<xsuptrace 1>: reproducible noise for runtime tests

FEATURES:
All reflective surfaces can be switched to ReflectionMapping: what
then appears on its surface is a picture to be loaded. This feature
But users have to demand standard interfaces first.

Prompts (':') for scalars and vectors can be defined either with <w [eiter]>
or <n [on]> acknowledge or answer with a new input

3 constant objects: sky, hell, ground (which only allows plein-air images)
Any number of variable objects (limited only by memory)
As variable objects by default 2 balls and 1 other object each predefined
ned. But standard objects can be deleted again.
If more than the standard number is required by an object, inquire
Prompt the new coordinates.
All objects editable (constant only by reassignment of color to normal)
procedure, variable also by location and size).
Some exotic objects are scalable and rotatable. This will be expanded.
Any number of lamps, the first 2 predefined.
Surfaces 1. global, 2. individually assignable after assignment to objects.
LINUX: any size * .24f images can be loaded as 2D textures.

Objects as a ring list for faster intershade () (see Foley, p.
Lamps as a simply linked list.
Left-hand coordinate system: left <x <right, front <y <behind,
below <z <above.

NEW:
01.04.97: AttCol () - acceleration away - transparencies would be worse
07.04.98: individual Fresnel coefficients with individual dullness for
opaque, but metallic surfaces (so these coefficients TransC and
to overwrite the dullness transparently). That's physically correct
and, mirabile dictu, better than POVRAY3. Color charts (ColTabT) global
edierbar
Nov. 22, 1998: ReflV () after Glassner, Image Synthesis, p. 726, again in
Light () calculated per lamp
24.12.98: Object slice selectable; Unzipped DOS - *. 24f files are loadable
08.03.99: Experimental support for Ohta / Maekawa algorithm
01.09.01: DOS no longer supported
13.08.04: Init_Ohta () different, untested
24.10.08: Steel new to /usr/ich/laptop/xsuptrace.c

BUGS:
Spheres of stei, sup, sor determined very empirically
2DMapping on Steiner, Agnesi, SuperQuadrik and Drehkoerper only as a reflection
Map implements: the transformation (x, y, z) -> (u, v) would be hard
MapProc () and Init_Fresnel () are not prepared for multiple calls from xsuptrace
Editing boxes and pyramids still uneven
lambda and thin globally, not variable per surface
No transparency shading as in CALCNEW.C
For floating objects, NULL pointer errors are inevitable; you
Change a midpoint coordinate to small amounts
SOR orb is detected in Edit_Sor () instead of Gravity ()
Refractive indices do not depend on wavelengths of light
08.04.99: intershade () returns L-> Shad correctly, but the object cohesion
breaks again and again, slows down more
30.12.00: xgraf (gcc with optimization) can falsify the SOR curve if
in SorInput the difference quotient Dy / Dx (ie the slope between
two x fixed points) becomes too large.
09.09.03: Changes to transformation matrices only apply to gcc -g. dark
31.07.11: QuColProc () dare

HINTS:
Between internal data structures and user displays, complex conversion
take place; So do not patch global data!
*/

#define  SUPTRACE
#define  COLTABSIZE   127       // unter DOS ggf. kleiner     
#define  PIII                   // bei schlechterer CPU dringend aendern!

// CompileTime: Globale Zaehler, bei neuen Objekten oder Oberflaechen erhoehen

#define SurfCnt       27        
#define FormCnt       16

#include <time.h>
#define  SPALTEN 640
#define  ZEILEN  480
#define  RAY
#include "xdefines.h"   // SVGALIB: defines.h 
#include "ray.h"        // SVGALIB: #include bild16m.c || lock16m.c 

extern float Infinit,halb,Epsilon;
VCT3  lambda = { 52.36, 56.6, 68.313 };
float duenne = 0.35, LampDiv = 1.;

// RunTime: Zaehler je Sitzung 
int ObjCnt  = 0;
int RingCnt = 0;
int LampCnt = 0;
int FormCnts[FormCnt] = {0};
int TestFormCnt = FormCnt-1;

#ifdef JITTER
float circle[19][2] = {
  {0.75, 0.433}, { 0.0,0.866},   {-0.75,0.433},{-0.75,-0.433 },{0.0,-0.866 },
  {0.75,-0.433}, { 0.0,0.0  },   { 0.75,0.0  },{0.375, 0.65  },{-0.375,0.65},
  {-0.75,0.0  }, {-0.375,-0.65}, {0.375,-0.65},{0.375,0.216  },{0.0,0.433  },
  {-0.375,0.217},{-0.375,-0.216},{0.0,-0.433 },{0.375,-0.217}};
float jitter_offset = 0.75/((float)RAND_MAX);
#endif

// global, um Debuggen und Fehler() zu erlauben
static uint x,y,RDepth = 0;
// global wegen ray.s
VCTd4  dquart;          
VCT4   quart;
VCT6   bicub;

#ifdef OHTA
typedef struct { VCT3 dist; float costheta; } dirT;
dirT    **direction;
int     lastring;
#endif

int   normal[FormCnt] = {0,1,4,7,2,11,10,7,6,11,3,14,12,5,2,23};
char  ObjStr[FormCnt][32] = {
  "den Himmel          ",
  "die Hoelle          ",
  "den Boden           ",
  "eine Kugel          ",
  "ein Moebiusband     ",
  "eine Steinerflaeche ",
  "einen Torus         ",
  "ein Ellipsoid       ",
  "einen Kegel         ",
  "eine Pyramide       ",
  "einen Quader        ",
  "eine Agnesi         ",             
  "ein Superellipsoid  ",
  "Rotationskoerper    ",
  "eine Scheibe        ",
  "eine Lemniskate     "
  };

FrameT Frame = {
  { 2.0, -8.0, 0.992},  // eye          
  { 0.1,  0.1, 0.1 },   // Ambient   
    0.96, 17,  5, 
    0.01, 0.0,          // AttenEps unbenutzt 
  { 0.50, 0.5, 0.6}, 0};// Fog_Color, Fog 

LampT *Lampen = NULL;
Prims *Boden,*Hoelle,*Himmel,*Ring,*Last;
int   arg = TRUE;

// VORDEFINIERTE OBJEKTE 

kugelT k1   =  {
  { 2.5, -2.7, 1.0 }, 1.0 };

kugelT k2   =  {
  {-0.2, -4.0, 1.3 }, 1.15 };

steiT  stei =  {
  {-2.0, -5.0, 1.0},
  { 1.0,  1.0, 1.0}};

moeT   moeb =  {
  {{ 2.4, 0.5, 4.0 }, 1.4 }, 
  0.25, 1 }; 

torT   tor  =  {
  { 2.9,-5.5, 0.6}, 0.3, 0.1 };

ellT   ell  =  {
  {3.8, -3.9, 1.4 },
  {0.3, -0.2, 0.6 },
  {0,0,0,0,0,0,0,0,0,0}};

coneT cone =  {
  {{ 1.4,-4.5,1.6 }, 0.29146 },
  0.3, 1.4, 0,1,20 }; 

pyrT pyr = {
  {{ 3,4,
  { 1.0, 1.0, 1.0 },    // LINKS - normal
    {{-0.9,-1.3, 2.2 }, // links 
    { 0.4,-2.5, 2.6 },  // Mitte 
    { 0.1,-0.5, 4.2 }}},// oben  
  { 3,4,
    { 1.0, 1.0, 1.0 },  // RECHTS 
    {{ 0.4,-2.5, 2.6 }, // Mitte  
     { 1.3, 0.2, 2.2 }, // rechts 
     { 0.1,-0.5, 4.2 }}},// oben   
  { 3,4,
    { 1.0, 1.0, 1.0 },   // UNTEN  
    {{ 1.3, 0.2, 2.2 },  // rechts 
    { 0.4,-2.5, 2.6 },   // Mitte  
    {-0.9,-1.3, 2.2 }}}, // links  
  { 3,4,
    { 1.0, 1.0, 1.0 },   // HINTEN 
    {{ 0.1,-0.5, 4.2 },  // oben   
    { 1.3, 0.2, 2.2 },   // rechts 
    {-0.9,-1.3, 2.2 }}}},// links  
  0, 0 };                // Polygon,dummy 

agnT agn = {{{-7.3,0.5,3.5},3.}, {-20, 0, 0}, 1.1 };

BoxInput B1 = { -1,1,3.0,1.5,-1,1 };

boxT box1; 

superT sup = {{ -1.5,-1.5,2.4 }, {2.0/0.7,0.7/0.6,2.0/0.6}, 
  {{-1,-1,-1},{1,1,1}},{1,1,1}};

sorInput sorI = {
  7,TRUE,
  {{ 1.80000,-0.100000},
    { 0.118143,0.020000},
  { 0.620253,0.540084},
    { 0.210970,0.827004},
    { 0.194093,0.962025},
  { 0.286920,1.035000},
    { 0.488354,1.150000}}};

discT scheibe = {{{ -1, 2, 2.7 }, 1.8 }, {0.4,-0.8,0.55}, 1, 0.7 };

lemniT lemnis = {{{ 4.1, -0.8, 1.85 }, 1.3 }, { 90., 0., 0. }};

// Vordefinierte Lampen 

LampT L1 = {
  {  4.0, -3.5, 4.5 },
  {  0.95, 0.8, 0.8 },
  {  1.0,  1.0, 1.0 },   
    0.6, NULL, NULL };
LampT L2 = {
  { -2.0, -3.5, 1.5 },  
  {  0.9,  0.9, 1.0 },
  {  1.0,  1.0, 1.0 },
    0.3, NULL, NULL };

// TEXTUREN 

uchar Lattice[LatCnt][LatCnt][LatCnt];

typedef struct { int Nr; VCT3 c; } ColTabT;
typedef VCT3 ColList[COLTABSIZE+1];

ColList HellTab   = {{ 0,0,0 }};
ColList FlameTab  = {{ 0,0,0 }};
ColList MarbleTab = {{ 0,0,0 }};

ColTabT MarbleCols[4]  = {
  {  0, { 0.41,0.25,0.15}},
  { 36, { 0.20,0.43,0.55}},
  { 66, { 0.91,0.93,0.88}},
  {127, { 0.64,0.66,0.55}}};

ColTabT HellCols[4]  = {
  {  0, { 0.7, 0.2, 0.1}},
  { 30, { 0.5, 0.8, 0.2}},
  { 60, { 0.9, 0.7, 1.0}},
  {127, { 0.7, 0.4, 0.0}}}; 

ColTabT FlameCols[6] = {
  {  0, { 1.00,1.00,1.00}},
  { 59, { 0.99,0.77,0.42}},
  { 63, { 0.75,0.80,0.51}},
  { 88, { 0.90,0.59,0.34}}, 
  {108, { 0.69,0.38,0.30}},
  {127, { 0.12,0.19,0.54}}}; 

#include "surfaces.h"

float  h,v;

/*
#ifdef DEBUG
VCT3   c;
ulong  nr_of_rays = 0; // 1199073 
ulong  nr_of_refl = 0; //  574234 
ulong  nr_of_refr = 0; //  438160 
ulong  nr_of_coh  = 0; //   66893
ulong  nr_of_rest = 0; //   42195
#endif
*/

void 
Translate_Object (Prims *Obj, VCT3 *t)
{
  TransformT trans;
  Compute_Translation_Transform (&trans, t);
  Compose_Transforms (&Obj->transform, &trans);
}

void 
Scale_Object (Prims *Obj, VCT3 *s)
{
  TransformT trans;
  Compute_Scaling_Transform (&trans, s);
  Compose_Transforms (&Obj->transform, &trans);
}

void 
Rotate_Object (Prims *Obj, VCT3 *r)
{
  TransformT trans;
  Compute_Rotation_Transform (&trans, r);
  Compose_Transforms (&Obj->transform, &trans);
}

void 
Fehler(void)
{
  blau();
  printf("%c%s",7,"Nullvektor!\n");
  printf("Spalte: %d, Zeile: %d, Tiefe: %d\n",x,y,RDepth);
  exit(1);
}

// RAYTRACER-ZUSATZ-FUNKTIONEN 

void 
FogProc (VCT3 *p,VCT3 *c)
{
  float factor;

  if ((factor = exp(-vdist(p,&Frame.eye)/Frame.Fog_Distance)) < 0.2)
    factor = 0.2;
  factor += 0.1 * turbulence(p);
  c->x = (c->x - Frame.Fog_Color.x) * factor + Frame.Fog_Color.x;
  c->y = (c->y - Frame.Fog_Color.y) * factor + Frame.Fog_Color.y;
  c->z = (c->z - Frame.Fog_Color.z) * factor + Frame.Fog_Color.z;
}

void    
Gravity(Prims *Obj) // ermittelt Schwerpunkt und von daher Umkugel 
{
  float  r,s,t;
  ellT   *ep;
  torT   *tp;
  moeT   *mp;  
  coneT  *cp;
  pyrT   *pp;
  steiT  *sp;
  agnT   *ap;
  boxT   *bp;
  superT *up;
  discT  *dp;
  lemniT *lp;
  int   i,j,ganz;             
  VCT3  d[2];

  switch(Obj->form)
  {
  case moebius:
    mp = Obj->UU.moeptr;
    r  = halb * mp->hoch * mp->hoch * (1 - M_SQRT_2);
    Obj->umkugel = mp->ax;
    Obj->umkugel.m.x += r;
    Obj->umkugel.m.y += r;
    Obj->umkugel.rad += mp->hoch * 2; 
    break;  
  case steiner:
    sp = Obj->UU.steiptr;
    Obj->umkugel.m = sp->m;
    r = fabs(sp->ax.x);
    s = fabs(sp->ax.y);
    Obj->umkugel.rad = t = fabs(sp->ax.z);
    if (r > s)
      {
      if (r > t)
        Obj->umkugel.rad = r;
      }
    else
      {
      if (s > t)
        Obj->umkugel.rad = s;
      }
    break;
  case torus:
    tp = Obj->UU.torptr;
    Obj->umkugel.m = tp->m;
    Obj->umkugel.rad = tp->a + tp->b;
    tp->a *= tp->a;
    tp->b *= tp->b;
    break;
  case ellipsoid:
    ep = Obj->UU.ellptr;
    ep->mat.a = r = 1./(ep->ax.x * ep->ax.x);
    ep->mat.e = s = 1./(ep->ax.y * ep->ax.y);
    ep->mat.h = t = 1./(ep->ax.z * ep->ax.z); // Hyperboloid = -h
    ep->mat.d = -ep->m.x*r;
    ep->mat.g = -ep->m.y*s;
    ep->mat.i = -ep->m.z*t;     // Hyperboloid = -i 
    ep->mat.j = (ep->m.x*ep->m.x*r + ep->m.y*ep->m.y*s
      + ep->m.z*ep->m.z*t)-1;
    Obj->umkugel.m = ep->m;
    r = fabs(ep->ax.x);
    s = fabs(ep->ax.y);
    Obj->umkugel.rad = t = fabs(ep->ax.z);
    if (r > s)
      {
      if (r > t)
        Obj->umkugel.rad = r;
      }
    else
      {
      if (s > t)
        Obj->umkugel.rad = s;
      }
    break;
  case kegel:
    cp = Obj->UU.coneptr;
    r  = cp->apex.rad * cp->apex.rad;
    Obj->umkugel.m = cp->apex.m;
    Obj->umkugel.m.z = halb*(r+1) * (cp->high+cp->low) - r * cp->apex.m.z;
    Obj->umkugel.rad = r * (cp->apex.m.z-cp->high) * (cp->apex.m.z-cp->high) 
      + (cp->high-Obj->umkugel.m.z) * (cp->high-Obj->umkugel.m.z);
    Obj->umkugel.rad = sqrt(Obj->umkugel.rad);
    break;
  case pyramide: 
    pp = Obj->UU.pyrptr;
    pp->planes = 4;
    for (i = 0; i < 4; i++)
      {
      pp->flaechen[i].vertnum = 3;
      pp->flaechen[i].polynum = 4;
      }
    ganz = pp->flaechen[0].vertnum * pp->planes;
    Obj->umkugel.rad = 0;
    Obj->umkugel.m.x = Obj->umkugel.m.y = Obj->umkugel.m.z = 0;
    for (i = 0; i < pp->planes; i++)
      for (j = 0; j < pp->flaechen[i].vertnum; j++)
        vaddeq(&Obj->umkugel.m,&pp->flaechen[i].vtx[j]);
    vscaleeq(&Obj->umkugel.m,1./(float)ganz);
    for (i = 0; i < pp->planes; i++)
      for (j = 0; j < pp->flaechen[i].vertnum; j++)
        if ((r = vdist(&Obj->umkugel.m,&pp->flaechen[i].vtx[j])) 
          > Obj->umkugel.rad)
         Obj->umkugel.rad = r;
    for (i = 0; i < pp->planes; i++)
      {
      vsub(d,&pp->flaechen[i].vtx[1],&pp->flaechen[i].vtx[0]);
      vsub(&d[1],&pp->flaechen[i].vtx[2],&pp->flaechen[i].vtx[1]);
      vcross(&pp->flaechen[i].normal,d,&d[1]);
      normalize(&pp->flaechen[i].normal);
      vsubnorm(d,&pp->flaechen[i].vtx[0],&Obj->umkugel.m);
      // gegen falsche Reihenfolge von Polygonecken-Eingaben
      negnorm(d,&pp->flaechen[i].normal);
      }
    break;
  case box:
    bp = Obj->UU.boxptr;
    bp->planes = 6;
    for (i = 0; i < 6; i++)
      {
      bp->flaechen[i].vertnum = 4;
      bp->flaechen[i].polynum = 6;    
      } 
    ganz = bp->flaechen[0].vertnum * bp->planes;
    Obj->umkugel.rad = 0;
    Obj->umkugel.m.x = Obj->umkugel.m.y = Obj->umkugel.m.z = 0;
    for (i = 0; i < bp->planes; i++)
       for (j = 0; j < bp->flaechen[i].vertnum; j++)
        vaddeq(&Obj->umkugel.m,&bp->flaechen[i].vtx[j]);
    vscaleeq(&Obj->umkugel.m,1./(float)ganz);
    for (i = 0; i < bp->planes; i++)
      for (j = 0; j < bp->flaechen[i].vertnum; j++)
        if ((r = vdist(&Obj->umkugel.m,&bp->flaechen[i].vtx[j]))
          > Obj->umkugel.rad)
          Obj->umkugel.rad = r;
    for (i = 0; i < bp->planes; i++)
      {
      vsub(d,&bp->flaechen[i].vtx[1],&bp->flaechen[i].vtx[0]);
      vsub(&d[1],&bp->flaechen[i].vtx[2],&bp->flaechen[i].vtx[1]);
      vcross(&bp->flaechen[i].normal,d,&d[1]);
      normalize(&bp->flaechen[i].normal);
      vsubnorm(d,&bp->flaechen[i].vtx[0],&Obj->umkugel.m);
      // gegen falsche Reihenfolge von Polygonecken-Eingaben 
      negnorm(d,&bp->flaechen[i].normal);
      }
    break;
  case agnesi:
    ap = Obj->UU.agnptr;
    Obj->umkugel.m = ap->ax.m;
    Obj->umkugel.rad = ap->scale*1.2;
    Create_Transform (&Obj->transform);
    Rotate_Object (Obj,&ap->rotate);
    d[0].x = d[0].y = d[0].z = ap->scale;
    Scale_Object(Obj,d);
    Translate_Object (Obj,&ap->ax.m);
    break;
  case super:
    up = Obj->UU.supptr;
    Obj->umkugel.m = up->m;
    if (up->scal.x > up->scal.y)
      {
      if (up->scal.x > up->scal.z)
        Obj->umkugel.rad = up->scal.x;
      else
        Obj->umkugel.rad = up->scal.z;
      }  
    else
      {
      if (up->scal.y > up->scal.z)
        Obj->umkugel.rad = up->scal.y;
      else
        Obj->umkugel.rad = up->scal.z;
      }
    Obj->umkugel.rad *= 1.7;   // groesser als theoretisches sqrt(2) 
    Create_Transform (&Obj->transform);
    Scale_Object (Obj,&up->scal);
    Translate_Object (Obj, &up->m); 
    break;
  case disc:
    dp = Obj->UU.discptr;
    Obj->umkugel = dp->ax;
    normalize (&dp->normal);
    dp->d = -vdot(&dp->ax.m,&dp->normal);   // v.Mangold, I,430  
    break;
  case lemni:
    lp = Obj->UU.lemniptr;
    Obj->umkugel = lp->ax;
    Create_Transform (&Obj->transform);
    Rotate_Object(Obj,&lp->rotate);       
    Translate_Object(Obj,&lp->ax.m);
    break;   
  default: ;
  }
}

// Spezielle Schnittpunkt-Routinen 

#define DEPTH_TOLERANCE 1.0e-3  // double 1.0E-4  
#define ZERO_TOLERANCE  1.0e-4  // double 1.0E-10 
#define SGNX(x) (((x) >= 0.) ? 1 : -1)
#define MAX_ITERATIONS  20
#define PLANECOUNT      9

static float planes[PLANECOUNT][4] =
   {{1, 1, 0, 0}, {1,-1, 0, 0},
    {1, 0, 1, 0}, {1, 0,-1, 0},
    {0, 1, 1, 0}, {0, 1,-1, 0},
    {1, 0, 0, 0}, {0, 1, 0, 0},
    {0, 0, 1, 0}};

char 
intersect_box (VCT3 *P, VCT3 *D, float *dmin, float *dmax)
{
  float tmin,tmax;

  // Links/rechts 
  if (fabs (D->x) > Epsilon)
    {
    if (D->x > Epsilon)
      {
      if ((*dmax = (1-P->x) / D->x) < Epsilon)
        return FALSE;
      *dmin = (-1-P->x) / D->x;
      }
    else
      {
      if ((*dmax = (-1-P->x) / D->x) < Epsilon)
        return FALSE;
      *dmin = (1-P->x) / D->x;
      }
    if (*dmin > *dmax) 
      return FALSE;
    }
  else
    {
    if (fabs(P->x) > 1)
      return FALSE;
    *dmin = -Infinit;
    *dmax =  Infinit;
    }
  tmin = tmax = 0.;
  // Oben/unten 
  if (fabs (D->y) > Epsilon)
    {
    if (D->y > Epsilon)
      {
      tmin = (-1-P->y) / D->y;
      tmax = (1-P->y) / D->y;
      }
    else
      {
      tmax = (-1-P->y) / D->y;
      tmin = (1-P->y) / D->y;
      }
    if (tmax < *dmax)
      {
      if (tmax < Epsilon) 
        return FALSE;
      if (tmin > *dmin)
        {
        if (tmin > tmax) 
          return FALSE;
        *dmin = tmin;
        }
      else
        {
        if (*dmin > tmax)
          return FALSE;
        }
      *dmax = tmax;
      }
    else
      {
      if (tmin > *dmin)
        {
        if (tmin > *dmax) 
          return FALSE;
        *dmin = tmin;
        }
      }
    }
  else
    {
    if (fabs(P->y) > 1)
      return FALSE;
    }
  // Vorn/hinten 
  if (fabs (D->z) > Epsilon)
    {
    if (D->z > Epsilon)
      {
      tmin = (-1-P->z) / D->z;
      tmax = (1-P->z) / D->z;
      }
    else
      {
      tmax = (-1-P->z) / D->z;
      tmin = (1-P->z) / D->z;
      }
    if (tmax < *dmax)
      {
      if (tmax < Epsilon) 
        return FALSE;
      if (tmin > *dmin)
        {
        if (tmin > tmax) 
          return FALSE;
        *dmin = tmin;
        }
      else
        {
        if (*dmin > tmax) 
          return FALSE;
        }
      *dmax = tmax;
      }
    else
      {
      if (tmin > *dmin)
        {
        if (tmin > *dmax) 
          return FALSE;
        *dmin = tmin;
        }
      }
    }
  else
    {
    if (fabs(P->z) > 1)
      return FALSE;
    }
  *dmin = tmin;
  *dmax = tmax;
  return TRUE;
}

So here's the code for the raytracer written by media philosopher Chapter 6 of Critical Code Studies. I'd like to invite you to an exploration of this portion. I can also make the full file available for exploration. I can also post the original German note. This version has been translated by the Hammermann family.


A few starter questions:
* What parts seem to be written by Kittler? And what parts by others?
* How does this raytracer code complement his theoretical writing?

Comments

  • Here's the original German for that first code:

    /*
    v. 3.57
    31.07.11
    PTRACE.PAS (c't 1/93,167ff.) erweitert 
    Superellipsoid, Rotationskoerper und prozedurale Texturen aus povray3
    DOS-Version nicht mehr unterstuetzt
    
    COMPILIEREN: 
    Normal: xgraf xsuptrace ray.s matrices.s
    // Option -DNEWFRESNEL: vereinfachtes Fresnellicht aus povray3 
    Option -DJITTER:     unscharfe (und zeitfressende) Schatten
    Option -DGAMMA:      Gammakorrektur
    SVGALIB oder DGA:    bild.i ".equ XWINDOW,1" aendern!  
    
    RUNTIME:
    <xsuptrace 1>: reproduzierbares Rauschen fuer Laufzeittests
    
    FEATURES:
    Alle spiegelnden Oberflaechen sind auf ReflectionMapping umstellbar: was
    dann auf ihrer Oberflaeche erscheint, ist ein zu ladendes Bild. Dies Feature 
    muessen Benutzer Standardoberflaechen aber erst abverlangen.  
    
    Prompts (':') fuer Skalare und Vektoren lassen sich entweder mit <w[eiter]> 
    oder <n[ein]> quittieren oder mit neuer Eingabe beantworten
    
    3 konstante Objekte: Himmel, Hoelle, Boden (was nur plein-air-Bilder erlaubt)
    Beliebig viele variable Objekte (nur durch Arbeitsspeicher begrenzt)
    Als variable Objekte standardmaessig 2 Kugeln und je 1 anderes Objekt vordefi-
    niert. Aber Standardobjekte lassen sich wieder loeschen.
    Falls von einem Objekt mehr als die Standardanzahl verlangt wird, erfragt ein
    Prompt die neuen Koordinaten.
    Alle Objekte edierbar (konstante nur durch Neuzuordnung von Farb- zu Normal-
    prozedur, variable auch nach Ort und Groesse).  
    Einige exotische Objekte skalierbar und rotierbar. Das wird noch ausgebaut.
    Beliebig viele Lampen, die 2 ersten vordefiniert. 
    Oberflaechen 1. global, 2. nach Zuweisung an Objekte einzeln edierbar.
    LINUX: beliebig grosse *.24f-Bilder als 2D-Texturen ladbar.
    
    Objekte als Ringliste fuer schnelleres intershade() (vgl. Foley, S. 784); 
    Lampen als einfach verkettete Liste.
    Linkshaendiges Koordinatensystem: links < x < rechts, vorn < y < hinten, 
    unten < z < oben. 
    
    NEU:  
    01.04.97: AttCol()-Beschleunigung weg - Transparenzen wuerden schlechter
    07.04.98: Individuelle Fresnelkoeffizienten mit individueller Mattheit fuer 
    opake, aber metallische Oberflaechen (so dass diese Koeffizienten TransC und 
    die Mattheit transpar ueberschreiben duerfen). Das ist physikalisch korrekt 
    und, mirabile dictu, besser als in POVRAY3. Farbtafeln (ColTabT) global 
    edierbar
    22.11.98: ReflV() nach Glassner, Image Synthesis, S. 726, noch einmal in 
    Light() pro Lampe berechnet
    24.12.98: Objekt Scheibe waehlbar; ungezippte DOS-*.24f-Dateien sind ladbar
    08.03.99: Experimenteller Support fuer Ohta/Maekawa-Algorithmus
    01.09.01: DOS nicht mehr unterstuetzt
    13.08.04: Init_Ohta() anders, noch ungetestet
    24.10.08: Stahl neu gegenueber /usr/ich/laptop/xsuptrace.c
    
    BUGS:
    Umkugeln von stei, sup, sor sehr empirisch ermittelt
    2DMapping auf Steiner, Agnesi, SuperQuadrik und Drehkoerper nur als Reflexion-
    Map implementiert: die Transformation (x,y,z)->(u,v) waere schwer
    MapProc() und Init_Fresnel() nicht auf Mehrfachaufruf von xsuptrace vorbereitet
    Edieren von Boxen und Pyramiden noch uneinheitlich
    lambda und duenne global, also nicht pro Oberflaeche variabel
    Keine Transparenzabschattierung wie in CALCNEW.C
    Bei frei plazierbaren Objekten sind NULL-Pointer-Fehler unvermeidlich; man 
    aendere eine Mittelpunkt-Koordinate um Kleinbetraege
    SOR-Umkugel wird in Edit_Sor() statt Gravity() ermittelt
    Brechungsindices haengen nicht von Lichtwellenlaengen ab
    08.04.99: intershade() gibt L->Shad korrekt zurueck, aber die Objektkohaerenz 
    bricht immer wieder weg, bremst also eher
    30.12.00: xgraf (gcc mit Optimierung) kann die SOR-Kurve faelschen, falls
    in SorInput der Differenzenquotient Dy/Dx (also die Kurvensteigung zwischen
    zwei x-Fixpunkten) zu gross wird.
    09.09.03: ƒnderungen an Transformationsmatrixen greifen nur bei gcc -g. Dunkel
    31.07.11: QuColProc() entwanzt
    
    HINTS:
    Zwischen internen Datenstrukturen und Benutzeranzeigen finden komplexe Umrech-
    nungen statt; globale Daten also nicht mutwillig patchen!
    */
    
Sign In or Register to comment.