Re: semicircle

Search this archive.

From: Matan Ziv-Av (matan@svgalib.org)
Date: Tue 30 Nov 1999 - 22:24:05 IST


Wow, is that the most active day of this list, or what? I hope ruthers
won't decide we have too much traffic for their servers.

Anyway, here's a program I wrote a few years ago (in turbo pascal) to
draw a filled ellipse sector. I changed the program a bit to work with
svgalib, and disable pattern fill (since it seems fpc-0.99.12 can't do
pointer arithmetic). 

The function assumnes 0<=se<=sa<=360, so if you want a semicircle that
spans the base line (x positive), you must divide it to two different
sectors.


-- 
Matan Ziv-Av.                         matan@svgalib.org




Program filledell(input,output);

Uses svgalib;

const pattern:array[0..15,0..15] of word=(
(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
(1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1),
(1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1),
(1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1),
(1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1),
(1,1,1,1,1,1,4,4,1,1,1,1,1,1,1,1),
(1,1,1,1,1,1,4,4,1,1,1,1,1,1,1,1),
(1,1,1,1,1,1,1,1,4,4,1,1,1,1,1,1),
(1,1,1,1,1,1,1,1,4,4,1,1,1,1,1,1),
(1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1),
(1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1),
(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
);

var
  colors:^byte;
  i,j,k:integer;
  ch:char;

procedure filledellipse(x,y,xr,yr,se,sa:integer);

(* fill an ellipse sector with the pattern in colors *)

var
  j1,j2,j3,j0:integer;
  i:longint;
  a,b:real;
  p:^byte;

begin
  b:=1.0*yr*yr;
  if b>0 then for i:=0 to yr do begin
    a:=1.0*xr*xr*(1.0-i*i/b);
    j1:=round(sqrt(a));
    j2:=round(sqrt(a));
    j3:=round(sqrt(a));
    j0:=round(sqrt(a));
    case (se div 90) mod 4 of
      0: if i<sin(se/180*pi)*yr then 
        j0:=round(cos(se/180*pi)/sin(se/180*pi)*i*xr/yr);
      1: if i<sin(se/180*pi)*yr then 
        j0:=round(cos(se/180*pi)/sin(se/180*pi)*i*xr/yr)
        else j0:=-j1-1;
      2: begin
           j0:=0;
           j1:=-1;
           if i<-sin(se/180*pi)*yr then 
             j2:=round(cos(se/180*pi)/sin(se/180*pi)*i*xr/yr);
         end;
      3: begin
           j0:=0;
           j1:=-1;
           if i<-sin(se/180*pi)*yr then 
             j2:=round(cos(se/180*pi)/sin(se/180*pi)*i*xr/yr)
             else j2:=-j3-1;
         end;
    end;

    if(sa<>360) then case (sa div 90) mod 4 of
      3: if i<-sin(sa/180*pi)*yr then 
        j3:=-round(cos(sa/180*pi)/sin(sa/180*pi)*i*xr/yr);
      2: if i<-sin(sa/180*pi)*yr then 
        j3:=-round(cos(sa/180*pi)/sin(sa/180*pi)*i*xr/yr)
        else j3:=-j2-1;
      1: begin
           j2:=0;
           j3:=-1;
           if i<sin(sa/180*pi)*yr then 
             j1:=-round(cos(sa/180*pi)/sin(sa/180*pi)*i*xr/yr);
         end;
      0: begin
           j2:=0;
           j3:=-1;
           if i<sin(sa/180*pi)*yr then 
             j1:=-round(cos(sa/180*pi)/sin(sa/180*pi)*i*xr/yr)
             else j1:=-j0-1;
         end;
    end;
    vga_drawscansegment(colors^{+(((y+i) mod 8)*4096+((x-j1) mod 8))},
                        x-j1,y-i,j0+j1+1);    
    if i>0 then   
      vga_drawscansegment(colors^{+(((y-i) mod 8)*4096+((x-j2) mod 8))},
                        x-j2,y+i,j2+j3+1);    
  end;
end;

begin (* main *)

  getmem(colors,65536); 

  for i:=0 to 256 do 
    for j:=0 to 15 do
      for k:=0 to 15 do 
        begin
          (colors{+j*4096+i*16+j})^:=pattern[j,k];
	end;

  fillchar(colors^,65536,4);
  
  vga_setmode(G1024x768x256);  

  for i:=0 to 360 do for j:=0 to 10 do
  filledellipse(300,300,200,100,0,i);

  fillchar(colors^,65536,12);

  for i:=0 to 359 do for j:=0 to 10 do
  filledellipse(600,300,200,100,359-i,360);

  readln(ch);

  vga_setmode(GTEXT);

end.


This archive was generated by hypermail 2.1.4 : Wed 21 Jan 2004 - 22:10:22 IST