Introduction
Local genius Calvin's Hobbies recently challenged us to trace the hue of an image. It is recommended to read his challenge beforehand, but to highlight the main points:
- The trace of hue in an image can be found by starting at one pixel, finding its hue angle(
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
), and moving one pixel's width in that direction. If this process is repeated, and a black pixel is left at each pixel passed, we produce a trace of the image.
Here is a simple example of the trace:
We start at pixel 250, 250
, with RGB color 36, 226, 132
. We observe that the hue of this color is 150. Thus, we begin drawing a black line 150 degrees counterclockwise from the positive x-axis. We run into the square to the left, with RGB color 100, 220, 7
and hue 94. This results in an almost vertical line to the next square. We continue the pattern into every square, and observe the change in slope at each new color. The length of this trace was 300 pixels. If you're wondering why the image is so ugly, it's because I randomly generated 25 colors in 100x100 squares and used my answer to trace it. On a much more complex and beautiful image, we may get a trace like this one:
- Calvin created this wonderful code snippet on the original post that draws a trace over an image, starting at the point provided by the mouse cursor. This is a very useful testing tool!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><style>canvas{border:1px solid black;}</style>Load an image: <input type='file' onchange='load(this)'><br><br>Max length <input id='length' type='text' value='300'><br><br><div id='coords'></div><br><canvas id='c' width='100' height='100'>Your browser doesn't support the HTML5 canvas tag.</canvas><script>function load(t){if(t.files&&t.files[0]){var e=new FileReader;e.onload=setupImage,e.readAsDataURL(t.files[0])}}function setupImage(t){function e(t){t.attr("width",img.width),t.attr("height",img.height);var e=t[0].getContext("2d");return e.drawImage(img,0,0),e}img=$("<img>").attr("src",t.target.result)[0],ctx=e($("#c")),ctxRead=e($("<canvas>"))}function findPos(t){var e=0,a=0;if(t.offsetParent){do e+=t.offsetLeft,a+=t.offsetTop;while(t=t.offsetParent);return{x:e,y:a}}return void 0}$("#c").mousemove(function(t){function e(t,e){var a=ctxRead.getImageData(t,e,1,1).data,i=a[0]/255,r=a[1]/255,o=a[2]/255;return Math.atan2(Math.sqrt(3)*(r-o),2*i-r-o)}if("undefined"!=typeof img){var a=findPos(this),i=t.pageX-a.x,r=t.pageY-a.y;$("#coords").html("x = "+i.toString()+", y = "+r.toString());var o=parseInt($("#length").val());if(isNaN(o))return void alert("Bad max length!");for(var n=[i],f=[r],h=0;n[h]>=0&&n[h]<this.width&&f[h]>=0&&f[h]<this.height&&o>h;)n.push(n[h]+Math.cos(e(n[h],f[h]))),f.push(f[h]-Math.sin(e(n[h],f[h]))),h++;ctx.clearRect(0,0,this.width,this.height),ctx.drawImage(img,0,0);for(var h=0;h<n.length;h++)ctx.fillRect(Math.floor(n[h]),Math.floor(f[h]),1,1)}});</script>
Snippet tested in Google Chrome
- Answers to that challenge may also serve as appropriate testing tools for this challenge.
Note: I do not take any credit for Calvin's work, and have received explicit permission to use his ideas in this challenge.
The Challenge
In that challenge, we found the trace. Now, I'm asking you to find the image. You will be given a start point, an end point, and a length
, and your program must output an image whose trace beginning at the start point arrives at the end point in approximately length
pixels. Moreover, because there are so many options, your program's algorithm must be inherently random in some regard--thus the same input should (more often than not) produce a different output image.
Input
You will receive seven positive integers as input: w, h, x1, y1, x2, y2, len
where:
x1, x2 < w <= 1920
y1, y2 < h <= 1080
len < 2000
These guidelines are minimum requirements. Your program may accept higher values.
You may receive input through stdin, a file, or as arguments to a function. You will ONLY receive these 5 integers as input.
Output
As output, produce an image of width w
and height h
with a continuous hue trace from x1,y1
to x2, y2
in approximately len
pixel-width steps.
- Output should be random.
- Output may be in any format--whether it be .bmp, .png, PPM, or an image shown on-screen at runtime makes no difference.
- You may assume it is possible to move from
x1, y1
tox2, y2
in underlen
pixels. - Output should NOT show the path of the trace from
x1, y1
tox2, y2
--though an image showing this path in your answer is appreciated.
Rules
- This is a popularity-contest! Try to make your output beautiful or interesting. More interesting hue traces than straight lines are also recommended.
- This is not code-golf. As such, readable code is appreciated. Still, try to keep size below ~2KB. This rule will not be strictly enforced.
- Values are approximate. If your code's trace reaches its destination within ~5-10% of
len
pixels, this is acceptable. Along this same vein, do not worry about slightly incorrect hue angle values. Some error is reasonable. - This is graphical-output. Please include output images of your solution in your answer.
- Standard Loopholes apply.
Questions, comments, concerns? Let me know!
atan((y1-y2)/(x1-x2))
you could quite easily find a "random" color whose hue is this angle. You could then draw a solid line of this color between the points on a white background, divert a bit to account for length, and boom. I really want to promote creativity with this question, and I don't think code-golf does that. \$\endgroup\$