feat: add quiz 3 cross-checker.

This commit is contained in:
jackfiled 2025-05-19 21:56:26 +08:00
parent a4624b477f
commit 3bfb4dde2e
9 changed files with 163 additions and 2 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(plct_lab) project(plct-lab)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
@ -7,3 +7,4 @@ add_subdirectory(third-party/googletest-1.17.0)
add_subdirectory(mixplus) add_subdirectory(mixplus)
add_subdirectory(counter) add_subdirectory(counter)
add_subdirectory(cross-checker)

18
README.md Normal file
View File

@ -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.

View File

@ -1,3 +1,4 @@
#pragma once
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>

View File

@ -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)

View File

@ -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

24
cross-checker/main.cpp Normal file
View File

@ -0,0 +1,24 @@
#include <cross-checker.h>
#include <iostream>
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;
}
}

View File

@ -0,0 +1,58 @@
#include <cmath>
#include <algorithm>
#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;
}

View File

@ -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)

View File