Làm thế nào tôi có thể tạo ra một bản đồ sao?


8

Tôi đang cố gắng tạo ra một bản đồ sao.

Cố gắng của tôi sẽ là:

  1. Có chiều rộng và chiều cao cho bản đồ.
  2. Đặt các điểm (sao) ngẫu nhiên trên diện tích chiều rộng và chiều cao.

Một cách tiếp cận đơn giản, nhưng nó có vấn đề đặt ngẫu nhiên các ngôi sao cực kỳ gần nhau.

Để giải quyết vấn đề này, một cách tiếp cận là có khoảng cách tối thiểu và khi tạo sao, bạn so sánh khoảng cách từ ngôi sao mới với mọi ngôi sao được tạo và nếu khoảng cách dưới mức tối thiểu, bạn tạo ra một ngôi sao mới, nhưng tôi không biết nếu đó là hiệu quả. Bất cứ lời khuyên?


3
Có thể có nhiều cách hiệu quả hơn để làm điều đó, nhưng tại sao nó không hiệu quả với bạn? Bạn có vấn đề với việc thực hiện này? Bạn đang tối ưu hóa sớm?
Vaillancourt

Mục đích của bản đồ sao là gì? Nó là một nền tảng, hoặc giống như một sân chơi?
Erik

@AlexandreVaillancourt yea Tôi không biết mình muốn tạo bao nhiêu ngôi sao và cảm giác như đó là một cách rất kém hiệu quả.
zebleckDAMM

@Erik không phải là nền, các ngôi sao bạn có thể tương tác
zebleckDAMM

Và ... bạn sẽ làm điều đó một thời gian hay ngoại tuyến?
Vaillancourt

Câu trả lời:


13

Một lấy mẫu Poisson-Đĩa phân phối sẽ cho phép bạn chọn điểm ngẫu nhiên khoảng cách tối thiểu ngoài & thuật toán Bridson của hiệu quả có thể giải quyết vấn đề trong thời gian O (n) - đủ nhanh cho thời gian thực cung cấp đếm sao bạn không nhận được quá lớn.

Thuật toán của Bridson chia vùng đầu ra thành một lưới các ô có kích thước tương ứng với khoảng cách tối thiểu cho phép, sao cho chỉ một điểm có thể xuất hiện trong mỗi ô. Sau đó, khi bạn xem xét thêm một điểm mới, bạn chỉ cần kiểm tra một bộ sưu tập các ô lân cận có hình dạng đĩa đối lập với toàn bộ danh sách các điểm. Ví dụ, hãy xem xét hình ảnh sau đây:

nhập mô tả hình ảnh ở đây

Khi kiểm tra xem dấu chấm màu xanh của ứng viên có quá gần với các chấm hiện có hay không, bạn không cần phải kiểm tra nó so với mọi dấu chấm hiện có. Thay vào đó, bạn có thể giới hạn tìm kiếm trong các dấu chấm trong các ô lân cận (mà bạn có thể tìm thấy nhanh chóng bằng bảng tra cứu). Mike Bostock có một hình ảnh động đẹp hiển thị thuật toán đang diễn ra.

Việc thực hiện tiêu chuẩn chỉ liên quan đến khoảng cách tối thiểu cố định giữa các điểm. Bài viết lấy mẫu Poisson Disk của Herman Tulleken (bao gồm mã nguồn) bao gồm một điều chỉnh cho việc thay đổi khoảng cách tối thiểu ở các phần khác nhau của hình ảnh; về cơ bản giống như một thuật toán hoà sắc . Sử dụng tiếng ồn perlin / tiếng ồn đơn giản như trong đám mây bài viết có thể cho bản đồ sao trông tự nhiên hơn. Ví dụ: tôi đã sử dụng hình ảnh bên trái để tạo bên phải:

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Để làm điều này, khi xem xét một điểm ứng cử viên, trước tiên tôi kiểm tra giá trị của hình ảnh đầu vào, nó mang lại giá trị từ 0 đến 1. Sau đó, tôi chia tỷ lệ này đến khoảng cách tối thiểu & tối đa mong muốn giữa các điểm; trong trường hợp này tôi đã chọn 5 & 20 pixel. Vì vậy, khi đặt một điểm trong vùng tối, các ngôi sao của tôi có thể ở gần 5 pixel với nhau & khi đặt các ngôi sao ở vùng sáng, chúng có thể cách nhau tối đa 20 pixel.

Điều đáng chú ý là việc tăng tốc của Bridson không hoạt động chính xác với lấy mẫu khoảng cách thay đổi vì các điểm đầu ra không sử dụng khoảng cách tối thiểu thống nhất. Tuy nhiên, bạn vẫn có thể sử dụng lưới đầu ra để giảm tìm kiếm. Lưới nhỏ hơn dẫn đến việc tìm kiếm hàng xóm gần nhất nhanh hơn với chi phí tăng bộ nhớ cho bảng tra cứu lớn hơn.


2
Các liên kết là rất tốt đẹp. Tuy nhiên, họ có thể bị lạc theo thời gian. Nó có thể tốt hơn để bao gồm nhiều chi tiết hơn ở đây.
Trilarion

Đã thêm một chút giải thích & minh họa để bảo vệ chống lại điều đó.
Pikalek

1

Một giải pháp rất ngây thơ nhưng đơn giản là chỉ cần luôn luôn nhảy khoảng cách "tối thiểu", và sau đó nối một số tiền ngẫu nhiên lên trên đó. Điều này có nghĩa là các ngôi sao sẽ không bao giờ có quá nhiều bạn thân, và ít nhất bạn sẽ có một chút sai lệch.

ví dụ

for (int x = 0; x < MAX_WIDTH; x+= MIN_SEPERATION_X)
{
  x += generateRandom();

  for (int y = 0; y < MAX_HEIGHT; y+= MIN_SEPERATION_Y)
  {
    y += generateRandom();

    if (x < MAX_WIDTH && y < MAX_HEIGHT)
    {
      image[x + y * width] = STAR;
    }
  }
}

(Chèn chức năng tạo số ngẫu nhiên yêu thích của bạn)


Nhưng nếu bạn đánh một ngôi sao khác ở đó thì sao? (Ngoài ra, các ngôi sao của bạn phải ở trong một dải nghiêng nếu làm như thế này.)
Trilarion

1
Có thể đánh một ngôi sao khác? Tôi chỉ giả sử một lần lặp trên toàn bộ hình ảnh. Không phải cả hai số luôn thay đổi bởi một khoảng cách tối thiểu dừng lại đó? Tôi nghe thấy sự hợp nhất của các ngôi sao khá lộn xộn nên tôi đồng ý rằng điều đó tốt để đảm bảo chúng không xảy ra. Gây ra một siêu tân tinh sẽ là một lỗi rất không phù hợp.
Huxellberger

Tôi có nghĩa là min_separation không được đảm bảo (không thể với thuật toán này) vì bạn luôn thêm các số ngẫu nhiên. Ít nhất là đảm bảo, các số ngẫu nhiên không thể lớn hơn min_separation. Khoảng cách tối thiểu được đảm bảo sau đó là min_separation - max (Gener_Random). Nhưng đó không phải là một cách tiếp cận thực sự xấu. +1
Trilarion

Cách tiếp cận này sẽ có xu hướng tạo ra các cột sao theo hàng dọc gọn gàng, vì bạn không thay đổi tọa độ x khi y thay đổi. Điều này dường như không phải là ngẫu nhiên hoặc tự nhiên cho các bộ sưu tập dày đặc.
DMGregory

0

Nếu bạn biết kích thước XYZ của không gian chơi của mình, bạn có thể chọn một điểm ngẫu nhiên trong không gian đó

và sau đó thực hiện SphereCast để kiểm tra xem đã có gì quá gần chưa.

//pseudo code

SpawnStar(){
 Vector3 spot = new vector3(random(0,world size),random(0,world size,random(0,world size)

  while(true){
  SphereCast(spot, radius)
   if(hit something){
      spot = get new random spot
    }else{
     SpawnStar();
     brake;
    }
  } 
}

Vấn đề với điều này là nó có thể sẽ không tốt cho thời gian thực, tuy nhiên đối với việc tạo trước nó vẫn ổn và khá nhanh.


1
Dù SphereCast là gì, đây không phải là giải pháp chính xác được đề cập trong câu hỏi và được coi là không hiệu quả?
Trilarion


1
Tôi nghĩ bạn có nghĩa là OverlapSphere. SphereCast bắn một quả cầu dọc theo một đường, vì vậy nó có dấu chân phát hiện hình viên nang.
DMGregory
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.