001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009 010package imagingbook.common.noise.perlin; 011 012import imagingbook.common.noise.hashing.HashFunction; 013 014/** 015 * <p> 016 * This class implements a 1-dimensional Perlin noise [1] generator. See Ch. 8 of [2] for details. 017 * </p> 018 * <p> 019 * [1] K. Perlin. Improving noise. In "SIGGRAPH’02: Proceedings of the 29th Annual Conference on Computer Graphics and 020 * Interactive Techniques", pp. 681–682, San Antonio, Texas (2002).<br> [2] W. Burger and M.J. Burge. "Principles of 021 * Digital Image Processing - Advanced Methods" (Vol. 3). Undergraduate Topics in Computer Science. Springer-Verlag, 022 * London (2013). 023 * </p> 024 * 025 * @author WB 026 * @version 2022/11/24 027 */ 028public class PerlinNoiseGenerator1d extends PerlinNoiseGenerator { 029 030 /** 031 * Constructor. 032 * @param f_min minimum frequency 033 * @param f_max maximum frequency 034 * @param persistence persistence 035 * @param hf hash function 036 */ 037 public PerlinNoiseGenerator1d(double f_min, double f_max, double persistence, HashFunction hf) { 038 super(f_min, f_max, persistence, hf); 039 } 040 041 /** 042 * 1D combined (multi-frequency) Perlin noise function. Returns the value of the combined Perlin noise function for 043 * the one-dimensional position x. 044 * 045 * @param x interpolation position 046 * @return the multi-frequency noise value for position x 047 */ 048 public double getNoiseValue(double x) { 049 double sum = 0; 050 for (int i = 0; i < F.length; i++) { 051 sum = sum + A[i] * noise(F[i] * x); 052 } 053 return sum; 054 } 055 056 /** 057 * 1D elementary (single-frequency) Perlin noise function. 058 * 059 * @param x Interpolation position. 060 * @return The value of the elementary Perlin noise function for the one-dimensional position x. 061 */ 062 private double noise(double x) { 063 int p0 = ffloor(x); 064 double g0 = gradient(p0); 065 double g1 = gradient(p0 + 1); 066 double x01 = x - p0; 067 double w0 = g0 * x01; 068 double w1 = g1 * (x01 - 1); 069 return interpolate(x01, w0, w1); 070 } 071 072 /** 073 * @param p discrete position. 074 * @return A pseudo-random gradient value for the discrete position p. 075 */ 076 private double gradient(int p) { 077 return 2.0 * hashFun.hash(p) - 1; 078 } 079 080 /** 081 * Local interpolation function. 082 * @param x01 The interpolation position in [0,1] 083 * @param w0 Tangent value for x=0. 084 * @param w1 Tangent value for x=1. 085 * @return The interpolated noise value at position x01. 086 */ 087 private double interpolate(double x01, double w0, double w1) { // local interpolation function (x01 is in [0,1]) 088 double s = this.s(x01); 089 return (1 - s) * w0 + s * w1; 090 } 091}