Overhaul zoom and rotation, modify parameter details

pull/321/head
Anthony Hall 2025-09-09 17:51:31 -07:00
rodzic 00fbb4f1d7
commit 473708a427
1 zmienionych plików z 32 dodań i 20 usunięć

Wyświetl plik

@ -5,10 +5,11 @@ class SpiralBitCrushEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<double>> &values, double sampleRate) override {
// Completing one revolution in input space traverses the hypotenuse of one "domain" in log-polar space
double effectScale = juce::jlimit(0.0, 1.0, values[0].load());
double domainX = juce::jmax(2.0, std::floor(values[1].load() + 0.0001));
double effectScale = juce::jlimit(0.0, 1.0, values[0].load());
double domainX = juce::jmax(2.0, std::floor(values[1].load() + 0.001));
double domainY = std::round(domainX * values[2].load());
osci::Point offset(values[3].load(), values[4].load());
double zoom = values[3].load() * juce::MathConstants<double>::twoPi; // Use same scale as angle
double rotation = values[4].load() * juce::MathConstants<double>::twoPi;
double domainHypot = std::hypot(domainX, domainY);
double domainTheta = std::atan2(domainY, domainX);
@ -22,17 +23,17 @@ public:
double r = std::hypot(input.x, input.y);
double logR = std::log(r);
double theta = std::atan2(input.x, -input.y);
osci::Point logPolarCoords(theta, logR);
osci::Point logPolarCoords(theta - rotation, logR - zoom);
logPolarCoords.rotate(0, 0, domainTheta);
logPolarCoords = logPolarCoords * scale - offset;
logPolarCoords = logPolarCoords * scale;
// Round this point to the center of the log-polar cell the input lies in, convert back to Cartesian
logPolarCoords.x = std::round(logPolarCoords.x);
logPolarCoords.y = std::round(logPolarCoords.y);
logPolarCoords = (logPolarCoords + offset) / scale;
logPolarCoords = logPolarCoords / scale;
logPolarCoords.rotate(0, 0, -domainTheta);
double outR = std::exp(logPolarCoords.y);
double outTheta = logPolarCoords.x;
double outR = std::exp(logPolarCoords.y + zoom);
double outTheta = logPolarCoords.x + rotation;
output.x = outR * std::sin(outTheta);
output.y = outR * -std::cos(outTheta);
}
@ -42,24 +43,35 @@ public:
if (input.z != 0) {
double signZ = input.z > 0 ? 1.0 : -1.0;
double logZ = std::log(std::abs(input.z));
logZ = logZ * scale - offset.y;
logZ = (logZ - zoom) * scale;
logZ = std::round(logZ);
logZ = (logZ + offset.y) / scale;
logZ = logZ / scale + zoom;
output.z = signZ * std::exp(logZ);
}
return (1 - effectScale) * input + effectScale * output;
}
std::shared_ptr<osci::Effect> build() const override {
auto eff = std::make_shared<osci::Effect>(
std::make_shared<SpiralBitCrushEffect>(),
std::vector<osci::EffectParameter*>{
new osci::EffectParameter("Spiral Bit Crush", "Constrains points to a spiral pattern.", "spiralBitCrushEnable", VERSION_HINT, 1.0, 0.0, 1.0),
new osci::EffectParameter("Spiral Density", "Controls the density of the spiral pattern.", "spiralDensity", VERSION_HINT, 13.0, 3.0, 30.0),
new osci::EffectParameter("Spiral Twist", "Controls how much the spiral pattern twists.", "spiralTwist", VERSION_HINT, -0.6, -1.0, 1.0),
new osci::EffectParameter("Angle Offset", "Rotates the spiral pattern.", "spiralOffsetX", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.4),
new osci::EffectParameter("Radial Offset", "Zooms the spiral pattern.", "spiralOffsetY", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 1.0)
});
auto eff = std::make_shared<osci::Effect>(
std::make_shared<SpiralBitCrushEffect>(),
std::vector<osci::EffectParameter*>{
new osci::EffectParameter("Spiral Bit Crush",
"Constrains points to a spiral pattern.",
"spiralBitCrush", VERSION_HINT, 1.0, 0.0, 1.0),
new osci::EffectParameter("Spiral Density",
"Controls the density of the spiral pattern.",
"spiralBitCrushDensity", VERSION_HINT, 13.0, 3.0, 30.0, 1.0),
new osci::EffectParameter("Spiral Twist",
"Controls how much the spiral pattern twists.",
"spiralBitCrushTwist", VERSION_HINT, 0.6, -1.0, 1.0),
new osci::EffectParameter("Zoom",
"Zooms the spiral pattern.",
"spiralBitCrushZoom", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.05),
new osci::EffectParameter("Rotation",
"Rotates the spiral pattern.",
"spiralBitCrushRotation", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001, osci::LfoType::ReverseSawtooth, 0.02)
}
);
eff->setIcon(BinaryData::swirl_svg);
return eff;
}