Skip to content

Commit 12cdabf

Browse files
committed
small assorted
1 parent 26075dc commit 12cdabf

File tree

4 files changed

+82
-48
lines changed

4 files changed

+82
-48
lines changed

README.md

Lines changed: 74 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1+
[![](https://jitpack.io/v/micycle1/PeasyGradients.svg)](https://jitpack.io/#micycle1/PeasyGradients)
2+
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=micycle1_PeasyGradients&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=micycle1_PeasyGradients)
3+
14
<h1 align="center">
25
<a href="https://github.com/micycle1/PeasyGradients">
36
<img src="resources/logo/Banner-2.png" alt="PeasyGradients"/></a>
47
</h1>
58

6-
[![](https://jitpack.io/v/micycle1/PeasyGradients.svg)](https://jitpack.io/#micycle1/PeasyGradients)
7-
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=micycle1_PeasyGradients&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=micycle1_PeasyGradients)
8-
9-
109
# PeasyGradients
1110
A Processing library for creating and rendering color gradients.
1211

@@ -94,56 +93,92 @@ _Zoom and rotation can be adjusted for most gradient types; certain gradient typ
9493
_For many of the gradient types, there are multiple methods available to call, offering varying degrees of customisation of the gradient's spectrum shape._
9594

9695

97-
## Interpolation: Easing Functions
98-
In the parts of a `Gradient` between color stops, colors are composed via interpolating the neighbouring two color stops. Easing functions affect how these two adjacent stops contribute to the color of each point between them.
96+
## Color Interpolation
9997

100-
For example, with *linear* interpolation, a point in a `Gradient` which is midway between 2 color stops is composed of 50% of the first color and 50% of the second color — there is a linear relationship between its position and the weighting of color it receives from each color stop. Other easing functions are non-linear (for example a point closer to one color stop may in some cases receive more color from the second color stop) which can result in more interesting gradients.
101-
102-
Certain easing functions suit some gradient types better than others — for example, the `BOUNCE` function works well with polygon gradients but rather more poorly with linear gradients. Therefore, and as with color spaces, experimentation with different interpolation functions is encouraged.
98+
In 1D gradients, colors between stops are calculated by interpolating between adjacent stop colors. The interpolation/easing function controls how colors blend:
10399

104-
Set the interpolation (easing) function for a given `Gradient` with `.setInterpolationMode()`, like so:
100+
- **Linear**: Colors blend evenly based on position (50% position = 50% of each color)
101+
- **Non-linear**: Colors blend with varying weights, creating more dynamic transitions
105102

103+
```java
104+
// Set interpolation mode
105+
gradient.setInterpolationMode(Interpolation.SMOOTH_STEP);
106106
```
107-
myGradient.setInterpolationMode(Interpolation.SMOOTH_STEP);
108-
```
109-
110-
See for a comparison of all available easing functions modes in expandable section below:
111-
112-
| **Linear**![](resources/interpolation_examples/linear.png ) | **Identity**![](resources/interpolation_examples/identity.png) | **Smooth Step**![](resources/interpolation_examples/smooth_step.png ) | **Smoother Step**![](resources/interpolation_examples/smoother_step.png) |
113-
|:---:|:---:|:---:|:---:|
114-
| **Exponential**![](resources/interpolation_examples/exponential.png ) | **Cubic**![](resources/interpolation_examples/cubic.png) | **Circular**![](resources/interpolation_examples/circular.png ) | **Bounce**![](resources/interpolation_examples/bounce.png) |
115-
| **Sine**![](resources/interpolation_examples/sine.png ) | **Parabola**![](resources/interpolation_examples/parabola.png) | **Gain 1**![](resources/interpolation_examples/gain1.png ) | **Gain 2**![](resources/interpolation_examples/gain2.png) |
116-
| **Exponential Impulse**![](resources/interpolation_examples/expimpulse.png ) | **Heartbeat**![](resources/interpolation_examples/heartbeat.png ) | | |
117-
118-
<details><summary style="font-size:135%; color:blue">💥See Interpolation Comparison...</summary>
119107

120-
| **Linear**![](resources/interpolation_examples/linear.png ) | **Identity**![](resources/interpolation_examples/identity.png) |
121-
|:---:|:--:|
122-
| **Smooth Step**![](resources/interpolation_examples/smooth_step.png ) | **Smoother Step**![](resources/interpolation_examples/smoother_step.png) |
123-
| **Exponential**![](resources/interpolation_examples/exponential.png ) | **Cubic**![](resources/interpolation_examples/cubic.png) |
124-
| **Circular**![](resources/interpolation_examples/circular.png ) | **Bounce**![](resources/interpolation_examples/bounce.png) |
125-
| **Sine**![](resources/interpolation_examples/sine.png ) | **Parabola**![](resources/interpolation_examples/parabola.png) |
126-
| **Gain 1**![](resources/interpolation_examples/gain1.png ) | **Gain 2**![](resources/interpolation_examples/gain2.png) |
127-
| **Exponential Impulse**![](resources/interpolation_examples/expimpulse.png ) | **Heartbeat**![](resources/interpolation_examples/heartbeat.png )
108+
Different interpolation modes suit different rendering patterns. For example, `BOUNCE` works well with polygon gradients but can appear jarring in linear gradients. Experiment with different modes to achieve desired effects.
109+
110+
Here's a comparison between all available interpolation modes:
111+
112+
<table>
113+
<tr>
114+
<td align="center" valign="center"><b>Linear</b></td>
115+
<td align="center" valign="center"><b>Identity</b></td>
116+
<td align="center" valign="center"><b>Smooth Step</b></td>
117+
<td align="center" valign="center"><b>Smoother Step</b></td>
118+
</tr>
119+
<tr>
120+
<td valign="top" width="25%"><img src="resources/interpolation_examples/linear.png"></td>
121+
<td valign="top" width="25%"><img src="resources/interpolation_examples/identity.png"></td>
122+
<td valign="top" width="25%"><img src="resources/interpolation_examples/smooth_step.png"></td>
123+
<td valign="top" width="25%"><img src="resources/interpolation_examples/smoother_step.png"></td>
124+
</tr>
125+
<tr>
126+
<td align="center" valign="center"><b>Exponential</b></td>
127+
<td align="center" valign="center"><b>Cubic</b></td>
128+
<td align="center" valign="center"><b>Circular</b></td>
129+
<td align="center" valign="center"><b>Bounce</b></td>
130+
</tr>
131+
<tr>
132+
<td valign="top" width="25%"><img src="resources/interpolation_examples/exponential.png"></td>
133+
<td valign="top" width="25%"><img src="resources/interpolation_examples/cubic.png"></td>
134+
<td valign="top" width="25%"><img src="resources/interpolation_examples/circular.png"></td>
135+
<td valign="top" width="25%"><img src="resources/interpolation_examples/bounce.png"></td>
136+
</tr>
137+
<tr>
138+
<td align="center" valign="center"><b>Sine</b></td>
139+
<td align="center" valign="center"><b>Parabola</b></td>
140+
<td align="center" valign="center"><b>Gain 1</b></td>
141+
<td align="center" valign="center"><b>Gain 2</b></td>
142+
</tr>
143+
<tr>
144+
<td valign="top" width="25%"><img src="resources/interpolation_examples/sine.png"></td>
145+
<td valign="top" width="25%"><img src="resources/interpolation_examples/parabola.png"></td>
146+
<td valign="top" width="25%"><img src="resources/interpolation_examples/gain1.png"></td>
147+
<td valign="top" width="25%"><img src="resources/interpolation_examples/gain2.png"></td>
148+
</tr>
149+
<tr>
150+
<td align="center" valign="center"><b>Exponential Impulse</b></td>
151+
<td align="center" valign="center"><b>Heartbeat</b></td>
152+
<td align="center" valign="center"></td>
153+
<td align="center" valign="center"></td>
154+
</tr>
155+
<tr>
156+
<td valign="top" width="25%"><img src="resources/interpolation_examples/expimpulse.png"></td>
157+
<td valign="top" width="25%"><img src="resources/interpolation_examples/heartbeat.png"></td>
158+
<td valign="top" width="25%"></td>
159+
<td valign="top" width="25%"></td>
160+
</tr>
161+
</table>
128162

129163
</details>
130164

131165
## Color Spaces
132166

133-
Color spaces define how the color value at each color stop is represented.
167+
Color space determines how colors are numerically represented, and this affects how colors blend during interpolation. Different color spaces can produce noticeably different gradients even with the same color stops.
134168

135-
Remember that a 1D `Gradient` consists of only a few defined color stops; all other colors in a `Gradient`'s spectrum are **composed** by **interpolating** between any two adjacent color stops. Representing color stops differently (in different color spaces) affects the results of interpolation, and this can have a noticeable effect on the overall spectrum of a gradient (so experimentation with different color spaces is encouraged). A rule of thumb: avoid the `RGB`, `RYB` and `HSB` color spaces as they don't interpolate luminosity well.
169+
<b> main comparison is perceptually uniform vs not!</b>
170+
ideally uniform hue perception and
136171

172+
A smooth transition using a model designed to mimic human perception of color. The blending is done so that the perceived brightness and color varies smoothly and evenly.
137173

138-
Set the color space for a given `Gradient` with `.setColorSpace()`, like so:
139-
140-
```
141-
myGradient.setColorSpace(ColorSpace.RGB);
142-
```
143174

144-
PeasyGradients supports many different color spaces — all possible color spaces are accessible via `ColorSpace.class` and examples of each are shown in the expandable section below:
175+
```java
176+
gradient.setColorSpace(ColorSpace.LAB); // Perceptually uniform blending
177+
```
178+
179+
For smooth, perceptually uniform gradients, prefer spaces like `OKLAB`, `ITP`, or `K_MUNK` over `RGB`, `RYB`, or `HSB`. This is because the latter don't maintain consistent perceived brightness during interpolation.
145180

146-
<details><summary style="font-size:135%; color:blue">💥See Color Space Comparison...</summary>
181+
All available spaces are accessible via `ColorSpace.class` and demonstration of each are shown in the expandable section below:
147182

148183
*Note that with the chosen gradient, the spectrum differences aren't too apparent between many of the colorspaces in the images below. Other gradients (i.e. using different colors) may exhibit more substantial differences between the different colorspaces.*
149184

src/main/micycle/peasygradients/gradient/Palette.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77

88
/**
99
* Provides methods for generating color palettes based on various color harmony
10-
* principles, employing the HSB color space and producing colors as sRGB
11-
* integers. The palettes can be used for creating gradients and other
10+
* principles The palettes can be used for creating gradients and other
1211
* color-related visual elements.
1312
*
1413
* @author Michael Carleton
@@ -28,7 +27,7 @@ public final class Palette {
2827
private static final float bMin = 0.75f; // min brightness
2928
private static final float sVarMax = 0.1f; // max saturation variance
3029
private static final float bVarMax = 0.1f; // max brightness variance
31-
private static final float GRC = 0.618033988749895f; // Golden ratio conjugate for hue distribution
30+
private static final double GRC = (Math.sqrt(5) + 1) / 2 - 1; // Golden ratio conjugate for hue distribution
3231

3332
/**
3433
* https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
@@ -88,7 +87,7 @@ public static int[] randomcolors(int ncolors) {
8887
public static int[] randomRandomcolors(int ncolors) {
8988
int[] out = new int[ncolors];
9089
for (int i = 0; i < ncolors; i++) {
91-
out[i] = -Functions.randomInt(0, 2 << 24);
90+
out[i] = (255 << 24) | -Functions.randomInt(0, 2 << 24);
9291
}
9392
return out;
9493
}
@@ -102,17 +101,17 @@ public static int[] randomRandomcolors(int ncolors) {
102101
* @param increment The hue increment between consecutive colors.
103102
* @return An array of colors, represented as ARGB integers.
104103
*/
105-
private static int[] generic(int colors, float increment) {
104+
private static int[] generic(int colors, double increment) {
106105
int[] out = new int[colors];
107106
float h = Functions.randomFloat(); // 0...1
108107
float s = Functions.random(sMin, 1);
109108
float b = Functions.random(bMin, 1);
110109

111110
for (int i = 0; i < colors; i++) {
112-
113111
double[] HSB = new double[] { h, PApplet.constrain(s + Functions.random(-sVarMax, sVarMax), sMin, 1),
114112
PApplet.constrain(b + Functions.random(-bVarMax, bVarMax), bMin, 1) };
115-
out[i] = ColorUtils.RGB1ToRGB255(ColorSpace.HSB.getColorSpace().toRGB(HSB));
113+
int color = ColorUtils.RGB1ToRGB255(ColorSpace.HSB.getColorSpace().toRGB(HSB));
114+
out[i] = color;
116115
h += increment;
117116
h %= 1;
118117
}

src/main/micycle/peasygradients/utilities/Functions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ public static double fastSin(double z) {
319319
* @return
320320
*/
321321
public static double fastAtan(double z) {
322-
return z * (QRTR_PI_F + 0.273f * (1 - Math.abs(z)));
322+
return z * (QRTR_PI_F + 0.273f * (1 - Math.abs(z))); // NOTE _F
323323
}
324324

325325
/**

src/test/micycle/peasygradients/colorspace/GradientTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void testMidPointMatch() {
3939
}
4040

4141
@ParameterizedTest
42-
@EnumSource(value = ColorSpace.class, mode = Mode.EXCLUDE, names = { "JAB", "IPT" }) // NOTE exlude failing
42+
@EnumSource(value = ColorSpace.class, mode = Mode.EXCLUDE, names = { "JAB", "IPT", "IPTo" }) // NOTE exlude failing
4343
void testBiGradientIsMonotonic(ColorSpace colorSpace) {
4444
Gradient gradient = new Gradient(WHITE, BLACK);
4545
gradient.setInterpolationMode(Interpolation.LINEAR);

0 commit comments

Comments
 (0)