@@ -34,39 +34,9 @@ void DrawInterlacing::drawGeometries(Gen::AxisId axisIndex) const
3434 || guides.interlacings == false )
3535 return ;
3636
37- std::map<double , double > otherWeights{{0.0 , 0.0 }, {1.0 , 0.0 }};
38-
39- const auto &otherGuides = parent.plot ->guides .at (!axisIndex);
40- const auto &otherAxisStyle =
41- parent.rootStyle .plot .getAxis (!axisIndex);
42- if (!otherAxisStyle.interlacing .color ->isTransparent ()
43- && otherGuides.interlacings != false )
44- for (const auto &otherInterval :
45- parent.getIntervals (!axisIndex)) {
46- if (Math::Floating::is_zero (otherInterval.isSecond ))
47- continue ;
48- auto min = std::max (otherInterval.range .getMin (), 0.0 );
49- auto max = std::min (otherInterval.range .getMax (), 1.0 );
50- auto mprev = std::prev (otherWeights.upper_bound (min));
51- auto mnext = otherWeights.lower_bound (max);
52-
53- if (mprev->first < min)
54- mprev = otherWeights.try_emplace (mprev,
55- min,
56- mprev->second );
57- if (mnext->first > max)
58- mnext = otherWeights.try_emplace (mnext,
59- max,
60- std::prev (mnext)->second );
61-
62- while (mprev != mnext)
63- mprev++->second +=
64- Math::FuzzyBool::And<double >(otherInterval.weight ,
65- otherInterval.isSecond ,
66- otherGuides.interlacings );
67- }
68-
69- auto orientation = !+axisIndex;
37+ auto otherWeights = getInterlacingWeights (!axisIndex);
38+ auto &&otherInterlacingColor =
39+ *parent.rootStyle .plot .getAxis (!axisIndex).interlacing .color ;
7040
7141 parent.painter .setPolygonToCircleFactor (0 );
7242 parent.painter .setPolygonStraightFactor (0 );
@@ -81,13 +51,14 @@ void DrawInterlacing::drawGeometries(Gen::AxisId axisIndex) const
8151 Math::Floating::less)
8252 - clippedBottom;
8353
84- auto rect = [&](const double &from, const double &to)
54+ auto rect = [&, orientation = +axisIndex](const double &from,
55+ const double &to)
8556 {
8657 return Geom::Rect{
87- Geom::Point::Coord (orientation, from, clippedBottom ),
58+ Geom::Point::Coord (orientation, clippedBottom, from ),
8859 {Geom::Size::Coord (orientation,
89- to - from ,
90- clippedSize )}};
60+ clippedSize ,
61+ to - from )}};
9162 };
9263
9364 auto weight = Math::FuzzyBool::And<double >(interval.weight ,
@@ -105,36 +76,13 @@ void DrawInterlacing::drawGeometries(Gen::AxisId axisIndex) const
10576 interlacingColor,
10677 rect (first->first , next->first ));
10778 else if (axisIndex == Gen::AxisId::y) {
108- auto color = interlacingColor
109- + *otherAxisStyle.interlacing .color
110- * first->second ;
111-
112- color.alpha = 1
113- - (1
114- - axisStyle.interlacing .color ->alpha
115- * weight)
116- * (1
117- - otherAxisStyle.interlacing
118- .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 ));
13579 drawInterlacing (first->second > weight ? !axisIndex
13680 : axisIndex,
137- color,
81+ getCrossingInterlacingColor (
82+ *axisStyle.interlacing .color ,
83+ weight,
84+ otherInterlacingColor,
85+ first->second ),
13886 rect (first->first , next->first ));
13987 }
14088 }
@@ -312,4 +260,61 @@ void DrawInterlacing::drawSticks(double tickLength,
312260 canvas.restore ();
313261}
314262
263+ std::map<double , double > DrawInterlacing::getInterlacingWeights (
264+ Gen::AxisId axisIndex) const
265+ {
266+ std::map<double , double > weights{{0.0 , 0.0 }, {1.0 , 0.0 }};
267+
268+ auto &&guides = parent.plot ->guides .at (axisIndex);
269+ auto &&axisStyle = parent.rootStyle .plot .getAxis (axisIndex);
270+ if (axisStyle.interlacing .color ->isTransparent ()
271+ || guides.interlacings == false )
272+ return weights;
273+
274+ for (auto &&interval : parent.getIntervals (axisIndex)) {
275+ if (Math::Floating::is_zero (interval.isSecond )) continue ;
276+ auto min = std::max (interval.range .getMin (), 0.0 );
277+ auto max = std::min (interval.range .getMax (), 1.0 );
278+ auto mprev = std::prev (weights.upper_bound (min));
279+ auto mnext = weights.lower_bound (max);
280+
281+ if (mprev->first < min)
282+ mprev = weights.try_emplace (mprev, min, mprev->second );
283+ if (mnext->first > max)
284+ mnext = weights.try_emplace (mnext,
285+ max,
286+ std::prev (mnext)->second );
287+
288+ while (mprev != mnext)
289+ mprev++->second +=
290+ Math::FuzzyBool::And<double >(interval.weight ,
291+ interval.isSecond ,
292+ guides.interlacings );
293+ }
294+ return weights;
295+ }
296+
297+ Gfx::Color DrawInterlacing::getCrossingInterlacingColor (
298+ const Gfx::Color &mainColor,
299+ double mainWeight,
300+ const Gfx::Color &otherColor,
301+ double otherWeight)
302+ {
303+ auto color = mainColor * mainWeight + otherColor * otherWeight;
304+
305+ color.alpha = 1
306+ - (1 - mainColor.alpha * mainWeight)
307+ * (1 - otherColor.alpha * otherWeight);
308+
309+ if (mainWeight + otherWeight > 1.0 )
310+ color = Math::Niebloid::interpolate (color,
311+ color
312+ * std::max ({std::abs (mainColor.red - otherColor.red ),
313+ std::abs (mainColor.green - otherColor.green ),
314+ std::abs (mainColor.blue - otherColor.blue )}),
315+ mainWeight + otherWeight - 1.0 );
316+
317+ return color;
318+ }
319+
315320}
0 commit comments