【发布时间】:2018-04-10 06:54:34
【问题描述】:
我正在谈论的完整演示在这里: https://ggodfrey.github.io/ComplexColor/index.html
我正在尝试制作一个可以尝试使用颜色绘制复值函数的网站。色调是使用复数答案的角度确定的,亮度是通过对复数答案的大小取对数然后找到小数部分来确定的。从那里,我使用一个函数将 HSL 转换为 RGB,然后将其放入我在画布上绘制的 Image 对象中,从而允许我在每个像素上进行绘制。
如上页所示,亮度“级别”在对数从一个整数变为另一个整数之间具有“粗糙”边缘。它应该看起来更像this。这个问题与我实际计算亮度的方式或使用 javascript 画布有关吗?
window.onload = function(){
var EQUATION = '';
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var x_min = -3;
var x_max = 3;
var y_min = -3;
var y_max = 3;
var image = ctx.createImageData(canvas.width, canvas.height);
Complex = function(re, im){
this.re = re;
this.im = im;
}
Complex.prototype.add = function(other){
return new Complex(this.re+other.re, this.im+other.im);
}
Complex.prototype.multiply = function(other){
return new Complex(this.re*other.re-other.im*this.im, this.re*other.im+this.im*other.re);
}
Complex.prototype.power = function(num){
var r = this.magnitude();
var theta = this.angle();
var a = Math.pow(r, num)*Math.cos(num*theta);
var b = Math.pow(r, num)*Math.sin(num*theta);
return new Complex(a, b);
}
Complex.prototype.magnitude = function(){
return Math.pow(Math.pow(this.re, 2) + Math.pow(this.im, 2), 0.5);
}
Complex.prototype.angle = function(){
return Math.atan2(this.im, this.re);
}
Complex.prototype.divide = function(other){
x = new Complex(this.re, this.im);
y = new Complex(other.re, other.im);
x = x.multiply(new Complex(other.re, -other.im));
y = y.multiply(new Complex(other.re, -other.im));
x = new Complex(x.re/y.re, x.im/y.re);
return x;
}
function hslToRgb(h, s, l){ //NOT MY CODE
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
} else {
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3.0);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3.0);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
function evaluate(i, j){
var z = new Complex(x_min+j*(x_max-x_min)/canvas.width, y_min+i*(y_max-y_min)/canvas.height);
var num = z.power(2).add(new Complex(-1, 0)).multiply(z.add(new Complex(-2, -1)).power(2));
var den = z.power(2).add(new Complex(2, 4));
var end = num.divide(den);
var color = end.angle()/(2*Math.PI);
var brightness = end.magnitude();
brightness = Math.log(brightness)/Math.log(2) % 1;
return [color, brightness];
}
function main(){
var data = image.data;
if(EQUATION !== null){
var count = 0;
for(var i=0;i<canvas.height;i++){
for(var j=0;j<canvas.width;j++){
var c = evaluate(i, j);
rgb = hslToRgb(c[0], 1, 0.4+c[1]/5);
var r = rgb[0];
var g = rgb[1];
var b = rgb[2];
var c = count*4;
data[c] = r;
data[c+1] = g;
data[c+2] = b;
data[c+3] = 255;
count++;
}
}
image.data = data;
ctx.putImageData(image, 0, 0);
}
}
main();
function getMousePos(canvas, evt){
var rect = canvas.getBoundingClientRect();
return {x: (evt.clientX-rect.left)/(rect.right-rect.left)*canvas.width,
y: (evt.clientY-rect.top)/(rect.bottom-rect.top)*canvas.height};
}
document.getElementById("submit").addEventListener("mousedown", function(event){
EQUATION = document.getElementById("equation").innerHTML;
var x = main();
})
document.getElementById("canvas").addEventListener("mousemove", function(event){
var loc = getMousePos(canvas, event);
document.getElementById('x').innerHTML = Math.round(loc.x*100)/100;
document.getElementById('y').innerHTML = Math.round(loc.y*100)/100;
document.getElementById('brightness').innerHTML = evaluate(loc.y, loc.x)[1];
})
}
<head>
<title>Complex Color</title>
<meta charset="utf-8"></head>
<body>
<input id="equation" type="text">Type Equation</input><button id="submit">Submit</button><br>
<canvas id="canvas" style="width:500px;height:500px"></canvas><p> <span id="x"></span>, <span id="y"></span>, <span id="brightness"></span></p>
</body>
【问题讨论】:
标签: javascript html5-canvas complex-numbers