#lang racket
(require racket/draw plot/utils )
(define (rgb-delta rgb-1 rgb-2)
(vector (- (send rgb-1 red) (send rgb-2 red))
(- (send rgb-1 green) (send rgb-2 green))
(- (send rgb-1 blue) (send rgb-2 blue)) ))
(define (delta? a)
(and (vector? a)
(= (vector-length a) 3)))
(define (red delta) (vector-ref delta 0))
(define (green delta) (vector-ref delta 1))
(define (blue delta) (vector-ref delta 2))
(define (exact->byte a)
(if [and [<= a 255] [>= a 0]]
(round a)
(error "Delta Color: exact->byte: out of color space error: " a) ))
(define (make-rgb r g b)
(make-color (exact->byte r)
(exact->byte g)
(exact->byte b)))
(define (rgb-delta-plus rgb delta)
(make-rgb (+ (send rgb red) (red delta))
(+ (send rgb green) (green delta))
(+ (send rgb blue) (blue delta))))
(define (rgb-delta-minus rgb delta)
(make-rgb (- (send rgb red) (red delta))
(- (send rgb green) (green delta))
(- (send rgb blue) (blue delta))))
(define (color? a) (is-a? a color%))
(define (subtract a b)
(cond ([and (color? a) (color? b)] (rgb-delta a b))
([and (color? a) (delta? b)] (rgb-delta-minus a b))
([and (delta? a) (delta? b)] (v- a b))
(else
(error "Delta Color: subtract: out of domain error"))))
(define divide v/)
(define multiply v*)
(define (add a b)
(cond ([and (delta? a) (delta? b)] (v+ a b)) ([and (delta? a) (color? b)] (rgb-delta-plus b a))
([and (color? a) (delta? b)]
(rgb-delta-plus a b))
(else
(error "Delta Color: add: out of domain error"))))
(provide add subtract multiply divide delta?)