/* * This file is part of libgim. * * libgim 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, either version 3 of the License, or (at your option) any later * version. * * libgim 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 libgim. If not, see . * * Copyright 2014-2015 Danny Robson */ #include "maths.hpp" #include namespace util { //------------------------------------------------------------------------- template template typename std::common_type::type util::point::distance (const point &rhs) const { return std::sqrt (distance2 (rhs)); } //------------------------------------------------------------------------- template template typename std::common_type::type util::point::distance2 (const point &rhs) const { typedef typename std::common_type::type result_t; result_t sum { 0 }; for (size_t i = 0; i < S; ++i) sum += pow2 (this->data[i] - rhs.data[i]); return sum; } //------------------------------------------------------------------------- template template typename std::common_type::type util::point::manhattan (const point &rhs) const { typedef typename std::common_type::type result_t; result_t sum { 0 }; for (size_t i = 0; i < S; ++i) sum += std::abs (this->data[i] - rhs.data[i]); return sum; } //------------------------------------------------------------------------- template template point point::redim (void) const { point out; std::copy_n (std::begin (this->data), min (S, D), std::begin (out.data)); return out; } //------------------------------------------------------------------------- template template point point::redim (const point &fill) const { point out; static constexpr auto L1 = min (S, D); static constexpr auto L2 = D - L1; std::copy_n (std::begin (this->data), L1, std::begin (out.data)); std::copy_n (fill.data + L1, L2, out.data + L1); return out; } //------------------------------------------------------------------------- template template point point::redim (T fill) const { point out; auto cursor = std::copy_n (std::begin (this->data), min (S, D), std::begin (out.data)); std::fill (cursor, std::end (out.data), fill); return out; } ///------------------------------------------------------------------------ /// expand point to use homogenous coordinates of a higher dimension. /// ie, fill with (0,..,0,1) template template point point::homog (void) const { static_assert (D > S, "homog will not overwrite data"); point out; // Copy the existing data auto c = std::copy (this->begin (), this->end (), out.begin ()); // Fill until the second last element with zeros auto f = std::fill_n (c, D - S - 1, T{0}); // Last element should be one *f = T{1}; return out; } //------------------------------------------------------------------------- template template point point::cast (void) const { point out; std::copy (std::begin (this->data), std::end (this->data), std::begin (out.data)); return out; } }