Task: Color wheel


C++: 
#include "colorwheelwidget.h"
#include <QPainter>
#include <QPaintEvent>
#include <cmath>

namespace {

QColor hsvToRgb(int h, double s, double v) {
    double hp = h/60.0;
    double c = s * v;
    double x = c * (1 - std::abs(std::fmod(hp, 2) - 1));
    double m = v - c;
    double r = 0, g = 0, b = 0;
    if (hp <= 1) {
        r = c;
        g = x;
    } else if (hp <= 2) {
        r = x;
        g = c;
    } else if (hp <= 3) {
        g = c;
        b = x;
    } else if (hp <= 4) {
        g = x;
        b = c;
    } else if (hp <= 5) {
        r = x;
        b = c;
    } else {
        r = c;
        b = x;
    }
    r += m;
    g += m;
    b += m;
    return QColor(r * 255, g * 255, b * 255);
}

}

ColorWheelWidget::ColorWheelWidget(QWidget *parent)
    : QWidget(parent) {
    setWindowTitle(tr("Color Wheel"));
    resize(400, 400);
}

void ColorWheelWidget::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    const QColor backgroundColor(0, 0, 0);
    const QColor white(255, 255, 255);
    painter.fillRect(event->rect(), backgroundColor);
    const int margin = 10;
    const double diameter = std::min(width(), height()) - 2*margin;
    QPointF center(width()/2.0, height()/2.0);
    QRectF rect(center.x() - diameter/2.0, center.y() - diameter/2.0,
                diameter, diameter);
    for (int angle = 0; angle < 360; ++angle) {
        QColor color(hsvToRgb(angle, 1.0, 1.0));
        QRadialGradient gradient(center, diameter/2.0);
        gradient.setColorAt(0, white);
        gradient.setColorAt(1, color);
        QBrush brush(gradient);
        QPen pen(brush, 1.0);
        painter.setPen(pen);
        painter.setBrush(brush);
        painter.drawPie(rect, angle * 16, 16);
    }
}



Go: package main

import (
    "github.com/fogleman/gg"
    "math"
)

const tau = 2 * math.Pi

func hsb2rgb(hue, sat, bri float64) (r, g, b int) {
    u := int(bri*255 + 0.5)
    if sat == 0 {
        r, g, b = u, u, u
    } else {
        h := (hue - math.Floor(hue)) * 6
        f := h - math.Floor(h)
        p := int(bri*(1-sat)*255 + 0.5)
        q := int(bri*(1-sat*f)*255 + 0.5)
        t := int(bri*(1-sat*(1-f))*255 + 0.5)
        switch int(h) {
        case 0:
            r, g, b = u, t, p
        case 1:
            r, g, b = q, u, p
        case 2:
            r, g, b = p, u, t
        case 3:
            r, g, b = p, q, u
        case 4:
            r, g, b = t, p, u
        case 5:
            r, g, b = u, p, q
        }
    }
    return
}

func colorWheel(dc *gg.Context) {
    width, height := dc.Width(), dc.Height()
    centerX, centerY := width/2, height/2
    radius := centerX
    if centerY < radius {
        radius = centerY
    }
    for y := 0; y < height; y++ {
        dy := float64(y - centerY)
        for x := 0; x < width; x++ {
            dx := float64(x - centerX)
            dist := math.Sqrt(dx*dx + dy*dy)
            if dist <= float64(radius) {
                theta := math.Atan2(dy, dx)
                hue := (theta + math.Pi) / tau
                r, g, b := hsb2rgb(hue, 1, 1)
                dc.SetRGB255(r, g, b)
                dc.SetPixel(x, y)
            }
        }
    }
}

func main() {
    const width, height = 480, 480
    dc := gg.NewContext(width, height)
    dc.SetRGB(1, 1, 1) 
    dc.Clear()
    colorWheel(dc)
    dc.SavePNG("color_wheel.png")
}