chiark / gitweb /
merge into history old stuff found on chiark
[moebius.git] / graphics.cc
1 /*
2  * Graphics library
3  */
4
5 #include <iostream.h>
6
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11
12 #include "library.hh"
13 #include "graphics.hh"
14 #include "output.hh"
15 #include "parameter.hh"
16
17 static int checkneededline(Onscreen a, Onscreen b) {
18   double xd= a.x - b.x;
19   double yd= a.y - b.y;
20   int n= (int)ceil(sqrt(xd*xd+yd*yd)*100.0);
21   return n>0 ? n : 1;
22 }
23
24 static Parameter<double>
25 sotextpit("sotextpit", "Pitch of solid texture (0: grid mode)",
26           0., 1., 0., 1000.);
27
28 void Cell::display(Output& o) {
29   int nn[4];
30   int totalnn= 0;
31   int i;
32   for (i=0; i<4; i++) {
33     nn[i]= checkneededline(p[i],p[(i+1)&3]);
34     totalnn+= nn[i];
35   }
36   Point *array= new Point[totalnn];
37   Point *inarrayp= array;
38   Point mean(0,0,0);
39   for (i=0; i<4; i++) {
40     for (int a=0; a<nn[i]; a++) {
41       double fp= (double)a         / nn[i];
42       double fn= (double)(nn[i]-a) / nn[i];
43       *inarrayp++= p[i]*fn + p[(i+1)&3]*fp;
44     }
45     mean = mean + p[i];
46   }
47   mean = mean * 0.25;
48   Output::Colour colour= Output::grid;
49   if (sotextpit > 0) {
50     bool white= false;
51     for (i=0; i<3; i++) {
52       double intpartdummy;
53       double remainder= modf(mean[i] / sotextpit, &intpartdummy);
54       if (remainder >= 0.5 || (remainder >= -0.5 && remainder < 0.0))
55         white= !white;
56     }
57     colour= white ? Output::solidwhite : Output::solidblack;
58   }
59   o.drawcell(array,totalnn,colour);
60   delete[] array;
61 }                          
62
63 SortedCellList::Fragment* SortedCellList::insertfragment(int at) {
64   if (used==size) {
65     size+=5; size<<=1;
66     fragments= (Fragment**)realloc(fragments,sizeof(Fragment*)*size);
67     if (!fragments) { perror("realloc"); exit(1); }
68   }
69   memmove(fragments+at+1, fragments+at, sizeof(Fragment*)*(used-at));
70   used++;
71   Fragment *nf= new Fragment;
72   fragments[at]= nf;
73   return nf;
74 }
75
76 void SortedCellList::insert(Cell *it) {
77   double index= it->index();
78   int fragment;
79   for (fragment= used-1;
80        fragment >= 0 && index < fragments[fragment]->entries[0].index;
81        fragment--);
82   if (fragment < 0) {
83     Fragment *nf= insertfragment(0);
84     nf->used= 1;
85     nf->entries[0].index= index;
86     nf->entries[0].cell= it;
87     return;
88   }
89   int entry;
90   for (entry= 0;
91        entry < fragments[fragment]->used &&
92        index > fragments[fragment]->entries[entry].index;
93        entry++);
94   if (fragments[fragment]->used >= fragmentsize) {
95     Fragment *nf= insertfragment(fragment+1);
96     nf->used= fragmentsize>>1;
97     fragments[fragment]->used -= nf->used;
98     memcpy(nf->entries,
99            fragments[fragment]->entries + fragments[fragment]->used,
100            nf->used*sizeof(Entry));
101     if (entry >= fragments[fragment]->used) {
102       entry-= fragments[fragment]->used;
103       fragment++;
104     }
105   }
106   memmove(fragments[fragment]->entries + entry+1,
107           fragments[fragment]->entries + entry,
108           sizeof(Entry) * (fragments[fragment]->used - entry));
109   fragments[fragment]->entries[entry].index= index;
110   fragments[fragment]->entries[entry].cell= it;
111   fragments[fragment]->used++;
112 }
113
114 SortedCellList::~SortedCellList() {
115   for (int fragment=0; fragment<used; fragment++) {
116     for (int entry=0; entry<fragments[fragment]->used; entry++) {
117       delete fragments[fragment]->entries[entry].cell;
118     }
119     delete fragments[fragment];
120   }
121   free(fragments);
122 }
123
124 void SortedCellList::display(Output& o) {
125   o.startimage();
126   for (int fragment=0; fragment<used; fragment++) {
127     for (int entry=0; entry<fragments[fragment]->used; entry++) {
128       if (Point::indexvisible(fragments[fragment]->entries[entry].index)) {
129         fragments[fragment]->entries[entry].cell->display(o);
130       }
131     }
132   }
133   o.endimage();
134 }