From 56a73275c1f13bfc16e5ca9e32ed988674d0ec5b Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Fri, 20 Apr 2018 15:04:54 +1000 Subject: [PATCH] geom/line: add basic line class --- CMakeLists.txt | 4 +++ geom/line.cpp | 0 geom/line.hpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++ test/geom/line.cpp | 28 +++++++++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 geom/line.cpp create mode 100644 geom/line.hpp create mode 100644 test/geom/line.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8abd6090..e597cd9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,6 +233,8 @@ list ( geom/frustum.hpp geom/iostream.cpp geom/iostream.hpp + geom/line.hpp + geom/line.cpp geom/ops.hpp geom/plane.cpp geom/plane.hpp @@ -496,6 +498,8 @@ if (TESTS) geom/aabb geom/ellipse geom/frustum + geom/line + geom/plane geom/ray geom/sphere hash/checksum diff --git a/geom/line.cpp b/geom/line.cpp new file mode 100644 index 00000000..e69de29b diff --git a/geom/line.hpp b/geom/line.hpp new file mode 100644 index 00000000..267a424e --- /dev/null +++ b/geom/line.hpp @@ -0,0 +1,63 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2018 Danny Robson + */ + +#pragma once + +#include "../point.hpp" +#include "../vector.hpp" + +namespace util::geom { + // an line of infinite extent that passes though 'base'. + // + // direction should be normalised + template + struct line { + line () = default; + line (util::point a, util::point b): + line (a, normalised (b - a)) + { ; } + + line (util::point _base, util::vector _direction): + base (_base), + direction (_direction) + { + CHECK (is_normalised (direction)); + } + + util::point base; + util::vector direction; + }; + + using line2f = line<2,float>; + using line3f = line<3,float>; + + + template + T + distance2 (line l, point p) + { + const auto t = dot (p - l.base, l.direction); + return distance2 (p, l.base + l.direction * t); + } + + + template + T + distance (line l, point p) + { + return std::sqrt (distance2 (l, p)); + } +}; diff --git a/test/geom/line.cpp b/test/geom/line.cpp new file mode 100644 index 00000000..9be94787 --- /dev/null +++ b/test/geom/line.cpp @@ -0,0 +1,28 @@ +#include "tap.hpp" + +#include "geom/line.hpp" + +int +main (int, char**) +{ + util::TAP::logger tap; + + static struct { + util::point3f origin; + util::vector3f direction; + util::point3f q; + float distance; + const char *message; + } TESTS[] = { + { { 0, 0, 0 }, { 1, 0, 0}, { 0, 0, 0 }, 0, "origin line, origin point" } , + { { 0, 1, 0 }, { 1, 0, 0}, { 0, 0, 0 }, 1, "+x line, unit distance" }, + }; + + for (auto const& t: TESTS) { + util::geom::line3f l { t.origin, t.direction }; + auto d = distance2 (l, t.q); + tap.expect_eq (d, t.distance, "%!", t.message); + } + + return tap.status (); +} \ No newline at end of file