From 3bfb4dde2eeaebe4d0d65ff4a4dd68d50368f1d8 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 19 May 2025 21:56:26 +0800 Subject: [PATCH] feat: add quiz 3 cross-checker. --- CMakeLists.txt | 5 ++- README.md | 18 +++++++++ counter/include/counter.h | 1 + cross-checker/CMakeLists.txt | 11 +++++ cross-checker/include/cross-checker.h | 38 ++++++++++++++++++ cross-checker/main.cpp | 24 +++++++++++ cross-checker/src/cross-checker.cpp | 58 +++++++++++++++++++++++++++ cross-checker/tests/CMakeLists.txt | 10 +++++ cross-checker/tests/smoke-tests.cpp | 0 9 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 README.md create mode 100644 cross-checker/CMakeLists.txt create mode 100644 cross-checker/include/cross-checker.h create mode 100644 cross-checker/main.cpp create mode 100644 cross-checker/src/cross-checker.cpp create mode 100644 cross-checker/tests/CMakeLists.txt create mode 100644 cross-checker/tests/smoke-tests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a6e49c5..302f093 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,10 @@ cmake_minimum_required(VERSION 3.10) -project(plct_lab) +project(plct-lab) set(CMAKE_CXX_STANDARD 11) add_subdirectory(third-party/googletest-1.17.0) add_subdirectory(mixplus) -add_subdirectory(counter) \ No newline at end of file +add_subdirectory(counter) +add_subdirectory(cross-checker) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8cea02e --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# PLCT LAT TEST + +## Build + +```bash +make build +cd build +cmake .. +make +``` + +Three test will be in: + +- mixplus +- counter +- cross-checker + +There are unit-tests implemented by gtest. \ No newline at end of file diff --git a/counter/include/counter.h b/counter/include/counter.h index 6bac9b9..0053047 100644 --- a/counter/include/counter.h +++ b/counter/include/counter.h @@ -1,3 +1,4 @@ +#pragma once #include #include diff --git a/cross-checker/CMakeLists.txt b/cross-checker/CMakeLists.txt new file mode 100644 index 0000000..cf105e4 --- /dev/null +++ b/cross-checker/CMakeLists.txt @@ -0,0 +1,11 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC) + +add_library(libcross-checker STATIC ${SRC}) + +add_executable(cross-checker main.cpp) + +target_link_libraries(cross-checker libcross-checker) + +add_subdirectory(tests) diff --git a/cross-checker/include/cross-checker.h b/cross-checker/include/cross-checker.h new file mode 100644 index 0000000..9f2664d --- /dev/null +++ b/cross-checker/include/cross-checker.h @@ -0,0 +1,38 @@ +// +// Created by ricardo on 19/05/25. +// + +#ifndef CROSS_CHECKER_H +#define CROSS_CHECKER_H + +namespace cross_checker +{ + // 既可以表示点也可以表示一个向量 + struct Point + { + double x; + double y; + + Point(const double a, const double b) : x(a), y(b) + { + } + + static int orientation(const Point& p, const Point& q, const Point& r); + + static bool onSegment(const Point& p, const Point& q, const Point& r); + }; + + struct Line + { + Point startPoint; + Point endPoint; + + Line(const Point a, const Point b): startPoint(a), endPoint(b) + { + } + + bool intersect(const Line& other); + }; +} + +#endif //CROSS_CHECKER_H diff --git a/cross-checker/main.cpp b/cross-checker/main.cpp new file mode 100644 index 0000000..c8c6b19 --- /dev/null +++ b/cross-checker/main.cpp @@ -0,0 +1,24 @@ +#include +#include + +int main(int argc, char** argv) +{ + if (argc != 9) + { + std::cout << "ERROR: 4 point must be provided" << std::endl; + } + + cross_checker::Line line1(cross_checker::Point(std::stod(argv[1]), std::stod(argv[2])), cross_checker::Point( + std::stod(argv[3]), std::stod(argv[4]))); + cross_checker::Line line2(cross_checker::Point(std::stod(argv[5]), std::stod(argv[6])), cross_checker::Point( + std::stod(argv[7]), std::stod(argv[8]))); + + if (line1.intersect(line2)) + { + std::cout << "TRUE" << std::endl; + } + else + { + std::cout << "FALSE" << std::endl; + } +} diff --git a/cross-checker/src/cross-checker.cpp b/cross-checker/src/cross-checker.cpp new file mode 100644 index 0000000..7657656 --- /dev/null +++ b/cross-checker/src/cross-checker.cpp @@ -0,0 +1,58 @@ +#include +#include +#include "cross-checker.h" + + +// 计算向量叉积的方向 +// 返回值: +// 0 表示三点共线 +// 1 表示逆时针方向(正) +// -1 表示顺时针方向(负) +int cross_checker::Point::orientation(const Point& p, const Point& q, const Point& r) +{ + const double val = (q.x - p.x) * (r.y - p.y) - (r.x - p.x) * (q.y - p.y); + if (std::fabs(val) < 1e-9) return 0; // 共线 + return (val > 0) ? 1 : -1; +} + +bool cross_checker::Point::onSegment(const Point& p, const Point& q, const Point& r) +{ + return q.x <= std::max(p.x, r.x) && q.x >= std::min(p.x, r.x) && + q.y <= std::max(p.y, r.y) && q.y >= std::min(p.y, r.y); +} + +bool cross_checker::Line::intersect(const Line& other) +{ + const int o1 = Point::orientation(startPoint, endPoint, other.startPoint); + const int o2 = Point::orientation(startPoint, endPoint, other.endPoint); + const int o3 = Point::orientation(other.startPoint, other.endPoint, startPoint); + const int o4 = Point::orientation(other.startPoint, other.endPoint, endPoint); + + // 普通情况:跨立实验 + if (o1 != o2 && o3 != o4) + { + return true; + } + + // 特殊情况:共线 + if (o1 == 0 && Point::onSegment(startPoint, other.startPoint, endPoint)) + { + return true; + } + if (o2 == 0 && Point::onSegment(startPoint, other.endPoint, endPoint)) + { + return true; + } + if (o3 == 0 && Point::onSegment(other.startPoint, startPoint, other.endPoint)) + { + return true; + } + if (o4 == 0 && Point::onSegment(other.startPoint, endPoint, other.endPoint)) + { + return true; + } + + return false; +} + + diff --git a/cross-checker/tests/CMakeLists.txt b/cross-checker/tests/CMakeLists.txt new file mode 100644 index 0000000..2a6c194 --- /dev/null +++ b/cross-checker/tests/CMakeLists.txt @@ -0,0 +1,10 @@ +enable_testing() + +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} TEST_SRC) + +add_executable( + cross-checker-tests + ${TEST_SRC} +) + +target_link_libraries(cross-checker-tests GTest::gtest_main libcount) diff --git a/cross-checker/tests/smoke-tests.cpp b/cross-checker/tests/smoke-tests.cpp new file mode 100644 index 0000000..e69de29