// This is free and unencumbered software released into the public domain.
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non-commercial, and by any
// means.
// In jurisdictions that recognize copyright laws, the author or authors
// of this software dedicate any and all copyright interest in the
// software to the public domain. We make this dedication for the benefit
// of the public at large and to the detriment of our heirs and
// successors. We intend this dedication to be an overt act of
// relinquishment in perpetuity of all present and future rights to this
// software under copyright law.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// For more information, please refer to <http://unlicense.org/>
import java.util.Random; // I can't stand arbitrary output
// Image parameters: This is the stuff that's easy to change
final int w = 640, h = 640, d = 640;
// Other locals
PImage img = createImage(w, h, RGB);
// Generic setup code: Nothing of interest happens here, I promise.
// This function just normalizes the x/y values to [0,1] and passes
// them to colAt() one by one to populate the image. In a fragment
// shader, this function would not exist.
void setup() {
size(w, h);
}
float zat = -1;
void draw() {
if (++zat > d)
zat = 0;
img.loadPixels();
int ind = 0;
for (int y = 0; y < h; ++y) {
float yf = y / (float)h;
for (int x = 0; x < w; ++x)
img.pixels[ind++] = colAt(x / (float)w, yf, zat / d);
}
img.updatePixels();
image(img, 0, 0);
}
// Utility functions, boilerplate boilerplate boilerplate
static float sqr(float x) { return x*x; }
static float hypot(float x, float y) { return sqrt(sqr(x) + sqr(y)); }
// This is where the actual logic starts.
float distLine(float x1, float y1, float z1, float x2, float y2, float z2, float x, float y, float z) {
float l2 = sqr(x1 - x2) + sqr(y1 - y2) + sqr(z1 - z2);
// System.out.println("(" + x1 + ", " + y1 + ") -> (" + x + ", " + y + ") = " + hypot(x - x1, y - y1));
if (l2 == 0) return sqrt(sqr(x - x1) + sqr(y - y1) + sqr(z - z1));
float t = ((x - x1) * (x2 - x1) + (y - y1) * (y2 - y1) + (z - z1) * (z2 - z1)) / l2;
if (t < 0) return sqrt(sqr(x-x1) + sqr(y-y1) + sqr(z-z1));
if (t > 1) return sqrt(sqr(x-x2) + sqr(y-y2) + sqr(z-z2));
return sqrt(sqr(x - (x1 + t * (x2 - x1))) + sqr(y - (y1 + t * (y2 - y1))) + sqr(z - (z1 + t * (z2 - z1))));
}
float lineLight(float x1, float y1, float z1, float x2, float y2, float z2, float r, float x, float y, float z) {
float dist = distLine(x1, y1, z1, x2, y2, z2, x, y, z);
if (dist >= r) return 0;
return 1 - dist / r;
}
// This function samples a pixel and is called millions of times to draw your image
color colAt(float x, float y, float z) {
return lerpColor(0x000000, 0xAFFFCF, lineLight(w/5, h/5, d*2.25/5, w*4/5, h*4/5, d*2.75/5, hypot(w/8, h/8), x * w, y * h, z * d));
}
Comments
0 B
|👍
/👎