feat: add quiz 3 cross-checker.
This commit is contained in:
parent
a4624b477f
commit
3bfb4dde2e
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
project(plct_lab)
|
||||
project(plct-lab)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
|
@ -7,3 +7,4 @@ add_subdirectory(third-party/googletest-1.17.0)
|
|||
|
||||
add_subdirectory(mixplus)
|
||||
add_subdirectory(counter)
|
||||
add_subdirectory(cross-checker)
|
18
README.md
Normal file
18
README.md
Normal 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.
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
|
|
11
cross-checker/CMakeLists.txt
Normal file
11
cross-checker/CMakeLists.txt
Normal 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)
|
38
cross-checker/include/cross-checker.h
Normal file
38
cross-checker/include/cross-checker.h
Normal 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
24
cross-checker/main.cpp
Normal 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;
|
||||
}
|
||||
}
|
58
cross-checker/src/cross-checker.cpp
Normal file
58
cross-checker/src/cross-checker.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
10
cross-checker/tests/CMakeLists.txt
Normal file
10
cross-checker/tests/CMakeLists.txt
Normal 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)
|
0
cross-checker/tests/smoke-tests.cpp
Normal file
0
cross-checker/tests/smoke-tests.cpp
Normal file
Loading…
Reference in New Issue
Block a user