@@ -35,38 +35,9 @@ void DrawInterlacing::drawGeometries(Gen::AxisId axisIndex) const
3535 || guides.interlacings == false )
3636 return ;
3737
38- std::map<double , double > othWeights{{0.0 , 0.0 }, {1.0 , 0.0 }};
39-
40- const auto &othGuides = parent.plot ->guides .at (!axisIndex);
41- const auto &othAxisStyle =
42- parent.rootStyle .plot .getAxis (!axisIndex);
43- if (!othAxisStyle.interlacing .color ->isTransparent ()
44- && othGuides.interlacings != false )
45- for (const auto &othInterval :
46- parent.getIntervals (!axisIndex)) {
47- if (Math::Floating::is_zero (othInterval.isSecond ))
48- continue ;
49- auto min = std::max (othInterval.range .getMin (), 0.0 );
50- auto max = std::min (othInterval.range .getMax (), 1.0 );
51- auto mprev = std::prev (othWeights.upper_bound (min));
52- auto mnext = othWeights.lower_bound (max);
53-
54- if (mprev->first < min)
55- mprev =
56- othWeights.try_emplace (mprev, min, mprev->second );
57- if (mnext->first > max)
58- mnext = othWeights.try_emplace (mnext,
59- max,
60- std::prev (mnext)->second );
61-
62- while (mprev != mnext)
63- mprev++->second +=
64- Math::FuzzyBool::And<double >(othInterval.weight ,
65- othInterval.isSecond ,
66- othGuides.interlacings );
67- }
68-
69- auto orientation = !Gen::orientation (axisIndex);
38+ auto otherWeights = getInterlacingWeights (!axisIndex);
39+ auto &&otherInterlacingColor =
40+ *parent.rootStyle .plot .getAxis (!axisIndex).interlacing .color ;
7041
7142 parent.painter .setPolygonToCircleFactor (0 );
7243 parent.painter .setPolygonStraightFactor (0 );
@@ -81,60 +52,39 @@ void DrawInterlacing::drawGeometries(Gen::AxisId axisIndex) const
8152 Math::Floating::less)
8253 - clippedBottom;
8354
84- auto rect = [&](const double &from, const double &to)
55+ auto rect = [&, orientation = orientation (axisIndex)](
56+ const double &from,
57+ const double &to)
8558 {
8659 return Geom::Rect{
87- Geom::Point::Coord (orientation, from, clippedBottom ),
60+ Geom::Point::Coord (orientation, clippedBottom, from ),
8861 {Geom::Size::Coord (orientation,
89- to - from ,
90- clippedSize )}};
62+ clippedSize ,
63+ to - from )}};
9164 };
9265
9366 auto weight = Math::FuzzyBool::And<double >(interval.weight ,
9467 interval.isSecond ,
9568 guides.interlacings );
9669 auto interlacingColor = *axisStyle.interlacing .color * weight;
9770
98- for (auto first = othWeights .begin (),
71+ for (auto first = otherWeights .begin (),
9972 next = std::next (first),
100- last = othWeights .end ();
73+ last = otherWeights .end ();
10174 next != last;
10275 ++next, ++first) {
10376 if (Math::Floating::is_zero (first->second ))
10477 drawInterlacing (axisIndex,
10578 interlacingColor,
10679 rect (first->first , next->first ));
10780 else if (axisIndex == Gen::AxisId::y) {
108- auto color =
109- interlacingColor
110- + *othAxisStyle.interlacing .color * first->second ;
111-
112- color.alpha =
113- 1
114- - (1
115- - axisStyle.interlacing .color ->alpha
116- * weight)
117- * (1
118- - othAxisStyle.interlacing .color ->alpha
119- * first->second );
120-
121- if (weight + first->second > 1.0 )
122- color = Math::Niebloid::interpolate (
123- color
124- * std::max ({std::abs (axisStyle.interlacing
125- .color ->red
126- - color.red ),
127- std::abs (
128- axisStyle.interlacing .color ->green
129- - color.green ),
130- std::abs (
131- axisStyle.interlacing .color ->blue
132- - color.blue )}),
133- color,
134- 2.0 - (weight + first->second ));
13581 drawInterlacing (first->second > weight ? !axisIndex
13682 : axisIndex,
137- color,
83+ getCrossingInterlacingColor (
84+ *axisStyle.interlacing .color ,
85+ weight,
86+ otherInterlacingColor,
87+ first->second ),
13888 rect (first->first , next->first ));
13989 }
14090 }
@@ -313,4 +263,61 @@ void DrawInterlacing::drawSticks(double tickLength,
313263 canvas.restore ();
314264}
315265
266+ std::map<double , double > DrawInterlacing::getInterlacingWeights (
267+ Gen::AxisId axisIndex) const
268+ {
269+ std::map<double , double > weights{{0.0 , 0.0 }, {1.0 , 0.0 }};
270+
271+ auto &&guides = parent.plot ->guides .at (axisIndex);
272+ auto &&axisStyle = parent.rootStyle .plot .getAxis (axisIndex);
273+ if (axisStyle.interlacing .color ->isTransparent ()
274+ || guides.interlacings == false )
275+ return weights;
276+
277+ for (auto &&interval : parent.getIntervals (axisIndex)) {
278+ if (Math::Floating::is_zero (interval.isSecond )) continue ;
279+ auto min = std::max (interval.range .getMin (), 0.0 );
280+ auto max = std::min (interval.range .getMax (), 1.0 );
281+ auto mprev = std::prev (weights.upper_bound (min));
282+ auto mnext = weights.lower_bound (max);
283+
284+ if (mprev->first < min)
285+ mprev = weights.try_emplace (mprev, min, mprev->second );
286+ if (mnext->first > max)
287+ mnext = weights.try_emplace (mnext,
288+ max,
289+ std::prev (mnext)->second );
290+
291+ while (mprev != mnext)
292+ mprev++->second +=
293+ Math::FuzzyBool::And<double >(interval.weight ,
294+ interval.isSecond ,
295+ guides.interlacings );
296+ }
297+ return weights;
298+ }
299+
300+ Gfx::Color DrawInterlacing::getCrossingInterlacingColor (
301+ const Gfx::Color &mainColor,
302+ double mainWeight,
303+ const Gfx::Color &otherColor,
304+ double otherWeight)
305+ {
306+ auto color = mainColor * mainWeight + otherColor * otherWeight;
307+
308+ color.alpha = 1
309+ - (1 - mainColor.alpha * mainWeight)
310+ * (1 - otherColor.alpha * otherWeight);
311+
312+ if (mainWeight + otherWeight > 1.0 )
313+ color = Math::Niebloid::interpolate (color,
314+ color
315+ * std::max ({std::abs (mainColor.red - otherColor.red ),
316+ std::abs (mainColor.green - otherColor.green ),
317+ std::abs (mainColor.blue - otherColor.blue )}),
318+ mainWeight + otherWeight - 1.0 );
319+
320+ return color;
321+ }
322+
316323}
0 commit comments