Task: Color wheel



C#: 

public MainWindow()
{
    InitializeComponent();
    RenderOptions.SetBitmapScalingMode(imgMain, BitmapScalingMode.HighQuality);
    imgMain.Source = new WriteableBitmap(480, 480, 96, 96, PixelFormats.Bgr32, null);
    
    DrawHue(100);
}

void DrawHue(int saturation)
{
    var bmp = (WriteableBitmap)imgMain.Source;

    int centerX = (int)bmp.Width / 2;
    int centerY = (int)bmp.Height / 2;
    int radius = Math.Min(centerX, centerY);
    int radius2 = radius - 40;

    bmp.Lock();
    unsafe{
        var buf = bmp.BackBuffer;
        IntPtr pixLineStart;
        for(int y=0; y < bmp.Height; y++){
            pixLineStart = buf + bmp.BackBufferStride * y;
            double dy = (y - centerY);
            for(int x=0; x < bmp.Width; x++){
                double dx = (x - centerX);
                double dist = Math.Sqrt(dx * dx + dy * dy);
                if (radius2 <= dist && dist <= radius) {
                    double theta = Math.Atan2(dy, dx);
                    double hue = (theta + Math.PI) / (2.0 * Math.PI);
                    *((int*)(pixLineStart + x * 4)) = HSB_to_RGB((int)(hue * 360), saturation, 100);
                }
            }
        }
    }
    bmp.AddDirtyRect(new Int32Rect(0, 0, 480, 480));
    bmp.Unlock();
}

static int HSB_to_RGB(int h, int s, int v)
{
    var rgb = new int[3];

    var baseColor = (h + 60) % 360 / 120;
    var shift = (h + 60) % 360 - (120 * baseColor + 60 );
    var secondaryColor = (baseColor + (shift >= 0 ? 1 : -1) + 3) % 3;

    
    rgb[baseColor] = 255;
    rgb[secondaryColor] = (int) ((Math.Abs(shift) / 60.0f) * 255.0f);

    
    for (var i = 0; i < 3; i++)
        rgb[i] += (int) ((255 - rgb[i]) * ((100 - s) / 100.0f));

    
    for (var i = 0; i < 3; i++)
        rgb[i] -= (int) (rgb[i] * (100-v) / 100.0f);

    return RGB2int(rgb[0], rgb[1], rgb[2]);
}

public static int RGB2int(int r, int g, int b) => r << 16 | g << 8 | b;






VB: Option explicit

Class ImgClass
  Private ImgL,ImgH,ImgDepth,bkclr,loc,tt
  private xmini,xmaxi,ymini,ymaxi,dirx,diry
  public ImgArray()  
  private filename   
  private Palette,szpal 
  
  public property get xmin():xmin=xmini:end property  
  public property get ymin():ymin=ymini:end property  
  public property get xmax():xmax=xmaxi:end property  
  public property get ymax():ymax=ymaxi:end property  
  public property let depth(x)
  if x<>8 and x<>32 then err.raise 9
  Imgdepth=x
  end property     
  
  public sub set0 (x0,y0) 
    if x0<0 or x0>=imgl or y0<0 or y0>imgh then err.raise 9 
    xmini=-x0
    ymini=-y0
    xmaxi=xmini+imgl-1
    ymaxi=ymini+imgh-1    
  end sub
  
  
  Public Default Function Init(name,w,h,orient,dep,bkg,mipal)
  
  dim i,j
  ImgL=w
  ImgH=h
  tt=timer
  loc=getlocale
  
  set0 0,0   
  redim imgArray(ImgL-1,ImgH-1)
  bkclr=bkg
  if bkg<>0 then 
    for i=0 to ImgL-1 
      for j=0 to ImgH-1 
        imgarray(i,j)=bkg
      next
    next  
  end if 
  Select Case orient
    Case 1: dirx=1 : diry=1   
    Case 2: dirx=-1 : diry=1
    Case 3: dirx=-1 : diry=-1
    Case 4: dirx=1 : diry=-1
  End select    
  filename=name
  ImgDepth =dep
  
  if imgdepth=8 then  
    loadpal(mipal)
  end if       
  set init=me
  end function

  private sub loadpal(mipale)
    if isarray(mipale) Then
      palette=mipale
      szpal=UBound(mipale)+1
    Else
      szpal=256  
    
    

, not relevant
   End if  
  End Sub

  
  
  
  Private Sub Class_Terminate
    
    if err<>0 then wscript.echo "Error " & err.number
    wscript.echo "copying image to bmp file"
    savebmp
    wscript.echo "opening " & filename & " with your default bmp viewer"
    CreateObject("Shell.Application").ShellExecute filename
    wscript.echo timer-tt & "  iseconds"
  End Sub
  
    function long2wstr( x)  
      dim k1,k2,x1
      k1=  (x and &hffff&)
      k2=((X And &h7fffffff&) \ &h10000&) Or (&H8000& And (x<0))
      long2wstr=chrw(k1) & chrw(k2)
    end function 
    
    function int2wstr(x)
        int2wstr=ChrW((x and &h7fff) or (&H8000 And (X<0)))
    End Function


   Public Sub SaveBMP
    
    Dim s,ostream, x,y,loc
   
    const hdrs=54 
    dim bms:bms=ImgH* 4*(((ImgL*imgdepth\8)+3)\4)  
    dim palsize:if (imgdepth=8) then palsize=szpal*4 else palsize=0

    with  CreateObject("ADODB.Stream") 
      .Charset = "UTF-16LE"    
      .Type =  2
      .open 
      
      
      
      
      .writetext ChrW(&h4d42)                           
      .writetext long2wstr(hdrs+palsize+bms)            
      .writetext long2wstr(0)                           
      .writetext long2wstr (hdrs+palsize)               
       
      .writetext long2wstr(40)                          
      .writetext long2wstr(Imgl)                        
      .writetext long2wstr(imgh)                        
      .writetext int2wstr(1)                            
      .writetext int2wstr(imgdepth)                     
      .writetext long2wstr(&H0)                         
       
      .writetext long2wstr(bms)                         
      .writetext long2wstr(&Hc4e)                       
      .writetext long2wstr(&hc43)                       
      .writetext long2wstr(szpal)                       
      .writetext long2wstr(&H0)                         
     
      
      
       Dim x1,x2,y1,y2
       If dirx=-1 Then x1=ImgL-1 :x2=0 Else x1=0:x2=ImgL-1
       If diry=-1 Then y1=ImgH-1 :y2=0 Else y1=0:y2=ImgH-1 
       
      Select Case imgdepth
      
      Case 32
        For y=y1 To y2  step diry   
          For x=x1 To x2 Step dirx
           
           .writetext long2wstr(Imgarray(x,y))
          Next
        Next
        
      Case 8
        
        For x=0 to szpal-1
          .writetext long2wstr(palette(x))  
        Next
        
        dim pad:pad=ImgL mod 4
        For y=y1 to y2 step diry
          For x=x1 To x2 step dirx*2
             .writetext chrw((ImgArray(x,y) and 255)+ &h100& *(ImgArray(x+dirx,y) and 255))
          Next
          
          if pad and 1 then .writetext  chrw(ImgArray(x2,y))
          if pad >1 then .writetext  chrw(0)
         Next
         
      Case Else
        WScript.Echo "ColorDepth not supported : " & ImgDepth & " bits"
      End Select

      
      Dim outf:Set outf= CreateObject("ADODB.Stream") 
      outf.Type    = 1 
      outf.Open
      .position=2              
      .CopyTo outf
      .close
      outf.savetofile filename,2   
      outf.close
    end with
  End Sub
end class



function hsv2rgb( Hue, Sat, Value) 
  dim Angle, Radius,Ur,Vr,Wr,Rdim
  dim r,g,b, rgb
  Angle = (Hue-150) *0.01745329251994329576923690768489
  Ur = Value * 2.55
  Radius = Ur * tan(Sat *0.01183199)
  Vr = Radius * cos(Angle) *0.70710678  
  Wr = Radius * sin(Angle) *0.40824829  
  r = (Ur - Vr - Wr)  
  g = (Ur + Vr - Wr) 
  b = (Ur + Wr + Wr) 
  
  
 if r >255 then 
   Rdim = (Ur - 255) / (Vr + Wr)
   r = 255
   g = Ur + (Vr - Wr) * Rdim
   b = Ur + 2 * Wr * Rdim 
 elseif r < 0 then
   Rdim = Ur / (Vr + Wr)
   r = 0
   g = Ur + (Vr - Wr) * Rdim
   b = Ur + 2 * Wr * Rdim 
 end if 

 if g >255 then 
   Rdim = (255 - Ur) / (Vr - Wr)
   r = Ur - (Vr + Wr) * Rdim
   g = 255
   b = Ur + 2 * Wr * Rdim
 elseif g<0 then   
   Rdim = -Ur / (Vr - Wr)
   r = Ur - (Vr + Wr) * Rdim
   g = 0
   b = Ur + 2 * Wr * Rdim   
 end if 
 if b>255 then
   Rdim = (255 - Ur) / (Wr + Wr)
   r = Ur - (Vr + Wr) * Rdim
   g = Ur + (Vr - Wr) * Rdim
   b = 255
 elseif b<0 then
   Rdim = -Ur / (Wr + Wr)
   r = Ur - (Vr + Wr) * Rdim
   g = Ur + (Vr - Wr) * Rdim
   b = 0
 end If
 
 hsv2rgb= ((b and &hff)+256*((g and &hff)+256*(r and &hff))and &hffffff)
end function

function ang(col,row)
    
    if col =0 then  
      if row<0 then ang=90 else ang=270 end if
    else  
   if col>0 then
      ang=atn(-row/col)*57.2957795130
   else
     ang=(atn(row/-col)*57.2957795130)+180
  end if
  end if
   ang=(ang+360) mod 360  
end function 


Dim X,row,col,fn,tt,hr,sat,row2
const h=160
const w=160
const rad=159
const r2=25500
tt=timer
fn=CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2)& "\testwchr.bmp"
Set X = (New ImgClass)(fn,w*2,h*2,1,32,0,0)

x.set0 w,h


for row=x.xmin+1 to x.xmax
   row2=row*row
   hr=int(Sqr(r2-row2))
   For col=hr To 159
     Dim a:a=((col\16 +row\16) And 1)* &hffffff
     x.imgArray(col+160,row+160)=a 
     x.imgArray(-col+160,row+160)=a 
   next    
   for col=-hr to hr
     sat=100-sqr(row2+col*col)/rad *50
    
     x.imgArray(col+160,row+160)=hsv2rgb(ang(row,col)+90,100,sat)
    next
    
  next  
Set X = Nothing