From 11ee5ce333eb3f485bc14238cce23d041490fbf1 Mon Sep 17 00:00:00 2001 From: dags- Date: Tue, 12 May 2020 17:15:09 +0100 Subject: [PATCH] - fix domain warp - added SCurve & Freq modules - improvements to Line module - clean-up of Noise/NoiseUtil --- src/main/java/me/dags/noise/Module.java | 9 ++++ .../me/dags/noise/domain/DirectionWarp.java | 2 +- src/main/java/me/dags/noise/func/SCurve.java | 19 ++++++++ .../java/me/dags/noise/modifier/Freq.java | 27 ++++++++++++ src/main/java/me/dags/noise/source/Line.java | 44 ++++++++++++++++++- src/main/java/me/dags/noise/util/Noise.java | 2 +- .../java/me/dags/noise/util/NoiseUtil.java | 33 ++++++++++++++ 7 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/dags/noise/func/SCurve.java create mode 100644 src/main/java/me/dags/noise/modifier/Freq.java diff --git a/src/main/java/me/dags/noise/Module.java b/src/main/java/me/dags/noise/Module.java index 50c8f69..60d8186 100644 --- a/src/main/java/me/dags/noise/Module.java +++ b/src/main/java/me/dags/noise/Module.java @@ -41,6 +41,7 @@ import me.dags.noise.modifier.Cache; import me.dags.noise.modifier.Clamp; import me.dags.noise.modifier.Curve; +import me.dags.noise.modifier.Freq; import me.dags.noise.modifier.Grad; import me.dags.noise.modifier.Invert; import me.dags.noise.modifier.Map; @@ -303,6 +304,14 @@ public float apply(float value) { }); } + default Module freq(double x, double y) { + return freq(Source.constant(x), Source.constant(y)); + } + + default Module freq(Module x, Module y) { + return new Freq(this, x, y); + } + /** * Applies a custom Curve function to the output of this Module * diff --git a/src/main/java/me/dags/noise/domain/DirectionWarp.java b/src/main/java/me/dags/noise/domain/DirectionWarp.java index 35fccdf..34aaf30 100644 --- a/src/main/java/me/dags/noise/domain/DirectionWarp.java +++ b/src/main/java/me/dags/noise/domain/DirectionWarp.java @@ -57,7 +57,7 @@ private DirectionWarp update(float x, float y) { if (this.x != x || this.y != y) { this.x = x; this.y = y; - float angle = direction.getValue(x, y) * 2 * NoiseUtil.PI2; + float angle = direction.getValue(x, y) * NoiseUtil.PI2; ox = NoiseUtil.sin(angle) * strength.getValue(x, y); oy = NoiseUtil.cos(angle) * strength.getValue(x, y); } diff --git a/src/main/java/me/dags/noise/func/SCurve.java b/src/main/java/me/dags/noise/func/SCurve.java new file mode 100644 index 0000000..9bd9837 --- /dev/null +++ b/src/main/java/me/dags/noise/func/SCurve.java @@ -0,0 +1,19 @@ +package me.dags.noise.func; + +import me.dags.noise.util.NoiseUtil; + +public class SCurve implements CurveFunc { + + private final float lower; + private final float upper; + + public SCurve(float lower, float upper) { + this.lower = lower; + this.upper = upper < 0 ? Math.max(-lower, upper) : upper; + } + + @Override + public float apply(float value) { + return NoiseUtil.pow(value, lower + (upper * value)); + } +} diff --git a/src/main/java/me/dags/noise/modifier/Freq.java b/src/main/java/me/dags/noise/modifier/Freq.java new file mode 100644 index 0000000..311c541 --- /dev/null +++ b/src/main/java/me/dags/noise/modifier/Freq.java @@ -0,0 +1,27 @@ +package me.dags.noise.modifier; + +import me.dags.noise.Module; + +public class Freq extends Modifier { + + private final Module x; + private final Module y; + + public Freq(Module source, Module x, Module y) { + super(source); + this.x = x; + this.y = y; + } + + @Override + public float getValue(float x, float y) { + float fx = this.x.getValue(x, y); + float fy = this.y.getValue(x, y); + return source.getValue(x * fx, y * fy); + } + + @Override + public float modify(float x, float y, float noiseValue) { + return 0; + } +} diff --git a/src/main/java/me/dags/noise/source/Line.java b/src/main/java/me/dags/noise/source/Line.java index 270b358..83f8afa 100644 --- a/src/main/java/me/dags/noise/source/Line.java +++ b/src/main/java/me/dags/noise/source/Line.java @@ -73,8 +73,12 @@ public float getValue(float x, float y) { } public float getValue(float x, float y, float widthModifier) { + return getValue(x, y, 0, widthModifier); + } + + public float getValue(float x, float y, float minWidth2, float widthModifier) { float dist2 = getDistance2(x, y); - float radius2 = radius.getValue(x, y) * widthModifier; + float radius2 = minWidth2 + radius.getValue(x, y) * widthModifier; if (dist2 > radius2) { return 0; } @@ -154,4 +158,42 @@ public static int sign(float x, float y, float x1, float y1, float x2, float y2) } return 1; } + + public static boolean intersect(float ax1, float ay1, float ax2, float ay2, float bx1, float by1, float bx2, float by2) { + return ((relativeCCW(ax1, ay1, ax2, ay2, bx1, by1) * relativeCCW(ax1, ay1, ax2, ay2, bx2, by2) <= 0) + && (relativeCCW(bx1, by1, bx2, by2, ax1, ay1) * relativeCCW(bx1, by1, bx2, by2, ax2, ay2) <= 0)); + } + + private static int relativeCCW(float x1, float y1, float x2, float y2, float px, float py) { + x2 -= x1; + y2 -= y1; + px -= x1; + py -= y1; + double ccw = px * y2 - py * x2; + if (ccw == 0F) { + // The point is colinear, classify based on which side of + // the segment the point falls on. We can calculate a + // relative value using the projection of px,py onto the + // segment - a negative value indicates the point projects + // outside of the segment in the direction of the particular + // endpoint used as the origin for the projection. + ccw = px * x2 + py * y2; + if (ccw > 0.0) { + // Reverse the projection to be relative to the original x2,y2 + // x2 and y2 are simply negated. + // px and py need to have (x2 - x1) or (y2 - y1) subtracted + // from them (based on the original values) + // Since we really want to get a positive answer when the + // point is "beyond (x2,y2)", then we want to calculate + // the inverse anyway - thus we leave x2 & y2 negated. + px -= x2; + py -= y2; + ccw = px * x2 + py * y2; + if (ccw < 0.0) { + ccw = 0.0; + } + } + } + return (ccw < 0F) ? -1 : ((ccw > 0F) ? 1 : 0); + } } diff --git a/src/main/java/me/dags/noise/util/Noise.java b/src/main/java/me/dags/noise/util/Noise.java index d832aa1..9d47b01 100644 --- a/src/main/java/me/dags/noise/util/Noise.java +++ b/src/main/java/me/dags/noise/util/Noise.java @@ -188,7 +188,7 @@ public static float cellEdge(float x, float y, int seed, EdgeFunc edgeFunc, Dist } else { distance2 = Math.max(distance, distance2); } -// distance2 = Math.max(Math.min(distance2, newDistance), distance); + distance = Math.min(distance, newDistance); } } diff --git a/src/main/java/me/dags/noise/util/NoiseUtil.java b/src/main/java/me/dags/noise/util/NoiseUtil.java index 4679f4d..df3176f 100644 --- a/src/main/java/me/dags/noise/util/NoiseUtil.java +++ b/src/main/java/me/dags/noise/util/NoiseUtil.java @@ -194,6 +194,39 @@ public static float exp(float x) { return x; } + public static float copySign(float value, float sign) { + if (sign < 0 && value > 0) { + return -value; + } + if (sign > 0 && value < 0) { + return -value; + } + return value; + } + + public static float pow(float value, int power) { + if (power == 0) { + return 1; + } + if (power == 1) { + return value; + } + if (power == 2) { + return value * value; + } + if (power == 3) { + return value * value * value; + } + if (power == 4) { + return value * value * value * value; + } + float result = 1; + for (int i = 0; i < power; i++) { + result *= value; + } + return result; + } + public static int hash(int x, int y) { int hash = x; hash ^= Y_PRIME * y;