From faf540b146dc7c4a48480673af9a8de56df2e34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20W=C3=BChrer?= Date: Sun, 19 Feb 2017 15:20:12 +0100 Subject: initial commit --- piechart.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 piechart.c diff --git a/piechart.c b/piechart.c new file mode 100644 index 0000000..aa52afd --- /dev/null +++ b/piechart.c @@ -0,0 +1,92 @@ +/* + * BUGS: + * adjacient colours could have higher contrast + * negative angles + */ + +#include +#include +#include +#include + +const float tau=(float)(M_PI*2); + +// draw sector +void draw(float angle, char* label){ + const float r=100; + static float progress=0; + static float overlap=0; + float fangle; if(angle<0)fangle=-angle;else fangle=angle-overlap; + // Mx,y : move to x,y + // Lx,y : draw line to x,y + // Arx,ry rot 0,0 x,y : arc with radii rx,ry rotated by rot large-arch or not,clockwise or not to point x,y + // z : closes the path + float x1=r*cosf(progress); + float y1=r*sinf(progress); + float x2=r*cosf(progress+fangle); + float y2=r*sinf(progress+fangle); + float divider=progress+fangle/2; + unsigned char rr=(unsigned char)(0xff*((divider)/(tau))); + unsigned char gg=(unsigned char)(0xff*((divider-tau/3)/(tau))); + unsigned char bb=(unsigned char)(0xff*((divider-2*tau/3)/(tau))); + printf("",rr,gg,bb,250+x1,250+y1,r,r,(fangle>M_PI),1,250+x2,250+y2); + float xo=250+(3*r/2*cosf(divider)); + float yo=250+(3*r/2*sinf(divider)); + printf("",250+(2*r/3*cosf(divider)),250+(2*r/3*sinf(divider)),xo,yo); + printf("%s\n",xo,yo,label); + progress+=fangle; + overlap-=angle; // multiple overlaps accumulate + if(overlap<0)overlap=0; +} +// put preliminary data on the stack +float scan_line (FILE* input, float sum){ + char* line=NULL; size_t len=0; + if(getline(&line,&len,input) != -1){ + { // chomp + char* l=&(line[strlen(line)-1]); + if(*l=='\n')*l='\0'; + } + /* at the very least, we need a true value. + * everything following it can be label or whatever. + * if strtof does not find anything (or the value is miniscule), the line is obviously a comment and should be ignored. + * (if the value is too huge to handle, the output will be meaningless.) + * + * If the value is negative, it is meant to overlap with the previous record. Or records. + * The value would have to be ignored for computing the sum total. + */ + char* label=line; + float number=strtof(label,&label); + if(number>0){ + sum=scan_line(input,sum+number); + float angle=tau*number/sum; + draw(angle,label); + }else if(number<0){ + sum=scan_line(input,sum); + float angle=tau*number/sum; + draw(angle,label); + }else{ + sum=scan_line(input,sum); + printf("\n",label); + } + } + free(line); + return sum; +} + +int main(int argc, char** argv){ + FILE* input=stdin; + // getopts + // print boilerplate + puts("\n\ +\n\ +"); + scan_line(input,0); + puts(""); + return 0; +} -- cgit v1.2.3