มี (ครอบครัวของ) ฟังก์ชั่นเสียงรบกวนไม่ลดลง monotonically (s)?


10

ฉันต้องการฟังก์ชั่นในการเคลื่อนไหววัตถุที่เคลื่อนที่จากจุด A ไปยังจุด B เมื่อเวลาผ่านไปเช่นถึงจุด B ในเวลาที่กำหนด แต่ตำแหน่งของมันในเวลาใดก็ได้จะถูกรบกวนแบบสุ่มอย่างต่อเนื่อง แต่ไม่ย้อนกลับ วัตถุเคลื่อนที่ไปตามเส้นตรงดังนั้นฉันต้องการเพียงมิติเดียว

ในทางคณิตศาสตร์นั่นหมายความว่าฉันกำลังมองหา f (x) ต่อเนื่อง, x ∈ [0,1], เช่นนั้น:

  • f (0) = 0
  • f (1) = 1
  • x <y → f (x) ≤ f (y)
  • ที่คะแนน "มากที่สุด" f (x + d) - f (x) ไม่มีความสัมพันธ์ที่ชัดเจนกับ d (ฟังก์ชั่นไม่ได้เพิ่มขึ้นอย่างสม่ำเสมอหรือคาดการณ์ได้ฉันคิดว่ามันก็เทียบเท่ากับการบอกว่าไม่มีอนุพันธ์ระดับใดคงที่)

โดยหลักการแล้วฉันอยากได้ครอบครัวที่มีฟังก์ชั่นเหล่านี้โดยระบุสถานะเมล็ดพันธุ์ ฉันต้องการเมล็ดพันธุ์อย่างน้อย 4 บิต (ฟังก์ชั่นที่เป็นไปได้ 16 ฟังก์ชัน) สำหรับการใช้งานในปัจจุบันของฉัน แต่เนื่องจากไม่มีความรู้สึกที่จะให้มากขึ้น

เพื่อหลีกเลี่ยงปัญหาต่าง ๆ ที่มีข้อผิดพลาดการสะสมฉันต้องการฟังก์ชั่นที่ไม่ต้องการสถานะภายในใด ๆ นั่นคือฉันต้องการให้มันเป็นฟังก์ชั่นจริงไม่ใช่ฟังก์ชั่นการเขียนโปรแกรม


3
ข้อกำหนดที่สามและสี่ของคุณสามารถประมาณได้f'(x)>0ดังนั้นการรวมปกติของค่าสัมบูรณ์ของฟังก์ชั่นเสียงใด ๆ จะตอบสนองความต้องการของคุณทั้งหมด น่าเสียดายที่ฉันไม่รู้วิธีง่ายๆในการคำนวณสิ่งนั้น แต่อาจมีคนอื่นทำ :)
SkimFlux

จะรบกวนการตั้งฉากของฟังก์ชันของคุณในทันที
kaoD

เมื่อคุณพูดว่า "เพื่อหลีกเลี่ยงปัญหาต่าง ๆ ที่มีข้อผิดพลาดการสะสม" ฉันคิดว่าคุณกังวลเกี่ยวกับความแม่นยำ ดูเหมือนว่าคุณมีความกังวลกับต้นทุนด้านประสิทธิภาพของการประเมินที่มากเกินไป คุณควรระบุให้ชัดเจนว่าข้อ จำกัด ด้านประสิทธิภาพและหน่วยความจำที่เราต้องปฏิบัติคืออะไรความต้องการนั้นไม่สามารถช่วยเหลือได้เนื่องจากเราสามารถสร้างฟังก์ชั่นที่มีสถานะซึ่งไม่มีข้อผิดพลาดในการสะสมได้ นอกจากนี้จุดที่ 4 ของคุณผิด ตัวอย่างเล็ก ๆ น้อย ๆ : ไม่มีอนุพันธ์ของ e ^ x เป็นค่าคงที่ดังนั้นจึงไม่เท่ากับการพูดอย่างนั้น
Superbest

คำตอบ:


4

สำหรับโพสต์นี้ y = f (t) โดยที่ t คือพารามิเตอร์ที่คุณเปลี่ยนแปลง (เวลา / ความคืบหน้า) และ y คือระยะทางไปยังเป้าหมาย ดังนั้นฉันจะพูดในแง่ของคะแนนในแปลง 2 มิติที่แกนนอนคือเวลา / ความคืบหน้าและแนวตั้งคือระยะทาง

ฉันคิดว่าคุณสามารถสร้างโค้ง Bezier ลูกบาศก์โดยมีจุดแรกที่ (0, 1) และจุดที่สี่ (สุดท้าย) ที่ (1, 0) จุดกึ่งกลางสองจุดสามารถวางแบบสุ่ม (x = rand, y = rand) ภายในสี่เหลี่ยม 1 ต่อ 1 ฉันไม่สามารถยืนยันการวิเคราะห์นี้ได้ แต่จากการเล่นกับแอปเพล็ต (ใช่ไปข้างหน้าแล้วหัวเราะ) ดูเหมือนว่าเส้นโค้ง Bezier จะไม่ลดลงด้วยข้อ จำกัด ดังกล่าว

นี่จะเป็นฟังก์ชั่นพื้นฐานของคุณ b (p1, p2) ซึ่งให้เส้นทางที่ไม่ลดลงจากจุด p1 ไปยังจุด p2

ตอนนี้คุณสามารถสร้าง ab (p (1) = (0, 1), p (n) = (1, 0)) และเลือกจำนวน p (i) ตามเส้นโค้งนี้เช่นที่ 1

โดยพื้นฐานแล้วคุณกำลังสร้างเส้นทาง "ทั่วไป" หนึ่งเส้นทางจากนั้นแยกเป็นกลุ่มและสร้างแต่ละส่วนใหม่

เนื่องจากคุณต้องการฟังก์ชั่นทางคณิตศาสตร์: สมมติว่าขั้นตอนข้างต้นได้รับการบรรจุไว้ในฟังก์ชั่นหนึ่ง y = f (t, s) ซึ่งให้ระยะทางที่ t สำหรับฟังก์ชันของเมล็ด s คุณจะต้องการ:

  • 4 ตัวเลขแบบสุ่มสำหรับการวางจุดกลาง 2 จุดของเส้นแบ่ง Bezier หลัก (จาก (0, 1) ถึง (1, 0))
  • หมายเลข n-1 สำหรับขอบเขตของแต่ละเซกเมนต์หากคุณมีเซกเมนต์ n ส่วน (ส่วนแรกจะเริ่มต้นที่ (0, 1) คือ t = 0 และสิ้นสุดสุดท้ายที่ (1,0) ie t = 1)
  • 1 หมายเลขถ้าคุณต้องการสุ่มจำนวนเซ็กเมนต์
  • 4 ตัวเลขเพิ่มเติมสำหรับการวางจุดกลางของเส้นโค้งของส่วนที่คุณที่ดินของคุณที่

ดังนั้นแต่ละเมล็ดต้องจัดหาอย่างใดอย่างหนึ่งต่อไปนี้:

  • 7 + n จำนวนจริงระหว่าง 0 ถึง 1 (ถ้าคุณต้องการควบคุมจำนวนของกลุ่ม)
  • 7 จำนวนจริงและหนึ่งจำนวนเต็มมากกว่า 1 (สำหรับจำนวนเซ็กเมนต์สุ่ม)

ฉันจินตนาการว่าคุณสามารถทำสิ่งเหล่านี้ได้โดยเพียงแค่ใส่จำนวนตัวเลขเป็นเมล็ด หรือคุณสามารถทำสิ่งต่าง ๆ เช่นจัดหาหนึ่งหมายเลขเป็นเมล็ดแล้วเรียกตัวสร้างตัวเลขสุ่มในตัวด้วย rand (s), rand (s + 1), rand (s + 2) และอื่น ๆ (หรือเริ่มต้นด้วย s แล้วเรียก rand.NextNumber ต่อไป)

โปรดทราบว่าแม้ว่าฟังก์ชั่นทั้งหมด f (t, s) ประกอบด้วยหลายกลุ่มคุณจะประเมินเพียงหนึ่งส่วนสำหรับแต่ละ t คุณจะต้องคำนวณขอบเขตของเซกเมนต์ซ้ำ ๆ ด้วยวิธีนี้เนื่องจากคุณจะต้องเรียงลำดับเพื่อให้แน่ใจว่าไม่มีเซกเมนต์ซ้อนทับกันสองส่วน คุณอาจจะปรับให้เหมาะสมและกำจัดงานพิเศษนี้และหาจุดสิ้นสุดของหนึ่งเซ็กเมนต์สำหรับการโทรแต่ละครั้ง แต่ตอนนี้ฉันยังไม่เห็นชัดเจน

นอกจากนี้ไม่จำเป็นต้องใช้เส้นโค้ง Bezier เส้นโค้งใด ๆ ที่เหมาะสมจะทำ

ฉันสร้างตัวอย่างการนำ Matlab มาใช้

ฟังก์ชัน Bezier (vectorized):

function p = bezier(t, points)
% p = bezier(t, points) takes 4 2-dimensional points defined by 2-by-4 matrix
% points and gives the value of the Bezier curve between these points at t.
% 
% t can be a number or 1-by-n vector. p will be an n-by-2 matrix.
    coeffs = [
        (1-t').^3, ...
        3*(1-t').^2.*t', ...
        3*(1-t').*t'.^2, ...
        t'.^3
    ];

    p = coeffs * points;
end

ฟังก์ชั่นสารประกอบ Bezier ที่อธิบายไว้ข้างต้น (จงใจเปิดโปงซ้ายเพื่อให้ชัดเจนว่าจำเป็นต้องมีการประเมินจำนวนเท่าใดสำหรับการโทรแต่ละครั้ง):

function p = bezier_compound(t, ends, s)
% p = bezier(t, points) takes 2 2-dimensional endpoints defined by a 2-by-2
% matrix ends and gives the value of a "compound" Bezier curve between
% these points at t.
% 
% t can be a number or 1-by-n vector. s must be a 1-by-7+m vector of random
% numbers from 0 to 1. p will be an n-by-2 matrix. 
    %% Generate a list of segment boundaries
    seg_bounds = [0, sort(s(9:end)), 1];

    %% Find which segment t falls on
    seg = find(seg_bounds(1:end-1)<=t, 1, 'last');

    %% Find the points that segment boundaries evaluate to
    points(1, :) = ends(1, :);
    points(2, :) = [s(1), s(2)];
    points(3, :) = [s(3), s(4)];
    points(4, :) = ends(2, :);

    p1 = bezier(seg_bounds(seg), points);
    p4 = bezier(seg_bounds(seg+1), points);

    %% Random middle points
    p2 = [s(5), s(6)] .* (p4-p1) + p1;
    p3 = [s(7), s(8)] .* (p4-p1) + p1;

    %% Gather together these points
    p_seg = [p1; p2; p3; p4];

    %% Find what part of this segment t falls on
    t_seg = (t-seg_bounds(seg))/(seg_bounds(seg+1)-seg_bounds(seg));

    %% Evaluate
    p = bezier(t_seg, p_seg);    
end

สคริปต์ที่พล็อตฟังก์ชั่นสำหรับเมล็ดสุ่ม (โปรดทราบว่านี่เป็นที่เดียวที่มีการเรียกใช้ฟังก์ชั่นสุ่มตัวแปรสุ่มไปยังรหัสอื่น ๆ ทั้งหมดจะถูกถ่ายทอดจากอาร์เรย์สุ่มอันนี้):

clear
clc

% How many samples of the function to plot (higher = higher resolution)
points = 1000;

ends = [
    0, 0;
    1, 1;
    ];

% a row vector of 12 random points
r = rand(1, 12);

p = zeros(points, 2);

for i=0:points-1
    t = i/points;
    p(i+1, :) = bezier_compound(t, ends, r);
end

% We take a 1-p to invert along y-axis here because it was easier to
% implement a function for slowly moving away from a point towards another.
scatter(p(:, 1), 1-p(:, 2), '.');
xlabel('Time');
ylabel('Distance to target');

นี่คือผลลัพธ์ตัวอย่าง:

ป้อนคำอธิบายรูปภาพที่นี่

ดูเหมือนจะเป็นไปตามเกณฑ์ส่วนใหญ่ของคุณ อย่างไรก็ตาม:

  • มี "มุม" สิ่งนี้อาจคล้อยตามโดยใช้เส้นโค้ง Bezier อย่างเหมาะสมยิ่งขึ้น
  • มัน "ชัด" ดูเหมือนว่า splines แม้ว่าคุณจะไม่สามารถคาดเดาได้จริง ๆ ว่ามันจะทำอะไรหลังจากช่วงเวลาที่ไม่สำคัญนอกเสียจากว่าคุณรู้จักเมล็ด
  • มันไม่ค่อยเบี่ยงเบนไปทางมุมมากเกินไป (สามารถแก้ไขได้ด้วยการเล่นกับการกระจายของเครื่องกำเนิดเมล็ด)
  • ฟังก์ชั่นลูกบาศก์เบซิเยร์ไม่สามารถไปถึงบริเวณใกล้มุมได้เนื่องจากข้อ จำกัด เหล่านี้

1

ฉันเดาว่าแทนที่จะผสมผสานโคไซน์ที่แปลงสภาพแล้ว (เช่นผลิตภัณฑ์ดอทในเสียงเพอร์ลินให้คุณ) คุณสามารถผสมผสานฟังก์ชั่นแบบโมโนโพนิกหลายตัวที่เริ่มต้นที่ f (0) = 0 เช่น f (x) = x หรือ 2x หรือ x ^ 2 เป็นต้นในความเป็นจริงเนื่องจากโดเมนของคุณถูก จำกัด ที่ 0 => 1 คุณสามารถผสมผสานฟังก์ชันตรีโกณฯ ที่เหมาะสมกับการเรียกเก็บเงินภายในโดเมนนั้นเช่น cos (90 * x + 270) เพื่อทำให้วิธีการปกติของคุณสิ้นสุดที่ 1 คุณสามารถหารผลรวมถ่วงน้ำหนักของวิธีการ monotonic เหล่านี้เริ่มต้นที่ f (0) = 0 โดย f (1) บางสิ่งเช่นนี้ควรกลับด้านค่อนข้างง่ายเช่นกัน (ซึ่งฉันรวบรวมคุณจากบิตเกี่ยวกับฟังก์ชั่นจริงไร้สัญชาติกับฟังก์ชั่นการเขียนโปรแกรม)

หวังว่านี่จะช่วยได้


1

คุณสามารถวิเคราะห์ภาพที่หยาบคายนี้ได้ป้อนคำอธิบายรูปภาพที่นี่ คุณสามารถจบลงด้วยฟังก์ชั่นที่ทำแอนิเมชั่นของคุณได้ทันทีโดยใช้ฟังก์ชั่นแรนด์แบบสม่ำเสมอ ฉันรู้ว่านี่ไม่ใช่สูตรทางคณิตศาสตร์ที่แน่นอน แต่จริงๆแล้วไม่มีสูตรทางคณิตศาสตร์สำหรับฟังก์ชั่นการสุ่มและแม้ว่าจะมีสูตรหนึ่งคุณก็ต้องเขียนโค้ดจำนวนมากเพื่อให้ได้สิ่งนี้ เมื่อพิจารณาว่าคุณไม่ได้ระบุเงื่อนไขความนุ่มนวลโปรไฟล์ความเร็วคือ $ C ^ 0 $ ต่อเนื่อง (แต่เนื่องจากคุณไม่ได้จัดการกับหุ่นยนต์คุณไม่จำเป็นต้องกังวลเกี่ยวกับโปรไฟล์เร่งความเร็วที่ไม่ต่อเนื่อง)


"จริงๆแล้วไม่มีสูตรทางคณิตศาสตร์สำหรับฟังก์ชั่นแบบสุ่ม" ฉันต้องการฟังก์ชั่นเสียงรบกวนไม่ใช่ฟังก์ชั่นแบบสุ่ม ฟังก์ชั่นเสียงรบกวนได้รับการบันทึกไว้เป็นอย่างดี ความหมายทีละน้อยเช่นนี้มีแนวโน้มที่จะสร้างความไร้ประสิทธิภาพอย่างใดอย่างหนึ่ง (การประเมินกลายเป็น O (ชิ้นส่วน) ซึ่งกลายเป็นปัญหาเมื่อคุณมีระยะเวลานาน), ฟังก์ชันที่ไม่บริสุทธิ์ (ประเมินใน O (1) แต่ต้องรักษาตำแหน่งก่อนหน้า) หรือ ฟังก์ชั่น จำกัด ที่เป็นไปได้ (เช่นจุดผันทั้งหมดอยู่ในช่วงเวลาคงที่)

อืมฉันคิดว่าฟังก์ชั่นเสียงรบกวนนั้นใช้ตัวสร้างตัวเลขแบบสุ่มและยังขึ้นอยู่กับชุดคู่มือ / จุดสำคัญที่ไม่ต่อเนื่องเพื่อให้ได้รูปร่าง (ฉันเห็น Perlin Noise ถูกกล่าวถึง .. หนึ่งในนั้นทำงานด้วยการสุ่มหลอก เครื่องกำเนิดตัวเลขที่ยากที่จะรวมเข้าด้วยกันจึงไม่มีวิธีการวิเคราะห์) หนึ่งสามารถรวมฟังก์ชั่นเสียงรบกวนการวิเคราะห์? ผมสงสัยว่าถ้าคนเหล่านี้อาจจะเป็นผู้สมัครที่เชื่อมโยง
teodron

ตัวอย่างเสียงเพอร์ลินใช้สถานะเมล็ดของตัวเลข 255 8 บิต แต่จากนั้นจะสร้างสัญญาณรบกวนแบบสุ่มในระยะไม่ จำกัด ในสามมิติ มันไม่ถูกต้องนักที่จะอธิบายว่ามันเป็น "จุดชี้แนะทาง" ในทางคณิตศาสตร์พวกมันก็เหมือนกับพารามิเตอร์อีก 256 ตัวที่คุณไม่ต้องการให้ อย่างที่คุณบอกว่ามันไม่สามารถบูรณาการได้ แต่มันเป็นฟังก์ชั่นที่บริสุทธิ์ หน้าที่คุณเชื่อมโยงไปนั้นเป็นคำอธิบายที่ไม่ถูกต้องเกี่ยวกับสัญญาณรบกวนของ Perlin (ไม่ใช่เสียงรบกวนของ Perlin ที่เขาอธิบาย) ในฐานะที่เป็นไม่ว่าจะเป็นไปได้สำหรับบางชนิดของฟังก์ชั่นเสียง ... ดีว่าเป็นคำถามที่ไม่ได้หรือไม่

1

วิธีปกติในการสร้างลำดับที่เพิ่มขึ้นของตัวเลขสุ่ม N จาก [0,1] คือการสร้างตัวเลขสุ่ม N ในช่วงใด ๆ จากนั้นหารพวกเขาทั้งหมดด้วยผลรวมทั้งหมดแล้วรวมพวกเขาครั้งละหนึ่งครั้งเพื่อให้ได้ ลำดับ.

สร้างลำดับ 2, 2, 5, 8, 6
ผลรวมของพวกเขาคือ 23 ดังนั้นจำนวนผลรวมของเราคือ 2/23, 2/23, 5/23, 8/23 และ 6/23
ลำดับสุดท้ายของเราคือ 2/23, 4/23, 9/23, 17/23, 23/23

สิ่งนี้สามารถขยายเป็น 2D ได้โดยการสร้างค่าเหล่านี้สำหรับทั้ง X และ Y คุณสามารถเพิ่ม N เพื่อรับความละเอียดที่คุณต้องการ


ในคำตอบที่คล้ายกันของ @ teodron คุณอ้างถึงความกังวลเกี่ยวกับประสิทธิภาพของเครื่องชั่งเวลาขนาดใหญ่ โดยไม่ทราบว่าปัญหาที่แท้จริงที่คุณเผชิญอยู่นั้นฉันไม่สามารถบอกได้ว่าข้อกังวลนั้นถูกต้องหรือไม่ แต่อีกทางเลือกหนึ่งคือการสร้างN ขนาดเล็กและผลลัพธ์จะราบรื่นขึ้น ขึ้นอยู่กับแอปพลิเคชันซึ่งอาจให้ผลลัพธ์ที่ดีกว่า

ป้อนคำอธิบายรูปภาพที่นี่
N = 100 ไม่มีการปรับให้เรียบ

ป้อนคำอธิบายรูปภาพที่นี่
N = 15 พร้อมการปรับให้เรียบ


ไม่ว่าคุณจะทำอะไรเพื่อความราบรื่นดูเหมือนว่าจะไม่ได้ผลแม้แต่ฟังก์ชั่น (ประมาณ x = 0.95) ฉันไม่แน่ใจว่าเป็นส่วนหนึ่งของโปรแกรมสร้างกราฟหรือเกิดข้อผิดพลาด ดูเหมือนว่าจะถูกละเมิดด้วยการพูดถึงเรื่องเดียวกันประมาณ 0.7 อย่างไรก็ตามฉันคุ้นเคยกับ "วิธีปกติ" - ฉันถามคำถามนี้เพราะฉันสงสัยว่าวิธีปกติคือเส็งเคร็ง Pre-Perlin-noise ท้ายที่สุดไม่มีใครมีปัญหากับ LUT ขนาดยักษ์ที่มีเสียงดังมันเป็นเพียง "วิธีปกติ" วันนี้เรามีวิธีที่ยืดหยุ่นและมีประสิทธิภาพมากขึ้น

3
ฉันเห็นด้วยกับ BlueRaja: มีวิธีการเรียบที่เป็นที่รู้จักและใช้งานง่ายในการปรับให้เรียบโดยไม่ละเมิดความซ้ำซากจำเจโดยไม่คำนึงถึงตัวอย่าง ตัวอย่างเช่นเส้นค่าเฉลี่ยเคลื่อนที่หรือเส้นโค้งการวาด อย่างไรก็ตาม @JoeWreschnig ข้อกังวลไม่เกี่ยวข้อง กฎและกลไกของเกมอาจขึ้นอยู่กับวัตถุที่ไม่เคยถอยกลับไปใช้ฟังก์ชั่น - มันเป็นความคิดที่ดีที่จะสมมติว่าสิ่งที่ผู้ถามไม่ต้องการจริงๆในสิ่งที่เขาบอกว่าเขาต้องการ
Superbest

1
@BlueRaja: การร้องเรียนขั้นพื้นฐานของฉันเกี่ยวกับวิธีการทีละน้อย ๆ แบบนี้อธิบายไว้ในคำตอบของฉันต่อ teodrone มันไม่เกี่ยวกับการค้นหา "ผลลัพธ์ที่แม่นยำและแม่นยำที่สุดในเชิงคณิตศาสตร์" - มันเกี่ยวกับการเปิดโอกาสใหม่ ๆ ด้วยเครื่องมือทางคณิตศาสตร์ที่เราไม่เคยรู้จักมาก่อน พิจารณาความคล้ายคลึงกันระหว่าง LUTs กับค่าเสียงยักษ์และเสียง Perlin อีกครั้ง ไม่ใช่คำถามทุกข้อในไซต์ที่ต้องการคำตอบที่ "ดีพอ" นอกคอก CS อันชาญฉลาดที่อยู่ครึ่งทางสามารถตอบโจทย์การบรรยายได้ - บางครั้งเรามาถ่ายทำสิ่งที่เป็นต้นฉบับและเป็นมืออาชีพใช่ไหม

1
หรือเราอาจปล่อยให้เว็บไซต์นี้หลงทางในความสับสนขั้นพื้นฐาน 90% เกี่ยวกับเมทริกซ์การแปลง 10% "ช่วยฉันหยุดเล่นเกม!" นั่นจะทำให้ไซต์ถามตอบที่ยอดเยี่ยมที่มืออาชีพทุกคนชื่นชอบ

2
@Joe: นั่นคือ erm ไม่ได้เรียกหา คุณขอวิธีการแก้ปัญหาให้เหมาะกับเกณฑ์ของคุณฉันให้คุณ เพียงเพราะว่ามันเรียบง่ายไม่ทำให้แย่
BlueRaja - Danny Pflughoeft

1

ฉันขอแนะนำการใช้งานนี้โดยได้รับแรงบันดาลใจจากผลรวมของอ็อคเทฟที่พบในเสียงเศษส่วนโดยมีการสับตูดราคาถูกที่นี่ 1/2^octaveผมเชื่อว่ามันเป็นเหตุผลได้อย่างรวดเร็วและสามารถปรับโดยขอเลอะเลือนน้อยกว่าเก็บไว้ในพารามิเตอร์ที่มีการสูญเสียของความแม่นยำประมาณ

คุณสามารถเห็นว่ามันเป็นการใช้งานทีละชิ้นซึ่งต้องใช้เวลาO (บันทึก (ชิ้นส่วน))เท่านั้น อาเรย์พารามิเตอร์ใช้สำหรับทั้งตำแหน่งเดือยและพิชิตและสำหรับระยะทางที่เดินทางเมื่อมาถึงเดือย

template<int N> struct Trajectory
{
    Trajectory(int seed = 0)
    {
        /* The behaviour can be tuned by changing 0.2 and 0.6 below. */
        if (seed)
            srand(seed);
        for (int i = 0; i < N; i++)
            m_params[i] = 0.2 + 0.6 * (double)(rand() % 4096) / 4096;
    }

    double Get(double t, int depth = N)
    {
        double min = 0.0, max = 1.0;
        for (int i = 0, dir = 0; i < N && i < depth; i++)
        {
            int j = (dir + 1 + i) % N;
            double mid = min + (max - min) * m_params[j];
            if (t < m_params[i])
            {
                dir += 1;
                t = t / m_params[i];
                max = mid;
            }
            else
            {
                dir ^= i;
                t = (t - m_params[i]) / (1.0 - m_params[i]);
                min = mid;
            }
        }
        t = (3.0 - 2.0 * t) * t * t; // Optional smoothing
        return min + (max - min) * t;
    }

    double m_params[N];
};

มันสามารถทำได้เร็วขึ้นโดยการคำนวณหน่วยคะแนนจุดลอยตัวล่วงหน้าโดยเสียค่าใช้จ่ายในการจัดเก็บข้อมูลมากถึงสามเท่า

นี่คือตัวอย่างด่วน:

ห้าวิถีที่แตกต่าง

ตัวอย่างได้มาพร้อมกับรหัสต่อไปนี้:

for (int run = 0; run < 5; run++)
{
    /* Create a new shuffled trajectory */
    Trajectory<12> traj;

    /* Print dots */
    for (double t = 0; t <= 1.0; t += 0.0001)
        printf("%g %g\n", t, traj.Get(t));
}

0

คิดออกมาดัง ๆ และการยอมรับแคลคูลัสไม่ใช่จุดแข็งของฉัน ... นี่อาจจะเป็นไปไม่ได้เหรอ? เพื่อหลีกเลี่ยงรูปแบบที่เห็นได้ชัดค่าเฉลี่ยของฟังก์ชั่นเสียงรบกวนในการเปลี่ยนแปลงใด ๆ ใน x จะต้องใกล้เคียงกับศูนย์และเพื่อรับประกันความน่าเชื่อถือของความกว้างของเสียงมากกว่าการเปลี่ยนแปลงใน x นั้นจะต้องเล็กกว่าการเปลี่ยนแปลงใน x ส่งผลให้ค่าที่ต่ำกว่าที่ x 'สัมพันธ์กับ x แต่นั่นหมายความว่าเมื่อคุณลด dx ไปที่ 0 ฟังก์ชันนี้จะต้องลด dA (โดยที่ A คือแอมพลิจูด) ไปยังศูนย์ซึ่งหมายความว่าคุณจะไม่ได้รับการสนับสนุนจากฟังก์ชั่นเสียงรบกวนใด ๆ

ฉันสามารถจินตนาการว่ามันเป็นไปได้ที่จะกำหนดฟังก์ชั่นที่ค่อย ๆ ลดการรบกวนทางเสียงเมื่อ x เข้าใกล้ 1 แต่นั่นจะทำให้คุณมีฟังก์ชั่นโค้งที่ชะลอตัวลงเมื่อ x เข้าใกล้ 1 ซึ่งไม่ใช่สิ่งที่ฉันคิดว่าคุณต้องการ


1
ฉันสามารถวาดกราฟจำนวนมากของฟังก์ชั่นดังกล่าวและในขณะที่ SkimFlux กล่าวว่าการรวมฟังก์ชั่นเสียงรบกวนให้ฟังก์ชั่นที่เทียบเท่าในทางปฏิบัติหากคุณทำให้เป็นมาตรฐาน ดังนั้นฟังก์ชั่นที่มีอยู่มันเป็นแค่เรื่องของการที่สามารถเข้ารหัสได้หรือไม่ ดังนั้นขอให้ที่นี่แทน math.se

ตัวอย่างเช่นฟังก์ชั่นใด ๆ ที่ชะลอตัวลงเมื่อ x เข้าใกล้ 1 มีฟังก์ชั่น "กลับด้าน" ที่เทียบเท่าg(x) = 1 - f(1 - x)ซึ่งแทนที่จะเร่งความเร็วเป็น x ออก 0

แน่นอนว่ามีฟังก์ชั่นอยู่ - คุณสามารถวาดรูปแบบหนึ่งเหมือนที่ Teodron ทำ แต่ฟังก์ชั่น 'เสียงรบกวน' หรือไม่? เสียงรบกวนหมายถึงฟังก์ชั่นต่อเนื่องตามอินพุตหลอกแบบสุ่มที่มีแอมพลิจูดโดยนัยเมื่อเทียบกับพื้นฐาน และถ้าแอมพลิจูดนั้นสูงเกินไปคุณจะไม่สามารถรับประกันความแตกต่างระหว่างขั้นตอนนั้นต่ำพอที่จะรักษาเอาท์พุทเสียงโมโนได้ แต่มันเกิดขึ้นกับฉันว่าความหนาแน่นของเสียงและขั้นตอนการแก้ไขอาจถูกสร้างขึ้นเพื่อตอบสนองความต้องการของคุณซึ่งฉันจะคิดอีกเล็กน้อย
Kylotan

เสียงรบกวนหมายความว่ามัน "คาดเดาไม่ได้" มันไม่ได้บอกอะไรเกี่ยวกับวิธีการสร้าง (หรือแม้กระทั่งในทางเทคนิคความต่อเนื่องแม้ว่าสำหรับอนิเมชั่นที่คุณมักจะต้องการเสียงที่ต่อเนื่องกัน) เป็นความจริงที่ว่าจุดปลายทางคงที่จะจำกัดความกว้างของคลื่นที่เป็นไปได้ของฟังก์ชั่นนี้ แต่ไม่ใช่ทั้งหมด ฟังก์ชั่นเสียงรบกวนอื่น ๆ มีคุณสมบัติที่คล้ายกันเช่น Perlin (x) = 0 สำหรับจำนวนเต็มใด ๆ x ความน่าเชื่อถือทางเดียวคือการรับประกันที่แข็งแกร่งกว่านั้น แต่ฉันไม่คิดว่ามันแข็งแกร่งกว่านี้มากจนทำให้เป็นไปไม่ได้

@JoeWreschnig ฉันแน่ใจว่าคุณทราบดีว่าฟังก์ชั่นเสียง Perlin นั้นละเมิดหลักเกณฑ์หลายข้อของคุณอย่างโจ่งแจ้ง ประการแรกมันผ่าน 0 ที่โหนดกริดดังนั้น f (x + d) -f (x) เป็นค่าคงที่หลายค่าของ d สำหรับบางอย่าง (เว้นระยะสม่ำเสมอ) x นอกจากนี้เนื่องจากเคล็ดลับการแคชที่ชาญฉลาดมันจะทำซ้ำสำหรับกริดขนาดใหญ่ สำหรับเสียงแบบคลาสสิกฉันคิดว่าการนำการอ้างอิงไปใช้ควรมีไทล์ไทล์ (x, y) เหมือนกับไทล์ (x + 256, y + 256) คุณควรระบุว่าสิ่งนี้เป็นที่ยอมรับและในระดับใด
Superbest
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.