chiark / gitweb /
found in ijackson@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 (int 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   int fragment;
59   for (fragment= used-1;
60        fragment >= 0 && index < fragments[fragment]->entries[0].index;
61        fragment--);
62   if (fragment < 0) {
63     Fragment *nf= insertfragment(0);
64     nf->used= 1;
65     nf->entries[0].index= index;
66     nf->entries[0].cell= it;
67     return;
68   }
69   int entry;
70   for (entry= 0;
71        entry < fragments[fragment]->used &&
72        index > fragments[fragment]->entries[entry].index;
73        entry++);
74   if (fragments[fragment]->used >= fragmentsize) {
75     Fragment *nf= insertfragment(fragment+1);
76     nf->used= fragmentsize>>1;
77     fragments[fragment]->used -= nf->used;
78     memcpy(nf->entries,
79            fragments[fragment]->entries + fragments[fragment]->used,
80            nf->used*sizeof(Entry));
81     if (entry >= fragments[fragment]->used) {
82       entry-= fragments[fragment]->used;
83       fragment++;
84     }
85   }
86   memmove(fragments[fragment]->entries + entry+1,
87           fragments[fragment]->entries + entry,
88           sizeof(Entry) * (fragments[fragment]->used - entry));
89   fragments[fragment]->entries[entry].index= index;
90   fragments[fragment]->entries[entry].cell= it;
91   fragments[fragment]->used++;
92 }
93
94 SortedCellList::~SortedCellList() {
95   for (int fragment=0; fragment<used; fragment++) {
96     for (int entry=0; entry<fragments[fragment]->used; entry++) {
97       delete fragments[fragment]->entries[entry].cell;
98     }
99     delete fragments[fragment];
100   }
101   free(fragments);
102 }
103
104 void SortedCellList::display(Output& o) {
105   o.startimage();
106   for (int fragment=0; fragment<used; fragment++) {
107     for (int entry=0; entry<fragments[fragment]->used; entry++) {
108       if (Point::indexvisible(fragments[fragment]->entries[entry].index)) {
109         fragments[fragment]->entries[entry].cell->display(o);
110       }
111     }
112   }
113   o.endimage();
114 }