chiark / gitweb /
found in ian@chiark:things/moebius.old-before-cvs
[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
16 static int checkneededline(Onscreen a, Onscreen b) {
17   double xd= a.x - b.x;
18   double yd= a.y - b.y;
19   int n= (int)ceil(sqrt(xd*xd+yd*yd)*100.0);
20   return n>0 ? n : 1;
21 }
22
23 void Cell::display(Output& o) {
24   int nn[4];
25   int totalnn= 0;
26   for (int i=0; i<4; i++) {
27     nn[i]= checkneededline(p[i],p[(i+1)&3]);
28     totalnn+= nn[i];
29   }
30   Point *array= new Point[totalnn];
31   Point *inarrayp= array;
32   for (i=0; i<4; i++) {
33     for (int a=0; a<nn[i]; a++) {
34       double fp= (double)a         / nn[i];
35       double fn= (double)(nn[i]-a) / nn[i];
36       *inarrayp++= p[i]*fn + p[(i+1)&3]*fp;
37     }
38   }
39   o.drawcell(array,totalnn);
40   delete[] array;
41 }                          
42
43 SortedCellList::Fragment* SortedCellList::insertfragment(int at) {
44   if (used==size) {
45     size+=5; size<<=1;
46     fragments= (Fragment**)realloc(fragments,sizeof(Fragment*)*size);
47     if (!fragments) { perror("realloc"); exit(1); }
48   }
49   memmove(fragments+at+1, fragments+at, sizeof(Fragment*)*(used-at));
50   used++;
51   Fragment *nf= new Fragment;
52   fragments[at]= nf;
53   return nf;
54 }
55
56 void SortedCellList::insert(Cell *it) {
57   double index= it->index();
58   for (int fragment= used-1;
59        fragment >= 0 && index < fragments[fragment]->entries[0].index;
60        fragment--);
61   if (fragment < 0) {
62     Fragment *nf= insertfragment(0);
63     nf->used= 1;
64     nf->entries[0].index= index;
65     nf->entries[0].cell= it;
66     return;
67   }
68   for (int entry= 0;
69        entry < fragments[fragment]->used &&
70        index > fragments[fragment]->entries[entry].index;
71        entry++);
72   if (fragments[fragment]->used >= fragmentsize) {
73     Fragment *nf= insertfragment(fragment+1);
74     nf->used= fragmentsize>>1;
75     fragments[fragment]->used -= nf->used;
76     memcpy(nf->entries,
77            fragments[fragment]->entries + fragments[fragment]->used,
78            nf->used*sizeof(Entry));
79     if (entry >= fragments[fragment]->used) {
80       entry-= fragments[fragment]->used;
81       fragment++;
82     }
83   }
84   memmove(fragments[fragment]->entries + entry+1,
85           fragments[fragment]->entries + entry,
86           sizeof(Entry) * (fragments[fragment]->used - entry));
87   fragments[fragment]->entries[entry].index= index;
88   fragments[fragment]->entries[entry].cell= it;
89   fragments[fragment]->used++;
90 }
91
92 SortedCellList::~SortedCellList() {
93   for (int fragment=0; fragment<used; fragment++) {
94     for (int entry=0; entry<fragments[fragment]->used; entry++) {
95       delete fragments[fragment]->entries[entry].cell;
96     }
97     delete fragments[fragment];
98   }
99   free(fragments);
100 }
101
102 void SortedCellList::display(Output& o) {
103   o.startimage();
104   for (int fragment=0; fragment<used; fragment++) {
105     for (int entry=0; entry<fragments[fragment]->used; entry++) {
106       if (Point::indexvisible(fragments[fragment]->entries[entry].index)) {
107         fragments[fragment]->entries[entry].cell->display(o);
108       }
109     }
110   }
111   o.endimage();
112 }