diff --git a/color/frgba.go b/color/frgba.go index 3db7455..f6dc87e 100644 --- a/color/frgba.go +++ b/color/frgba.go @@ -71,5 +71,5 @@ func (c FRGBA) Scale(v float64) FRGBA { // IsBlack returns true if the color is black. func (c FRGBA) IsBlack() bool { - return c.R < 0.0001 && c.G < 0.0001 && c.B < 0.0001 + return c.A < 0.0001 || (c.R < 0.0001 && c.G < 0.0001 && c.B < 0.0001) } diff --git a/fractal.go b/fractal.go index 1badd61..3733aa9 100644 --- a/fractal.go +++ b/fractal.go @@ -21,6 +21,7 @@ type Fractal struct { // NewFractal returns a new Fractal instance. func NewFractal(src Field, xfm *g2d.Aff3, comb OctaveCombiner, octaves float64) *Fractal { oct := int(octaves) + oct++ w := make([]float64, oct) for i := 0; i < oct; i++ { w[i] = 1 diff --git a/shape.go b/shape.go index b71b16b..9ef7028 100644 --- a/shape.go +++ b/shape.go @@ -124,7 +124,7 @@ type ShapeCombinerVF struct { Shape *graphics2d.Shape } -func NewShapeCombinerVF(src1, src2 ColorField, shape *graphics2d.Shape) *ShapeCombinerVF { +func NewShapeCombinerVF(src1, src2 VectorField, shape *graphics2d.Shape) *ShapeCombinerVF { return &ShapeCombinerVF{"ShapeCombinerVF", src1, src2, shape} } diff --git a/value.go b/value.go index 723f8e3..5308840 100644 --- a/value.go +++ b/value.go @@ -73,12 +73,13 @@ func (d *Direction) Eval2(x, y float64) float64 { // Magnitude converts a VectorField to a Field based on the vector's magnitude. type Magnitude struct { - Name string - Src VectorField + Name string + Src VectorField + Scale float64 } -func NewMagnitude(src VectorField) *Magnitude { - return &Magnitude{"Magnitude", src} +func NewMagnitude(src VectorField, scale float64) *Magnitude { + return &Magnitude{"Magnitude", src, scale} } // Eval2 implements the Field interface. Always >= 0 @@ -88,24 +89,26 @@ func (m *Magnitude) Eval2(x, y float64) float64 { for _, f := range v { s += f * f } - return math.Sqrt(s) + r := math.Sqrt(s) * m.Scale + return clamp(r) } // Select converts a VectorField to a field by selecting one of its components. type Select struct { - Name string - Src VectorField - Chan int + Name string + Src VectorField + Chan int + Scale float64 } -func NewSelect(src VectorField, ch int) *Select { - return &Select{"Select", src, ch} +func NewSelect(src VectorField, ch int, scale float64) *Select { + return &Select{"Select", src, ch, scale} } // Eval2 implements the Field interface. func (s *Select) Eval2(x, y float64) float64 { - v := s.Src.Eval2(x, y)[s.Chan] - return v + v := s.Src.Eval2(x, y)[s.Chan] * s.Scale + return clamp(v) } // Weighted converts a VectorField to a field by selecting one of its components. @@ -130,5 +133,5 @@ func (w *Weighted) Eval2(x, y float64) float64 { for i := 0; i < n; i++ { s += v[i] * w.Weights[i] } - return s + return clamp(s) }