좋아, 이것은 나에게 어려운 시간을 주었다. 나는 결과가 다른 것들 만큼 예술적 이지 않더라도 꽤 멋지다고 생각합니다 . 그것은 무작위성에 관한 것입니다. 일부 중간 이미지가 더 좋아 보일 수도 있지만 voronoi 다이어그램으로 완전히 작동하는 알고리즘을 원했습니다.
편집하다:
이것이 최종 알고리즘의 한 예입니다. 이미지는 기본적으로 각 색 구성 요소 (빨강, 녹색, 파랑)마다 하나씩 3 개의 보로 노이 다이어그램의 중첩입니다.
암호
끝에 ungolfed, 댓글 버전
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];
}
많은 노력이 필요했기 때문에 결과를 다른 단계에서 공유하고 싶은 느낌이 들었습니다.
첫 번째 단계 : 일부 점을 무작위로 배치하고 x=y
원본 png가 너무 커서 업로드 ( >2MB
) 하기 때문에 jpeg로 변환했습니다 .
둘째 : 더 나은 y 좌표를 가지십시오
y
축에 대해 무작위로 생성 된 다른 좌표 테이블을 가질 여유가 없었기 때문에 가능한 한 적은 문자로 " 임의의 " 좌표 를 얻는 간단한 방법이 필요했습니다 . x
포인트 AND
의 인덱스 에서 비트 단위로 테이블의 다른 포인트 좌표 를 사용했습니다 .
세번째 : 기억 나지 않지만 점점 좋아지고 있습니다
그러나이 시점에서 나는 140자를 넘었습니다.
네 번째 : 스캔 라인
농담, 이것은 원치 않는 일종의 시원하고 methinks입니다.
알고리즘의 크기를 줄이는 데 여전히 노력하고 있으며, 나는 자랑스럽게 발표합니다.
스타 폭스 에디션
보로 노이 instagram
다섯 번째 : 포인트 수를 늘리십시오
이제 코드가 작동하므로 25 포인트에서 60 포인트로 넘어 갑시다.
하나의 이미지에서만보기는 어렵지만 포인트는 모두 거의 같은 y
범위에 있습니다. 물론 비트 단위 작업을 변경하지 않은 &42
것이 훨씬 좋습니다.
그리고 우리는이 포스트의 첫 이미지와 같은 시점에 있습니다. 관심있는 희귀 코드에 대한 코드를 설명하겠습니다.
Ungolfed 및 설명 된 코드
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];
}
지금까지 읽어 주셔서 감사합니다.