Máy tạo sơ đồ Voronoi ngẫu nhiên có ai không?
OK, điều này đã cho tôi một thời gian khó khăn. Tôi nghĩ rằng nó khá đẹp tuy nhiên, ngay cả khi kết quả không quá arty như một số người khác. Đó là thỏa thuận với sự ngẫu nhiên. Có thể một số hình ảnh trung gian trông tốt hơn, nhưng tôi thực sự muốn có một thuật toán hoạt động hoàn toàn với sơ đồ voronoi.
Biên tập:
Đây là một ví dụ về thuật toán cuối cùng. Hình ảnh về cơ bản là sự chồng chất của ba sơ đồ voronoi, một cho mỗi thành phần màu (đỏ, xanh lá cây, xanh dương).
Mã
không có ý kiến, phiên bản nhận xét ở cuối
unsigned short red_fn(int i, int j){
int t[64],k=0,l,e,d=2e7;srand(time(0));while(k<64){t[k]=rand()%DIM;if((e=_sq(i-t[k])+_sq(j-t[42&k++]))<d)d=e,l=k;}return t[l];
}
unsigned short green_fn(int i, int j){
static int t[64];int k=0,l,e,d=2e7;while(k<64){if(!t[k])t[k]=rand()%DIM;if((e=_sq(i-t[k])+_sq(j-t[42&k++]))<d)d=e,l=k;}return t[l];
}
unsigned short blue_fn(int i, int j){
static int t[64];int k=0,l,e,d=2e7;while(k<64){if(!t[k])t[k]=rand()%DIM;if((e=_sq(i-t[k])+_sq(j-t[42&k++]))<d)d=e,l=k;}return t[l];
}
Tôi đã mất rất nhiều nỗ lực, vì vậy tôi cảm thấy muốn chia sẻ kết quả ở các giai đoạn khác nhau và có những kết quả tốt (không chính xác) để hiển thị.
Bước đầu tiên: có một số điểm được đặt ngẫu nhiên, với x=y
Tôi đã chuyển đổi nó thành jpeg vì png ban đầu quá nặng để tải lên ( >2MB
), tôi cá rằng đó là cách hơn 50 sắc thái của màu xám!
Thứ hai: có tọa độ y tốt hơn
Tôi không đủ khả năng để có một bảng tọa độ khác được tạo ngẫu nhiên cho y
trục, vì vậy tôi cần một cách đơn giản để có được các tọa độ " ngẫu nhiên " trong càng ít ký tự càng tốt. Tôi đã sử dụng x
tọa độ của một điểm khác trong bảng, bằng cách thực hiện một chút AND
theo chỉ số của điểm.
Thứ 3: Tôi không nhớ nhưng nó đang trở nên tốt đẹp
Nhưng tại thời điểm này, tôi đã vượt quá 140 ký tự, vì vậy tôi cần phải đánh nó xuống một chút.
Thứ 4: đường quét
Đùa thôi, đây không phải là muốn nhưng loại methinks thú vị.
Vẫn đang làm việc để giảm kích thước của thuật toán, tôi tự hào trình bày:
Phiên bản StarFox
Instagram inston
Thứ 5: tăng số điểm
Bây giờ tôi có một đoạn mã đang hoạt động, vì vậy hãy đi từ 25 đến 60 điểm.
Điều đó thật khó để nhìn thấy chỉ từ một hình ảnh, nhưng các điểm gần như nằm trong cùng một y
phạm vi. Tất nhiên, tôi đã không thay đổi thao tác bitwise, &42
tốt hơn nhiều:
Và chúng ta ở đây, cùng một điểm với hình ảnh đầu tiên từ bài đăng này. Bây giờ chúng ta hãy giải thích mã cho những người hiếm hoi sẽ quan tâm.
Mã bị giải thích và giải thích
unsigned short red_fn(int i, int j)
{
int t[64], // table of 64 points's x coordinate
k = 0, // used for loops
l, // retains the index of the nearest point
e, // for intermediary results
d = 2e7; // d is the minimum distance to the (i,j) pixel encoutnered so far
// it is initially set to 2e7=2'000'000 to be greater than the maximum distance 1024²
srand(time(0)); // seed for random based on time of run
// if the run overlaps two seconds, a split will be observed on the red diagram but that is
// the better compromise I found
while(k < 64) // for every point
{
t[k] = rand() % DIM; // assign it a random x coordinate in [0, 1023] range
// this is done at each call unfortunately because static keyword and srand(...)
// were mutually exclusive, lenght-wise
if (
(e= // assign the distance between pixel (i,j) and point of index k
_sq(i - t[k]) // first part of the euclidian distance
+
_sq(j - t[42 & k++]) // second part, but this is the trick to have "" random "" y coordinates
// instead of having another table to generate and look at, this uses the x coordinate of another point
// 42 is 101010 in binary, which is a better pattern to apply a & on; it doesn't use all the table
// I could have used 42^k to have a bijection k <-> 42^k but this creates a very visible pattern splitting the image at the diagonal
// this also post-increments k for the while loop
) < d // chekcs if the distance we just calculated is lower than the minimal one we knew
)
// { // if that is the case
d=e, // update the minimal distance
l=k; // retain the index of the point for this distance
// the comma ',' here is a trick to have multiple expressions in a single statement
// and therefore avoiding the curly braces for the if
// }
}
return t[l]; // finally, return the x coordinate of the nearest point
// wait, what ? well, the different areas around points need to have a
// "" random "" color too, and this does the trick without adding any variables
}
// The general idea is the same so I will only comment the differences from green_fn
unsigned short green_fn(int i, int j)
{
static int t[64]; // we don't need to bother a srand() call, so we can have these points
// static and generate their coordinates only once without adding too much characters
// in C++, objects with static storage are initialized to 0
// the table is therefore filled with 60 zeros
// see http://stackoverflow.com/a/201116/1119972
int k = 0, l, e, d = 2e7;
while(k<64)
{
if( !t[k] ) // this checks if the value at index k is equal to 0 or not
// the negation of 0 will cast to true, and any other number to false
t[k] = rand() % DIM; // assign it a random x coordinate
// the following is identical to red_fn
if((e=_sq(i-t[k])+_sq(j-t[42&k++]))<d)
d=e,l=k;
}
return t[l];
}
Cảm ơn đã đọc cho đến nay.