* filter/object_links_bottom_aligned.hh, * filter/object_links_center_aligned.hh, * filter/object_links_left_aligned.hh, * filter/object_links_non_aligned_simple.hh, * filter/object_links_right_aligned.hh, * filter/object_links_top_aligned.hh: Use anchor::Type.
* filter/internal/alignment_angle.hh, * filter/internal/component_aligned.hh: New. --- scribo/ChangeLog | 14 ++ scribo/filter/internal/alignment_angle.hh | 156 ++++++++++++++++++++++ scribo/filter/internal/component_aligned.hh | 114 ++++++++++++++++ scribo/filter/object_links_bottom_aligned.hh | 2 +- scribo/filter/object_links_center_aligned.hh | 2 +- scribo/filter/object_links_left_aligned.hh | 2 +- scribo/filter/object_links_non_aligned_simple.hh | 109 +-------------- scribo/filter/object_links_right_aligned.hh | 2 +- scribo/filter/object_links_top_aligned.hh | 2 +- 9 files changed, 297 insertions(+), 106 deletions(-) create mode 100644 scribo/filter/internal/alignment_angle.hh create mode 100644 scribo/filter/internal/component_aligned.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog index da11249..a9c13e3 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,19 @@ 2010-04-13 Guillaume Lazzara z@lrde.epita.fr
+ Use anchor::Type in alignment routines' dispatch. + + * filter/object_links_bottom_aligned.hh, + * filter/object_links_center_aligned.hh, + * filter/object_links_left_aligned.hh, + * filter/object_links_non_aligned_simple.hh, + * filter/object_links_right_aligned.hh, + * filter/object_links_top_aligned.hh: Use anchor::Type. + + * filter/internal/alignment_angle.hh, + * filter/internal/component_aligned.hh: New. + +2010-04-13 Guillaume Lazzara z@lrde.epita.fr + Small fixes related to object_groups.
* core/object_groups.hh: Add more preconditions. diff --git a/scribo/filter/internal/alignment_angle.hh b/scribo/filter/internal/alignment_angle.hh new file mode 100644 index 0000000..5b88012 --- /dev/null +++ b/scribo/filter/internal/alignment_angle.hh @@ -0,0 +1,156 @@ +// Copyright (C) 2010 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see http://www.gnu.org/licenses/. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_FILTER_INTERNAL_ALIGNMENT_ANGLE_HH +# define SCRIBO_FILTER_INTERNAL_ALIGNMENT_ANGLE_HH + +/// \file +/// +/// Return the alignment angle between two components according to an +/// anchor. + + +# include <mln/util/array.hh> +# include <mln/math/abs.hh> +# include <mln/math/pi.hh> + +# include <scribo/core/macros.hh> +# include <scribo/core/tag/anchor.hh> +# include <scribo/core/component_set.hh> + +namespace scribo +{ + + namespace filter + { + + namespace internal + { + + using namespace mln; + + + /// Return the alignment angle between two components according + /// to anchor. + /// + /// \return An angle in Radians. + template <typename L> + float + alignment_angle(const component_set<L>& comps, + unsigned current_object, unsigned nbh_object, + anchor::Type anchor); + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename L> + float + alignment_angle(const component_set<L>& comps, + unsigned current_object, unsigned nbh_object, + anchor::Type anchor) + { + trace::entering("scribo::filter::internal::alignment_angle_rad"); + + mln_precondition(comps.is_valid()); + + float dr, dc; + + if (nbh_object == current_object) + return 0; + + // Center + if (anchor == anchor::Center) + { + dr = math::abs(comps(current_object).bbox().pcenter().row() + - comps(nbh_object).bbox().pcenter().row()); + dc = math::abs(comps(current_object).bbox().pcenter().col() + - comps(nbh_object).bbox().pcenter().col()); + + return std::atan(dr / dc); + } + + // Top + else if (anchor == anchor::Top) + { + dr = math::abs(comps(current_object).bbox().pmin().row() + - comps(nbh_object).bbox().pmin().row()); + dc = math::abs(comps(current_object).bbox().pcenter().col() + - comps(nbh_object).bbox().pcenter().col()); + + return std::atan(dr / dc); + } + + // Bottom + else if (anchor == anchor::Bottom) + { + dr = math::abs(comps(current_object).bbox().pmax().row() + - comps(nbh_object).bbox().pmax().row()); + dc = math::abs(comps(current_object).bbox().pcenter().col() + - comps(nbh_object).bbox().pcenter().col()); + + return std::atan(dr / dc); + } + + // Left + else if (anchor == anchor::Left) + { + dr = math::abs(comps(current_object).bbox().pcenter().row() + - comps(nbh_object).bbox().pcenter().row()); + dc = math::abs(comps(current_object).bbox().pmin().col() + - comps(nbh_object).bbox().pmin().col()); + + return std::atan(dc / dr); + } + + // Right + else if (anchor == anchor::Right) + { + dr = math::abs(comps(current_object).bbox().pcenter().row() + - comps(nbh_object).bbox().pcenter().row()); + dc = math::abs(comps(current_object).bbox().pmax().col() + - comps(nbh_object).bbox().pmax().col()); + + return std::atan(dc / dr); + } + + else + trace::warning("Invalid anchor value... Aborting computation."); + + trace::exiting("scribo::filter::internal::alignment_angle_rad"); + return 0; + + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::filter::internal + + } // end of namespace scribo::filter + +} // end of namespace scribo + +#endif // SCRIBO_FILTER_INTERNAL_ALIGNMENT_ANGLE_HH diff --git a/scribo/filter/internal/component_aligned.hh b/scribo/filter/internal/component_aligned.hh new file mode 100644 index 0000000..7200d44 --- /dev/null +++ b/scribo/filter/internal/component_aligned.hh @@ -0,0 +1,114 @@ +// Copyright (C) 2010 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see http://www.gnu.org/licenses/. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_FILTER_INTERNAL_COMPONENT_ALIGNED_HH +# define SCRIBO_FILTER_INTERNAL_COMPONENT_ALIGNED_HH + +/// \file +/// +/// Invalidate components between two non aligned components. + + +# include <mln/util/array.hh> +# include <mln/math/abs.hh> +# include <mln/math/pi.hh> + +# include <scribo/core/macros.hh> +# include <scribo/core/tag/anchor.hh> +# include <scribo/core/component_set.hh> +# include <scribo/filter/internal/alignment_angle.hh> + +namespace scribo +{ + + namespace filter + { + + namespace internal + { + + using namespace mln; + + + template <typename L> + bool + component_aligned(const component_set<L>& comps, + unsigned current_object, unsigned nbh_object, + anchor::Type anchor, float max_alpha); + + + template <typename L> + bool + component_aligned_rad(const component_set<L>& comps, + unsigned current_object, unsigned nbh_object, + anchor::Type anchor, float max_alpha_rad); + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename L> + bool + component_aligned(const component_set<L>& comps, + unsigned current_object, unsigned nbh_object, + anchor::Type anchor, float max_alpha) + { + float max_alpha_rad = (max_alpha / 180.0f) * math::pi; + + return component_aligned(comps, current_object, anchor, max_alpha_rad); + } + + + + template <typename L> + bool + component_aligned_rad(const component_set<L>& comps, + unsigned current_object, unsigned nbh_object, + anchor::Type anchor, float max_alpha_rad) + { + trace::entering("scribo::filter::internal::component_aligned_rad"); + + mln_precondition(comps.is_valid()); + + float angle = alignment_angle(comps, current_object, + nbh_object, anchor); + + bool output = (angle <= max_alpha_rad); + + trace::exiting("scribo::filter::internal::component_aligned_rad"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::filter::internal + + } // end of namespace scribo::filter + +} // end of namespace scribo + + +#endif // ! SCRIBO_FILTER_INTERNAL_COMPONENT_ALIGNED_HH diff --git a/scribo/filter/object_links_bottom_aligned.hh b/scribo/filter/object_links_bottom_aligned.hh index f1816d4..ba8ff31 100644 --- a/scribo/filter/object_links_bottom_aligned.hh +++ b/scribo/filter/object_links_bottom_aligned.hh @@ -97,7 +97,7 @@ namespace scribo mln_precondition(links.is_valid());
object_links<L> - output = object_links_non_aligned_simple(links, 2, max_alpha); + output = object_links_non_aligned_simple(links, anchor::Bottom, max_alpha);
trace::exiting("scribo::filter::object_links_bottom_aligned"); return output; diff --git a/scribo/filter/object_links_center_aligned.hh b/scribo/filter/object_links_center_aligned.hh index abbac9e..8d89e73 100644 --- a/scribo/filter/object_links_center_aligned.hh +++ b/scribo/filter/object_links_center_aligned.hh @@ -95,7 +95,7 @@ namespace scribo
object_links<L> output = object_links_non_aligned_simple(objects, links, - 0, max_alpha); + anchor::Center, max_alpha);
trace::exiting("scribo::filter::object_links_center_aligned"); return output; diff --git a/scribo/filter/object_links_left_aligned.hh b/scribo/filter/object_links_left_aligned.hh index e69b110..a352d71 100644 --- a/scribo/filter/object_links_left_aligned.hh +++ b/scribo/filter/object_links_left_aligned.hh @@ -103,7 +103,7 @@ namespace scribo
object_links<L> output = object_links_non_aligned_simple(objects, links, - 3, + anchor::Left, max_alpha);
trace::exiting("scribo::filter::object_links_left_aligned"); diff --git a/scribo/filter/object_links_non_aligned_simple.hh b/scribo/filter/object_links_non_aligned_simple.hh index 5ecba0f..ae63527 100644 --- a/scribo/filter/object_links_non_aligned_simple.hh +++ b/scribo/filter/object_links_non_aligned_simple.hh @@ -38,6 +38,7 @@
# include <scribo/core/macros.hh> # include <scribo/core/object_links.hh> +# include <scribo/filter/internal/component_aligned.hh>
namespace scribo { @@ -48,13 +49,13 @@ namespace scribo using namespace mln;
/*! \brief Invalidate links between two non aligned components. - Alignment is based on a given edge of object bounding boxes. + Alignment is based on a given anchor of object bounding boxes.
\param[in] links Object links information. \param[in] max_alpha Maximum angle value (degrees).
- Exemple with dim == 1 and edge == 1 (bottom + Exemple with dim == 1 and anchor == 1 (bottom horizontal filter):
\verbatim @@ -79,18 +80,11 @@ namespace scribo
The angle between the two bottoms must be lower than \p alpha.
- edge values : - 0 = center - 1 = top - 2 = bottom - 3 = left - 4 = right - */ template <typename L> object_links<L> object_links_non_aligned_simple(const object_links<L>& links, - unsigned edge, + anchor::Type anchor, float max_alpha);
@@ -100,7 +94,7 @@ namespace scribo template <typename L> object_links<L> object_links_non_aligned_simple(const object_links<L>& links, - unsigned edge, + anchor::Type anchor, float max_alpha) { trace::entering("scribo::filter::object_links_non_aligned_simple"); @@ -111,100 +105,13 @@ namespace scribo const component_set<L>& comps = links.components();
object_links<L> output(links); - float dr, dc;
float max_alpha_rad = (max_alpha / 180.0f) * math::pi;
- // Center - if (edge == 0) - { - for_all_comps(i, comps) - { - if (links(i) != i) - { - dr = math::abs(comps(i).bbox().pcenter().row() - - comps(links(i)).bbox().pcenter().row()); - dc = math::abs(comps(i).bbox().pcenter().col() - - comps(links(i)).bbox().pcenter().col()); - - if (std::atan(dr / dc) > max_alpha_rad) - output(i) = i; - } - } - } - // Top - else if (edge == 1) - { - for_all_comps(i, comps) - if (links(i) != i) - { - dr = math::abs(comps(i).bbox().pmin().row() - - comps(links(i)).bbox().pmin().row()); - dc = math::abs(comps(i).bbox().pcenter().col() - - comps(links(i)).bbox().pcenter().col()); - - if (std::atan(dr / dc) > max_alpha_rad) - output(i) = i; - } - } - // Bottom - else if (edge == 2) - { - for_all_comps(i, comps) - { - if (links(i) != i) - { - dr = math::abs(comps(i).bbox().pmax().row() - - comps(links(i)).bbox().pmax().row()); - dc = math::abs(comps(i).bbox().pcenter().col() - - comps(links(i)).bbox().pcenter().col()); - - if (std::atan(dr / dc) > max_alpha_rad) - output(i) = i; - } - } - } - // Left - else if (edge == 3) - { - for_all_comps(i, comps) - { - if (links(i) != i) - { - dr = math::abs(comps(i).bbox().pcenter().row() - - comps(links(i)).bbox().pcenter().row()); - dc = math::abs(comps(i).bbox().pmin().col() - - comps(links(i)).bbox().pmin().col()); - - if (std::atan(dc / dr) > max_alpha_rad) - output(i) = i; - } - } - } - // Right - else if (edge == 4) - { - for_all_comps(i, comps) - { - if (links(i) != i) - { - dr = math::abs(comps(i).bbox().pcenter().row() - - comps(links(i)).bbox().pcenter().row()); - dc = math::abs(comps(i).bbox().pmax().col() - - comps(links(i)).bbox().pmax().col()); - - if (std::atan(dc / dr) > max_alpha_rad) - output(i) = i; - } - } - } - else - { - trace::warning("Invalid edge value... Aborting computation."); - trace::exiting("scribo::filter::object_links_non_aligned_simple"); - return output; - } + for_all_comps(i, comps) + if (!internal::component_aligned_rad(comps, i, links(i), anchor, max_alpha_rad)) + output(i) = i;
trace::exiting("scribo::filter::object_links_non_aligned_simple"); diff --git a/scribo/filter/object_links_right_aligned.hh b/scribo/filter/object_links_right_aligned.hh index 2ee0280..ee964a3 100644 --- a/scribo/filter/object_links_right_aligned.hh +++ b/scribo/filter/object_links_right_aligned.hh @@ -102,7 +102,7 @@ namespace scribo
object_links<L> output = object_links_non_aligned_simple(objects, links, - 4, + anchor::Right, max_alpha);
trace::exiting("scribo::filter::object_links_right_aligned"); diff --git a/scribo/filter/object_links_top_aligned.hh b/scribo/filter/object_links_top_aligned.hh index de5ab3b..57e8d40 100644 --- a/scribo/filter/object_links_top_aligned.hh +++ b/scribo/filter/object_links_top_aligned.hh @@ -96,7 +96,7 @@ namespace scribo mln_precondition(links.is_valid());
object_links<L> - output = object_links_non_aligned_simple(links, 1, max_alpha); + output = object_links_non_aligned_simple(links, anchor::Top, max_alpha);
trace::exiting("scribo::filter::object_links_top_aligned"); return output;