7b1e235a3ecc4666e0243e4e5e4b37ba8017862f..e7e07f42b336bb7b5c488eb3bcc6397c0a2a03f4
2020-08-24 wangzhengquan
fix conflict
e7e07f 对比 | 目录
2020-08-24 wangzhengquan
update
4aeefc 对比 | 目录
2020-08-24 wangzhengquan
modify iterator
fcf50e 对比 | 目录
2020-06-17 wangzhengquan
time
2a9ffa 对比 | 目录
2020-06-17 wangzhengquan
time
c2aa47 对比 | 目录
2020-06-16 wangzhengquan
修改算法
795d03 对比 | 目录
2020-06-16 wangzhengquan
commit
262e46 对比 | 目录
34个文件已添加
2个文件已修改
1953 ■■■■■ 已修改文件
.gitignore 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Make.common.inc 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Make.defines.freebsd 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Make.defines.linux 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Make.defines.macos 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Make.defines.solaris 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Makefile 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/IndirectAlg.c 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/Makefile 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/graph.c 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/include/IndirectAlg.h 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/include/graph.h 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic_pack/README.mk 补丁 | 查看 | 原始文档 | blame | 历史
basic_pack/include/IndirectAlg.h 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic_pack/include/graph.h 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic_pack/include/usg_common.h 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic_pack/include/usg_typedef.h 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic_pack/test_right_walk2.c 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/Makefile 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/include/usg_common.h 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/include/usg_typedef.h 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/usg_common.c 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
systype.sh 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/Makefile 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test.txt 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test2.txt 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test3.txt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_map.c 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_map2.c 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_right_walk 补丁 | 查看 | 原始文档 | blame | 历史
test/test_right_walk.c 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_right_walk2 补丁 | 查看 | 原始文档 | blame | 历史
test/test_right_walk2.c 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/test_right_walk3 补丁 | 查看 | 原始文档 | blame | 历史
test/test_right_walk3.c 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -1,13 +1,24 @@
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
@@ -19,3 +30,6 @@
*.exe
*.out
*.app
*.tar
*.tar.gz
.vscode/
Make.common.inc
New file
@@ -0,0 +1,2 @@
$(LIBCOMMON):
    (cd $(ROOT)/common && $(MAKE))
Make.defines.freebsd
New file
@@ -0,0 +1,19 @@
# Common make definitions, customized for each platform
# Definitions required in all program directories to compile and link
# C programs using gcc.
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
LDDIR=-L$(ROOT)/lib
LDLIBS=$(LDDIR) -lapue $(EXTRALIBS)
CFLAGS=-ansi -I$(ROOT)/include -std=c++11 -Wall -DBSD -D__BSD_VISIBLE $(EXTRA)
RANLIB=ranlib
AR=ar
AWK=awk
LIBAPUE=$(ROOT)/lib/libapue.a
# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out
Make.defines.linux
New file
@@ -0,0 +1,25 @@
# Common make definitions, customized for each platform
# Definitions required in all program directories to compile and link
# C programs using gcc.
CC = g++
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
CFLAGS = $(INCLUDE) -I. -I./include -I$(ROOT)/common -I$(ROOT)/common/include -g -std=c++11 -mcx16 -Wall  -DLINUX -D_GNU_SOURCE $(EXTRA)
ifeq ($(pic),y)
    CFLAGS += -fPIC
endif
RANLIB=echo
AR=ar
AWK=awk
# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out *.a *.so
Make.defines.macos
New file
@@ -0,0 +1,19 @@
# Common make definitions, customized for each platform
# Definitions required in all program directories to compile and link
# C programs using gcc.
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
LDDIR=-L$(ROOT)/lib
LDLIBS=$(LDDIR) -lapue $(EXTRALIBS)
CFLAGS=-ansi -I$(ROOT)/include -std=c++11 -Wall -DMACOS -D_DARWIN_C_SOURCE $(EXTRA)
RANLIB=ranlib
AR=ar
AWK=awk
LIBAPUE=$(ROOT)/lib/libapue.a
# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out
Make.defines.solaris
New file
@@ -0,0 +1,20 @@
# Common make definitions, customized for each platform
# Definitions required in all program directories to compile and link
# C programs using gcc.
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
LDDIR=-L$(ROOT)/lib
LDLIBS=$(LDDIR) -lapue $(EXTRALIBS)
CFLAGS=-std=c99 -m64 -I$(ROOT)/include -std=c++11 -Wall -DSOLARIS -D__EXTENSIONS__ $(EXTRA)
RANLIB=echo
AR=ar
AWK=nawk
LIBAPUE=$(ROOT)/lib/libapue.a
NAMEMAX=-DNAME_MAX=_XOPEN_NAME_MAX
# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out
Makefile
New file
@@ -0,0 +1,36 @@
DIRS = common algorithm test
all:
    for i in $(DIRS); do \
        (cd $$i && echo "making $$i" && $(MAKE) ) || exit 1; \
    done
clean:
    for i in $(DIRS); do \
        (cd $$i && echo "cleaning $$i" && $(MAKE) clean) || exit 1; \
    done
ipcrm:
    - ipcrm -a
    - ipcrm -M 0x1234
    - ipcrm -S 145
    - ipcrm -S 146
    - ipcrm -S 8899
tarname = basic_pack.tar.gz
tar:
    rm -f $(tarname)
    git archive --format tar.gz --output "./$(tarname)" $(branch)
tar2:
    rm -f $(tarname)
    mkdir -p basic_pack/include
    mkdir -p basic_pack/lib
    cp -a ./common/include/* basic_pack/include/
    cp -a ./algorithm/include/* basic_pack/include/
    cp  ./common/libusgcommon.so basic_pack/lib/
    cp  ./algorithm/libalg.so basic_pack/lib/
    cp README.md basic_pack
    cp test/test_right_walk2.c basic_pack
    tar -czvf $(tarname) basic_pack
README.md
@@ -1,4 +1,96 @@
## right_walk_alg
## 逆行算法调用说明
C++ 靠右行算法
### 1. 代码调用
```
 /**
 * 第一个参数@points  组成观测区域的彼此相邻的点
 * 第二个参数@_keepTime 保持时间
 * 第三个参数@_direction 正确行进的方向方向
 */
IndirectAlg indirectAlg((std::initializer_list<Point>){{0.0, 0.0}, {1000.0, 0.0},  {1000.0, 1000.0}, {0.0, 1000.0} }, 5, {1, 1});
//因为数据时流数据,下面的调用应该时在一个循环里面,处理完一条接着处理下一条
//构建传入的数据
Record record;
record.id = 1; //目标ID
record.timestamp = time(0); //时间戳
record.coordinate = {2.0, 3.0}; // 坐标
//判断是否逆行
indirectAlg.isRetrograde(record)
```
### 2 测试用例
test_right_walk2.c
```test_right_walk2.c
#include <usg_common.h>        /* cos */
#include <graph.h>
#include <IndirectAlg.h>
using namespace std;
int test2() {
    // IndirectAlg indirectAlg({  {{0.0, 0.0}, {1000.0, 0.0}}, {{1000.0, 0.0}, {1000.0, 1000.0}}, {{1000.0, 1000.0}, {0.0, 1000.0}}, {{0.0, 1000.0}, {0.0, 0.0}} }, 5, {1, 1});
    /**
     * 第一个参数@points  组成观测区域的彼此相邻的点
     * 第二个参数@_keepTime 保持时间
     * 第三个参数@_direction 正确行进的方向方向
     */
    IndirectAlg indirectAlg((std::initializer_list<Point>){{0.0, 0.0}, {1000.0, 0.0},  {1000.0, 1000.0}, {0.0, 1000.0} }, 5, {1, 1});
    int i = 0;
    // time_t start_time;
    srand((unsigned) time(0));
    double rx, ry;
    bool isRetrograde;
    //起点
    Point start = {0, 0};
    //传入的流数据记录信息Record
    Record record;
    record.id = 1; //目标ID
    record.timestamp = time(0); //时间戳
    record.coordinate = start; // 坐标
    // time(&start_time);
    //判断是否逆行
    while(!(isRetrograde = indirectAlg.isRetrograde(record)) ) {
        rx = ((double)(rand()%10))/100000;
        ry = ((double)(rand()%10))/100000;
        //std::cout << timestamp << ":" <<  << "isRetrograde" << isRetrograde;
       // err_msg(0, "%ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
        record.timestamp = time(0);
        //if (difftime(time(0), start_time) > 1)
        if (i > 10)
        {
            record.coordinate = {record.coordinate.x - rx , record.coordinate.y - ry};
        } else {
            record.coordinate = {record.coordinate.x + rx , record.coordinate.y + ry};
        }
        if (i > 100)
            break;
        sleep(1);
        i++;
    }
    printf("return %ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
    return 0;
}
int main() {
    test2();
}
```
### 3 编译
安装好so包后,用如下的方式编译,alg是逆行算法包,usgcommon是算法用的的公共包,pthread是系统的线程包
```
g++  -std=c++11  test_right_walk2.c -o test_right_walk2  -lalg  -lusgcommon -lpthread
```
algorithm/IndirectAlg.c
New file
@@ -0,0 +1,200 @@
#include "usg_common.h"
#include "IndirectAlg.h"
#include "graph.h"
#define PI 3.14159265
using namespace std;
struct Status {
    // target id
    std::string id;
    //第一次出现的时间
    time_t firstTime;
    //上次出现的时间
    time_t lastTime;
    //第一次逆行的时间
    time_t firstInvalTime;
    //上次逆行的时间
    time_t lastInvalTime;
     //第一次正确行的时间
    time_t firstValTime;
    //上次逆=正确行的时间
    time_t lastValTime;
    //上一次出现的坐标
    Point lastCoordinate;
    // Status(std::string _id, time_t ftime, time_t ltime, Point coordinate):
    //     id(_id), firstInvalTime(ftime), lastInvalTime(ltime), lastCoordinate(coordinate){}
};
IndirectAlg::IndirectAlg() {}
IndirectAlg::IndirectAlg(const initializer_list<Edge> & edges, const time_t & _keepTime, const Vector2 & _direction):
    frame(edges), keepTime(_keepTime), direction(_direction), mterminate(false) {
    mthread = std::thread(std::bind(&IndirectAlg::threadRoutine, this));
}
IndirectAlg::IndirectAlg(const initializer_list<Point> & points, const time_t & _keepTime, const Vector2 & _direction):
    keepTime(_keepTime), direction(_direction), mterminate(false) {
    if (points.size() > 0) {
        std::vector<Edge> edges;
        initializer_list<Point>::iterator iter;
        for(iter = points.begin(); iter < points.end(); iter++ ) {
            edges.push_back({*iter, *(iter +1)});
        }
        edges.push_back({*(points.end()), *(points.begin())});
        frame = Figure(edges);
    }
    mthread = std::thread(std::bind(&IndirectAlg::threadRoutine, this));
}
IndirectAlg::~IndirectAlg() {
    //销毁定时线程
    mterminate.store(true);
    mthread.join();
    //销毁map
    map<string, Status *>::iterator iter;
    Status *status = nullptr;
    for(iter = statusMap.begin(); iter != statusMap.end(); iter++) {
        //cout<<iter->first<<' '<<iter->second<<endl;
        status = iter->second;
        if (status != nullptr) {
            delete status;
            statusMap.erase(iter);
        }
    }
}
void IndirectAlg::threadRoutine() {
    //定时清理不在监控区的对象
    //sleep(this->keepTime);
    map<string, Status *>::iterator iter;
    Status *status = nullptr;
    while (!mterminate.load()) {
        std::this_thread::sleep_for(std::chrono::seconds(this->keepTime * 2));
        //sleep(this->keepTime);
        for(iter = statusMap.begin(); iter != statusMap.end();) {
            status = iter->second;
            if (status != nullptr) {
                // cout<< "iter " << iter->first <<' '<< iter->second <<  status->lastTime << endl;
               // printf("%ld, %ld, %ld\n", time(NULL), status->lastTime, (time(0) - status->lastTime));
                if(difftime(time(NULL), status->lastTime) > this->keepTime * 2) {
                    std::cout << status->id << "脱离监控区, remove from map\n";
                    delete status;
                    iter = statusMap.erase(iter);
                    continue;
                }
            }
            iter++;
        }
    }
}
/**
 * for debug
 */
void IndirectAlg::printRecord(int tag, Record &record) {
   // printf("%d  %ld : {%f, %f}\n", tag, record.timestamp, record.coordinate.x, record.coordinate.y);
}
/**
 * 是否逆行
*/
bool IndirectAlg::isRetrograde(Record &record) {
    if(record.id.length() == 0) {
        return false;
    }
    Status *status = nullptr;
    map<string, Status *>::iterator statusIter = statusMap.find(record.id);
    if( statusIter != statusMap.end() ) {
     status = statusIter->second;
    }
    if (status == nullptr) {
        // 第一次出现
        if(frame.contains(record.coordinate)) {
            status = new Status({
                .id = record.id,
                .firstTime = record.timestamp,
                .lastTime = record.timestamp,
                .firstInvalTime = 0,
                .lastInvalTime = 0,
                .firstValTime = 0,
                .lastValTime = 0,
                .lastCoordinate = record.coordinate});
            statusMap.insert({record.id, status});
            printRecord(1, record);
        }
        printRecord(2, record);
        return false;
    }
    Vector2 currentDirection = getVecor2(status -> lastCoordinate, record.coordinate);
    if(difftime(record.timestamp, status->lastTime) >= this->keepTime) {
//printf("update lastCoordinate curtime=%ld, lastTime=%ld, diff=%f\n", record.timestamp, status->lastTime, difftime(record.timestamp, status->lastTime));
        status->lastTime = record.timestamp;
        status->lastCoordinate = record.coordinate;
    }
    if (currentDirection.x == 0 && currentDirection.y == 0) {
        //没动
        printRecord(3, record);
        return false;
    }
    //status -> lastCoordinate = record.coordinate;
    //逆行判断 cos小于0即两个向量的夹角大于90度,表示逆行了
    if(frame.contains(record.coordinate) && getVector2Angle(direction, currentDirection) <= 0) {
        if(status->firstInvalTime ==0) {
            //第一次发生逆行
            status->firstInvalTime = status->lastInvalTime = record.timestamp;
//printf("%第一次发生逆行的时间=%ld\n", status->firstInvalTime);
            printRecord(4, record);
            return false;
        } else {
            status->lastInvalTime = record.timestamp;
//printf("%后续发生逆行的时间=%ld\n", status->lastInvalTime);
            //逆行时间超过keeptime
            if (difftime(status->lastInvalTime, status->firstInvalTime) >= keepTime) {
                status->firstValTime = status->lastValTime = 0;
                printRecord(5, record);
                return true;
            }
            printRecord(6, record);
            return false;
        }
    } else {
        if(status->firstValTime ==0) {
            //记录第一次正确行走时间
            status->firstValTime = status->lastValTime = record.timestamp;
            printRecord(7, record);
        } else {
            status->lastValTime = record.timestamp;
             //正确行走时间超过keeptime
            if (difftime(status->lastValTime, status->firstValTime) >= keepTime) {
                status->firstInvalTime = status->lastInvalTime = 0;
                printRecord(8, record);
            }
        }
        return false;
    }
}
algorithm/Makefile
New file
@@ -0,0 +1,53 @@
#
# Makefile for common library.
#
ROOT=..
PLATFORM=$(shell $(ROOT)/systype.sh)
LIBCOMMON=$(ROOT)/common/libusgcommon.a
DLIBCOMMON=$(ROOT)/common/libusgcommon.so
LIBALG = libalg.a
DLIBALG = libalg.so
LDLIBS =-L$(ROOT)/common -lusgcommon $(EXTRALIBS)
include $(ROOT)/Make.defines.$(PLATFORM)
SOURCES := $(wildcard *.c)
OBJS   = $(patsubst %.c, %.o, $(SOURCES))
all: $(LIBALG) $(DLIBALG)
graph.o:  $(LIBCOMMON)
IndirectAlg.o: $(LIBCOMMON)
#static lib
$(LIBALG): $(OBJS) $(LIBCOMMON)
    $(AR) rv $@ $?
    $(RANLIB) $@
#dynamic lib
$(DLIBALG):    $(SOURCES) $(DLIBCOMMON)
    rm -f *.o
    # $(CC) -fPIC $(CFLAGS) $(filter-out $(DLIBCOMMON), $^) -o $@ $(LDFLAGS) $(LDLIBS)
    $(CC) -fPIC -shared $(CFLAGS) -o  $@  $(filter-out $(DLIBCOMMON), $^)
#PREFIX is environment variable, but if it is not set, then set default value
ifeq ($(PREFIX),)
    PREFIX := /usr/local
endif
# 使用方式: g++ test1.c  -lcommon
install: $(DLIBALG)
    sudo install -d $(PREFIX)/lib/
    sudo install -m 644 $^ $(PREFIX)/lib/
    sudo install -d $(PREFIX)/include/
    sudo install -m 644 include/* $(PREFIX)/include/
clean:
    rm -f *.o a.out core temp.* *.a *.so
include $(ROOT)/Make.common.inc
algorithm/graph.c
New file
@@ -0,0 +1,51 @@
#include "usg_common.h"
#include "graph.h"
using namespace std;
const double epsilon = numeric_limits<float>().epsilon();
const numeric_limits<double> DOUBLE;
const double MIN = DOUBLE.min();
const double MAX = DOUBLE.max();
Figure::Figure(){}
//Figure::Figure(const initializer_list<Edge> & _edges): edges(_edges) {}
Figure::Figure(const std::vector<Edge> & _edges): edges(_edges) {}
Figure & Figure::operator=(Figure && f)       // move assignment
{
    //std::cout << "move assignment operator called:\n";
    if (this == &f)
        return *this;
    edges = std::move(f.edges);
    return *this;
}
// bool Figure::contains(const Point& p) const
// {
//     auto c = 0;
//     for (auto e : edges) if (e.isCorss(p)) c++;
//     return c % 2 != 0;
// }
bool Figure::contains(const Point& p) const
{
    return true;
}
/**
 * 是否相交
*/
bool Edge::isCorss(const Point& p) const
{
    if (a.y > b.y) return Edge{ b, a }.isCorss(p);
    if (p.y == a.y || p.y == b.y) return isCorss({ p.x, p.y + epsilon });
    if (p.y > b.y || p.y < a.y || p.x > max(a.x, b.x)) return false;
    if (p.x < min(a.x, b.x)) return true;
    auto blue = abs(a.x - p.x) > MIN ? (p.y - a.y) / (p.x - a.x) : MAX;
    auto red = abs(a.x - b.x) > MIN ? (b.y - a.y) / (b.x - a.x) : MAX;
    return blue >= red;
}
algorithm/include/IndirectAlg.h
New file
@@ -0,0 +1,52 @@
#ifndef __USG_INDIRECTALG_H__
#define __USG_INDIRECTALG_H__
#include "usg_common.h"
#include "graph.h"
struct Record
{
    std::string id;
    time_t timestamp;
    Point coordinate;
};
struct Status;
class IndirectAlg {
    Figure frame;
    //逆行持续时间,要超过这个时间才算逆行
    time_t keepTime;
    // 代表正确行走方向的向量
    Vector2 direction;
    // 状态缓存
    std::map<std::string, Status *> statusMap;
    std::atomic<bool> mterminate;
    std::thread mthread;
    void  threadRoutine();
public:
    IndirectAlg();
    IndirectAlg(const std::initializer_list<Edge> & edges, const time_t & _keepTime, const Vector2 & _direction);
    /**
     * @points  组成观测区域的彼此相邻的点
     * @_keepTime 保持时间
     * @_direction 正确行进的方向方向
     */
    IndirectAlg(const std::initializer_list<Point> & points, const time_t & _keepTime, const Vector2 & _direction);
    ~IndirectAlg();
    void printRecord(int tag, Record &record);
    /**
     * 是否逆行
    */
    bool isRetrograde(Record &record);
};
#endif
algorithm/include/graph.h
New file
@@ -0,0 +1,65 @@
#ifndef __USG_GRAPH_H__
#define __USG_GRAPH_H__
#include "usg_common.h"
struct Point {
//public:
    double x;
    double y;
    //Point(const double _x =0, const double _y =0) : x(_x), y(_y) {}
};
//平面向量
struct Vector2
{
    double x;
    double y;
};
class Edge {
public:
    const Point a, b;
    /**
     * 是否相交
    */
    bool isCorss(const Point& p) const;
};
class Figure {
    //const string  name;
    std::vector<Edge> edges;
public:
    Figure();
    //Figure(const std::initializer_list<Edge> & _edges);
    Figure(const std::vector<Edge> & _edges);
    Figure & operator=(Figure && f);       // move assignment
    bool contains(const Point& p) const;
};
 // 返回两个向量夹角的cos值, cos小于0即两个向量的夹角大于90度
static inline double getVector2Angle(const Vector2 & a, const Vector2 & b) {
    double doc_product =  a.x * b.x + a.y * b.y;
    double ma = sqrt(a.x * a.x + a.y * a.y);
    double mb = sqrt(b.x * b.x + b.y * b.y);
    double cos = doc_product / (ma * mb);
    return cos;
}
// 计算a指向b的向量
static inline Vector2 getVecor2(const Point &a, const Point &b) {
    return {b.x - a.x, b.y - a.y};
}
#endif
basic_pack/README.mk
basic_pack/include/IndirectAlg.h
New file
@@ -0,0 +1,52 @@
#ifndef __USG_INDIRECTALG_H__
#define __USG_INDIRECTALG_H__
#include "usg_common.h"
#include "graph.h"
struct Record
{
    std::string id;
    time_t timestamp;
    Point coordinate;
};
struct Status;
class IndirectAlg {
    Figure frame;
    //逆行持续时间,要超过这个时间才算逆行
    time_t keepTime;
    // 代表正确行走方向的向量
    Vector2 direction;
    // 状态缓存
    std::map<std::string, Status *> statusMap;
    std::atomic<bool> mterminate;
    std::thread mthread;
    void  threadRoutine();
public:
    IndirectAlg();
    IndirectAlg(const std::initializer_list<Edge> & edges, const time_t & _keepTime, const Vector2 & _direction);
    /**
     * @points  组成观测区域的彼此相邻的点
     * @_keepTime 保持时间
     * @_direction 正确行进的方向方向
     */
    IndirectAlg(const std::initializer_list<Point> & points, const time_t & _keepTime, const Vector2 & _direction);
    ~IndirectAlg();
    void printRecord(int tag, Record &record);
    /**
     * 是否逆行
    */
    bool isRetrograde(Record &record);
};
#endif
basic_pack/include/graph.h
New file
@@ -0,0 +1,65 @@
#ifndef __USG_GRAPH_H__
#define __USG_GRAPH_H__
#include "usg_common.h"
struct Point {
//public:
    double x;
    double y;
    //Point(const double _x =0, const double _y =0) : x(_x), y(_y) {}
};
//平面向量
struct Vector2
{
    double x;
    double y;
};
class Edge {
public:
    const Point a, b;
    /**
     * 是否相交
    */
    bool isCorss(const Point& p) const;
};
class Figure {
    //const string  name;
    std::vector<Edge> edges;
public:
    Figure();
    //Figure(const std::initializer_list<Edge> & _edges);
    Figure(const std::vector<Edge> & _edges);
    Figure & operator=(Figure && f);       // move assignment
    bool contains(const Point& p) const;
};
 // 返回两个向量夹角的cos值, cos小于0即两个向量的夹角大于90度
static inline double getVector2Angle(const Vector2 & a, const Vector2 & b) {
    double doc_product =  a.x * b.x + a.y * b.y;
    double ma = sqrt(a.x * a.x + a.y * a.y);
    double mb = sqrt(b.x * b.x + b.y * b.y);
    double cos = doc_product / (ma * mb);
    return cos;
}
// 计算a指向b的向量
static inline Vector2 getVecor2(const Point &a, const Point &b) {
    return {b.x - a.x, b.y - a.y};
}
#endif
basic_pack/include/usg_common.h
New file
@@ -0,0 +1,78 @@
/*
 * Our own header, to be included before all standard system headers.
 */
#ifndef __USG_COMMON_H__
#define __USG_COMMON_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <setjmp.h>
#include <signal.h>
#include <dirent.h>
#include <time.h>
#include <sched.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*
define int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t
*/
#include <stdint.h>
//c++ header
#include <iostream>
#include <string>
#include <cstdlib>
#include <atomic>
#include <algorithm>
#include <iomanip>
#include <limits>
#include <map>
#include <initializer_list>
#include <vector>
#include <thread>
/* Our own error-handling functions */
void err_exit(int error, const char *fmt, ...);
void err_msg(int error, const char *fmt, ...);
static inline int
itoa(int num, char *str)
{
     return sprintf(str, "%d", num);
}
static inline int
ftoa(float num, char *str)
{
     return sprintf(str, "%f", num);
}
#endif
basic_pack/include/usg_typedef.h
New file
@@ -0,0 +1,52 @@
#ifndef _USG_TYPEDEF_H__
#define _USG_TYPEDEF_H__
#ifdef __cplusplus
extern "C" {
#endif
/// @brief Compare And Swap
///        If the current value of *a_ptr is a_oldVal, then write a_newVal into *a_ptr
/// @return true if the comparison is successful and a_newVal was written
#define CAS(a_ptr, a_oldVal, a_newVal) __sync_bool_compare_and_swap(a_ptr, a_oldVal, a_newVal)
#if ! defined(__FreeBSD__) && ! defined(__OpenBSD__) && \
                ! defined(__sgi) && ! defined(__APPLE__)
                /* Some implementations already declare this union */
union semun {                   /* Used in calls to semctl() */
    int                 val;
    struct semid_ds *   buf;
    unsigned short *    array;
#if defined(__linux__)
    struct seminfo *    __buf;
#endif
};
#endif
/* Default file permissions are DEF_MODE & ~DEF_UMASK */
#define DEF_MODE   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
#define DEF_UMASK  S_IWGRP|S_IWOTH
/*
 * Default file access permissions for new files.
 */
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
/*
 * Default permissions for new directories.
 */
#define DIR_MODE  (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
#define min(a,b)  ((a) < (b) ? (a) : (b))
#define max(a,b)  ((a) > (b) ? (a) : (b))
#ifdef __cplusplus
}
#endif
#endif  /* #ifndef  _USG_TYPEDEF_H__ */
basic_pack/test_right_walk2.c
New file
@@ -0,0 +1,60 @@
#include <usg_common.h>        /* cos */
#include <graph.h>
#include <IndirectAlg.h>
using namespace std;
int test2() {
    // IndirectAlg indirectAlg({  {{0.0, 0.0}, {1000.0, 0.0}}, {{1000.0, 0.0}, {1000.0, 1000.0}}, {{1000.0, 1000.0}, {0.0, 1000.0}}, {{0.0, 1000.0}, {0.0, 0.0}} }, 5, {1, 1});
    /**
     * 第一个参数@points  组成观测区域的彼此相邻的点
     * 第二个参数@_keepTime 保持时间
     * 第三个参数@_direction 正确行进的方向方向
     */
    IndirectAlg indirectAlg((std::initializer_list<Point>){{0.0, 0.0}, {1000.0, 0.0},  {1000.0, 1000.0}, {0.0, 1000.0} }, 5, {1, 1});
    int i = 0;
    // time_t start_time;
    srand((unsigned) time(0));
    double rx, ry;
    bool isRetrograde;
    //起点
    Point start = {0, 0};
    //传入的流数据记录信息Record
    Record record;
    record.id = 1; //目标ID
    record.timestamp = time(0); //时间戳
    record.coordinate = start; // 坐标
    // time(&start_time);
    //判断是否逆行
    while(!(isRetrograde = indirectAlg.isRetrograde(record)) ) {
        rx = ((double)(rand()%10))/100000;
        ry = ((double)(rand()%10))/100000;
        //std::cout << timestamp << ":" <<  << "isRetrograde" << isRetrograde;
       // err_msg(0, "%ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
        record.timestamp = time(0);
        //if (difftime(time(0), start_time) > 1)
        if (i > 10)
        {
            record.coordinate = {record.coordinate.x - rx , record.coordinate.y - ry};
        } else {
            record.coordinate = {record.coordinate.x + rx , record.coordinate.y + ry};
        }
        if (i > 100)
            break;
        sleep(1);
        i++;
    }
    printf("return %ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
    return 0;
}
int main() {
    test2();
}
common/Makefile
New file
@@ -0,0 +1,44 @@
#
# Makefile for common library.
#
ROOT=..
PLATFORM=$(shell $(ROOT)/systype.sh)
include $(ROOT)/Make.defines.$(PLATFORM)
LIBCOMMON = libusgcommon.a
DLIBCOMMON = libusgcommon.so
SOURCES := $(wildcard *.c)
OBJS   = $(patsubst %.c, %.o, $(SOURCES))
all: $(LIBCOMMON) $(DLIBCOMMON)
#static lib
$(LIBCOMMON): $(OBJS)
    $(AR) rv $@ $?
    $(RANLIB) $@
#dynamic lib
$(DLIBCOMMON): $(SOURCES)
    rm -f *.o
    $(CC) -fPIC -shared $(CFLAGS) $^ -o $@ $(LDFLAGS) $(LDLIBS)
#PREFIX is environment variable, but if it is not set, then set default value
ifeq ($(PREFIX),)
    PREFIX := /usr/local
endif
# 使用方式: g++ test1.c  -lcommon
install: $(DLIBCOMMON)
    sudo install -d $(PREFIX)/lib/
    sudo install -m 644 $^ $(PREFIX)/lib/
    sudo install -d $(PREFIX)/include/
    sudo install -m 644 include/* $(PREFIX)/include/
clean:
    rm -f *.o a.out core temp.* *.a *.so
# include $(ROOT)/Make.libapue.inc
common/include/usg_common.h
New file
@@ -0,0 +1,78 @@
/*
 * Our own header, to be included before all standard system headers.
 */
#ifndef __USG_COMMON_H__
#define __USG_COMMON_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <setjmp.h>
#include <signal.h>
#include <dirent.h>
#include <time.h>
#include <sched.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*
define int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t
*/
#include <stdint.h>
//c++ header
#include <iostream>
#include <string>
#include <cstdlib>
#include <atomic>
#include <algorithm>
#include <iomanip>
#include <limits>
#include <map>
#include <initializer_list>
#include <vector>
#include <thread>
/* Our own error-handling functions */
void err_exit(int error, const char *fmt, ...);
void err_msg(int error, const char *fmt, ...);
static inline int
itoa(int num, char *str)
{
     return sprintf(str, "%d", num);
}
static inline int
ftoa(float num, char *str)
{
     return sprintf(str, "%f", num);
}
#endif
common/include/usg_typedef.h
New file
@@ -0,0 +1,52 @@
#ifndef _USG_TYPEDEF_H__
#define _USG_TYPEDEF_H__
#ifdef __cplusplus
extern "C" {
#endif
/// @brief Compare And Swap
///        If the current value of *a_ptr is a_oldVal, then write a_newVal into *a_ptr
/// @return true if the comparison is successful and a_newVal was written
#define CAS(a_ptr, a_oldVal, a_newVal) __sync_bool_compare_and_swap(a_ptr, a_oldVal, a_newVal)
#if ! defined(__FreeBSD__) && ! defined(__OpenBSD__) && \
                ! defined(__sgi) && ! defined(__APPLE__)
                /* Some implementations already declare this union */
union semun {                   /* Used in calls to semctl() */
    int                 val;
    struct semid_ds *   buf;
    unsigned short *    array;
#if defined(__linux__)
    struct seminfo *    __buf;
#endif
};
#endif
/* Default file permissions are DEF_MODE & ~DEF_UMASK */
#define DEF_MODE   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
#define DEF_UMASK  S_IWGRP|S_IWOTH
/*
 * Default file access permissions for new files.
 */
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
/*
 * Default permissions for new directories.
 */
#define DIR_MODE  (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
#define min(a,b)  ((a) < (b) ? (a) : (b))
#define max(a,b)  ((a) > (b) ? (a) : (b))
#ifdef __cplusplus
}
#endif
#endif  /* #ifndef  _USG_TYPEDEF_H__ */
common/usg_common.c
New file
@@ -0,0 +1,78 @@
#include "usg_common.h"
#include <errno.h>        /* for definition of errno */
#include <stdarg.h>        /* ISO C variable aruments */
#define MAXLINE 4096      /* max line length */
/**************************
 * Error-handling functions
 **************************/
static void    err_doit(int, const char *, va_list);
//static void err_doit(int errno, const char *fmt, va_list ap);
/*void unix_error(const char *fmt, ...) [> Unix-style error <]*/
/*{*/
    /*va_list        ap;*/
    /*va_start(ap, fmt);*/
    /*err_doit(errno, fmt, ap);*/
    /*va_end(ap);*/
/*}*/
void posix_error(int code, const char *fmt, ...) /* Posix-style error */
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(code, fmt, ap);
    va_end(ap);
}
/*
 * Fatal error unrelated to a system call.
 * Error code passed as explict parameter.
 * Print a message and terminate.
 */
void err_exit(int error, const char *fmt, ...)
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(error, fmt, ap);
    va_end(ap);
    //abort();        /* dump core and terminate */
    exit(1);
}
/*
 * Nonfatal error unrelated to a system call.
 * Print a message and return.
 */
void err_msg(int error, const char *fmt, ...)
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(error, fmt, ap);
    va_end(ap);
}
/*
 * Print a message and return to caller.
 * Caller specifies "errnoflag".
 */
static void err_doit(int error, const char *fmt, va_list ap)
{
    char    buf[MAXLINE];
    vsnprintf(buf, MAXLINE-1, fmt, ap);
    if (error != 0) {
        snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1, ": %s", strerror(error));
    }
    strcat(buf, "\n");
    fflush(stdout);        /* in case stdout and stderr are the same */
    fputs(buf, stderr);
    fflush(NULL);        /* flushes all stdio output streams */
}
systype.sh
New file
@@ -0,0 +1,28 @@
 # (leading space required for Xenix /bin/sh)
#
# Determine the type of *ix operating system that we're
# running on, and echo an appropriate value.
# This script is intended to be used in Makefiles.
# (This is a kludge.  Gotta be a better way.)
#
case `uname -s` in
"FreeBSD")
    PLATFORM="freebsd"
    ;;
"Linux")
    PLATFORM="linux"
    ;;
"Darwin")
    PLATFORM="macos"
    ;;
"SunOS")
    PLATFORM="solaris"
    ;;
*)
    echo "Unknown platform" >&2
    exit 1
esac
echo $PLATFORM
exit 0
test/Makefile
New file
@@ -0,0 +1,38 @@
ROOT=..
EXTRALIBS+=
INCLUDE+=-I. -I$(ROOT)/algorithm/include -I$(ROOT)/algorithm -I$(ROOT)/common/include
LIBCOMMON=$(ROOT)/common/libusgcommon.a
LIBALG=$(ROOT)/algorithm/libalg.a
LDLIBS = -lpthread
PLATFORM=$(shell $(ROOT)/systype.sh)
include $(ROOT)/Make.defines.$(PLATFORM)
PROGS =    test_right_walk test_right_walk3
all: $(PROGS)
# 如果包A 引用包B, B 要放在 A 后面
test_right_walk: $(LIBALG) $(LIBCOMMON)
test_right_walk3: $(LIBALG) $(LIBCOMMON)
#test_right_walk: $(ROOT)/algorithm/graph.c $(ROOT)/algorithm/IndirectAlg.c  $(LIBCOMMON)
test_right_walk2: test_right_walk2.c
    #g++  -std=c++11 -mcx16 -Wall  -DLINUX -D_GNU_SOURCE  test_right_walk2.c -o $@  -lalg -lusgcommon
    g++  -std=c++11  test_right_walk2.c -o test_right_walk2  -lalg  -lusgcommon -lpthread
clean:
    rm -f $(PROGS) $(TEMPFILES)
$(LIBCOMMON):
    (cd $(ROOT)/common && $(MAKE))
$(LIBALG):
    (cd $(ROOT)/algorithm && $(MAKE))
test/test.txt
New file
@@ -0,0 +1,132 @@
231 1592301264 {2041 40 387 920}
231 1592301264 {1970 54 426 913}
231 1592301265 {1938 58 381 917}
231 1592301265 {1919 54 381 920}
231 1592301265 {1841 58 394 990}
231 1592301265 {1932 29 284 1026}
231 1592301265 {1802 36 400 1055}
231 1592301265 {1776 18 400 1099}
231 1592301265 {1692 62 452 1074}
231 1592301265 {1602 102 555 1034}
231 1592301265 {1596 105 549 1026}
231 1592301265 {1570 43 510 1110}
231 1592301265 {1576 40 478 1121}
231 1592301265 {1583 43 458 1118}
231 1592301265 {1570 18 432 1154}
231 1592301265 {1563 25 413 1143}
231 1592301265 {1544 21 413 1150}
231 1592301265 {1537 73 374 1092}
231 1592301265 {1518 36 387 1147}
231 1592301266 {1518 32 381 1158}
231 1592301266 {1518 32 387 1169}
231 1592301266 {1512 40 374 1165}
231 1592301266 {1512 40 374 1165}
231 1592301266 {1512 43 381 1150}
231 1592301266 {1512 47 387 1150}
231 1592301266 {1512 51 381 1150}
231 1592301266 {1512 43 381 1161}
231 1592301266 {1512 43 374 1150}
231 1592301266 {1512 43 374 1158}
231 1592301266 {1505 36 374 1161}
231 1592301266 {1486 21 394 1176}
231 1592301266 {1447 29 426 1158}
231 1592301266 {1421 32 426 1147}
231 1592301266 {1363 21 445 1169}
231 1592301266 {1350 14 452 1176}
231 1592301267 {1337 21 458 1154}
231 1592301267 {1331 21 458 1147}
231 1592301267 {1311 21 484 1136}
231 1592301267 {1266 18 471 1099}
231 1592301267 {1240 18 478 1085}
231 1592301267 {1221 10 484 1088}
231 1592301267 {1208 0 407 1099}
231 1592301267 {1188 0 323 1114}
231 1592301267 {1169 0 310 1118}
231 1592301267 {1124 0 348 1099}
231 1592301267 {1098 0 374 1107}
231 1592301267 {1059 0 407 1096}
231 1592301267 {962 0 504 1070}
231 1592301267 {924 0 536 1063}
231 1592301267 {891 10 491 1026}
231 1592301267 {898 21 432 979}
231 1592301268 {833 102 361 851}
231 1592301268 {833 113 336 858}
231 1592301268 {794 0 355 1019}
231 1592301268 {743 0 413 1012}
231 1592301268 {646 40 510 960}
231 1592301268 {620 21 523 979}
231 1592301268 {575 58 555 946}
231 1592301268 {555 120 510 855}
231 1592301268 {555 80 439 928}
231 1592301268 {523 10 368 982}
231 1592301268 {504 47 342 898}
231 1592301268 {420 113 316 880}
231 1592301268 {407 105 336 884}
231 1592301268 {381 113 348 887}
231 1592301268 {368 58 361 953}
231 1592301272 {316 0 342 836}
231 1592301272 {329 0 387 840}
231 1592301272 {368 7 432 840}
231 1592301272 {374 10 426 833}
231 1592301273 {400 32 452 814}
231 1592301273 {445 7 400 855}
231 1592301273 {497 73 348 803}
231 1592301273 {555 3 277 865}
231 1592301273 {659 109 368 814}
231 1592301273 {665 54 400 847}
231 1592301273 {684 113 394 818}
231 1592301273 {749 65 361 898}
231 1592301273 {762 95 374 807}
231 1592301273 {840 65 290 906}
231 1592301273 {852 32 290 942}
231 1592301273 {833 0 329 997}
231 1592301273 {924 109 329 851}
231 1592301273 {988 0 452 993}
231 1592301274 {982 7 491 979}
231 1592301274 {1008 0 491 1015}
231 1592301274 {1033 3 478 1001}
231 1592301274 {1053 3 465 1008}
231 1592301274 {1182 0 348 1026}
231 1592301274 {1260 0 245 1023}
231 1592301274 {1350 43 310 990}
231 1592301274 {1350 0 426 1077}
231 1592301274 {1350 7 465 1074}
231 1592301274 {1356 0 484 1085}
231 1592301274 {1369 10 510 1081}
231 1592301274 {1402 18 471 1066}
231 1592301274 {1499 18 407 1081}
231 1592301274 {1550 29 381 1063}
231 1592301274 {1705 0 342 1114}
231 1592301274 {1731 10 329 1103}
231 1592301275 {1738 7 355 1107}
231 1592301275 {1738 21 426 1088}
231 1592301275 {1731 18 484 1096}
231 1592301275 {1738 54 555 1066}
231 1592301275 {1744 54 594 1070}
231 1592301275 {1990 36 348 957}
232 1592301284 {1815 829 523 690}
232 1592301284 {1731 745 471 781}
232 1592301284 {1647 730 529 792}
232 1592301284 {1557 705 555 818}
232 1592301284 {1505 690 575 829}
232 1592301284 {1453 661 581 855}
232 1592301284 {1460 643 516 891}
232 1592301284 {1447 621 491 895}
232 1592301284 {1395 573 516 939}
232 1592301284 {1376 533 516 1001}
232 1592301284 {1363 485 510 1045}
232 1592301284 {1356 471 510 1059}
232 1592301284 {1363 467 491 1066}
232 1592301284 {1376 442 465 1092}
232 1592301284 {1376 431 465 1099}
232 1592301285 {1408 390 458 1147}
232 1592301285 {1415 369 452 1161}
232 1592301285 {1447 332 426 1180}
232 1592301285 {1453 317 432 1198}
232 1592301285 {1473 306 426 1202}
232 1592301285 {1492 288 407 1220}
232 1592301285 {1499 292 413 1220}
232 1592301285 {1550 285 407 1176}
232 1592301285 {1563 277 407 1165}
232 1592301285 {1608 193 394 1169}
232 1592301285 {1628 211 381 1085}
test/test2.txt
New file
@@ -0,0 +1,86 @@
535 1592307583 {2061 120 445 760}
535 1592307583 {2080 102 394 858}
535 1592307583 {2067 105 361 840}
535 1592307583 {2016 98 387 851}
535 1592307583 {1977 105 400 844}
535 1592307583 {1944 95 381 862}
535 1592307583 {1873 105 413 1030}
535 1592307583 {1718 116 542 1048}
535 1592307583 {1712 124 523 1052}
535 1592307583 {1692 127 523 1066}
535 1592307584 {1680 120 465 1077}
535 1592307584 {1686 124 439 1066}
535 1592307584 {1712 109 348 1092}
535 1592307584 {1686 109 361 1088}
535 1592307584 {1550 124 400 1107}
535 1592307584 {1421 113 484 1129}
535 1592307584 {1369 124 516 1118}
535 1592307584 {1318 149 549 1121}
535 1592307584 {1318 138 536 1143}
535 1592307584 {1318 138 529 1140}
535 1592307584 {1324 135 439 1150}
535 1592307584 {1331 127 387 1165}
535 1592307584 {1324 146 290 1150}
535 1592307584 {1260 146 323 1132}
535 1592307584 {1234 135 323 1158}
535 1592307584 {1117 138 420 1150}
535 1592307584 {1027 153 516 1129}
535 1592307585 {1008 171 516 1107}
535 1592307585 {995 168 523 1114}
535 1592307585 {995 149 516 1136}
535 1592307585 {930 160 510 1110}
535 1592307585 {917 153 426 1110}
535 1592307585 {930 175 336 1085}
535 1592307585 {840 157 329 1110}
535 1592307585 {814 127 336 1176}
535 1592307585 {749 160 413 1121}
535 1592307585 {639 175 523 1107}
535 1592307585 {626 186 536 1099}
535 1592307585 {613 182 516 1110}
535 1592307585 {600 179 510 1110}
535 1592307585 {555 171 439 1121}
535 1592307585 {523 171 420 1125}
535 1592307585 {491 160 329 1165}
535 1592307586 {465 157 342 1180}
535 1592307586 {458 164 342 1180}
535 1592307586 {394 197 407 1136}
535 1592307586 {400 200 407 1132}
535 1592307586 {381 193 426 1140}
535 1592307586 {381 204 400 1114}
535 1592307586 {394 361 368 960}
538 1592307603 {432 182 471 1074}
538 1592307603 {465 182 432 1074}
538 1592307603 {510 171 387 1092}
538 1592307603 {529 179 381 1081}
538 1592307603 {568 171 355 1088}
538 1592307603 {633 164 316 1103}
538 1592307603 {678 160 432 1096}
538 1592307603 {684 171 516 1085}
538 1592307603 {704 186 549 1059}
538 1592307603 {736 179 562 1070}
538 1592307603 {756 179 562 1074}
538 1592307603 {865 142 458 1085}
538 1592307603 {930 138 368 1074}
538 1592307603 {1079 105 297 1096}
538 1592307604 {1130 105 471 1085}
538 1592307604 {1137 124 497 1066}
538 1592307604 {1156 124 516 1066}
538 1592307604 {1137 138 555 1055}
538 1592307604 {1195 131 516 1066}
538 1592307604 {1247 124 465 1077}
538 1592307604 {1389 113 342 1107}
538 1592307604 {1428 105 355 1118}
538 1592307604 {1486 105 303 1114}
538 1592307604 {1505 98 368 1121}
538 1592307604 {1531 102 368 1107}
538 1592307604 {1531 113 452 1096}
538 1592307604 {1531 116 465 1096}
538 1592307604 {1531 113 504 1103}
538 1592307604 {1544 105 504 1118}
538 1592307604 {1718 109 387 1059}
538 1592307605 {1738 105 432 1008}
538 1592307605 {1789 76 394 1048}
538 1592307605 {1867 69 342 1081}
538 1592307605 {1841 76 400 1066}
538 1592307605 {1925 91 413 920}
538 1592307605 {1970 102 432 876}
test/test3.txt
New file
@@ -0,0 +1,3 @@
67 1598255557 {343 213}
66 1598255557 {110 393}
67 1598255557 {343 213}
test/test_map.c
New file
@@ -0,0 +1,38 @@
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
    map<int, string> mapStudent;
    mapStudent.insert(pair<int, string>(1, "student_one"));
    mapStudent.insert(pair<int, string>(2, "student_two"));
    mapStudent.insert(pair<int, string>(3, "student_three"));
    map<int, string>::iterator iter;
    iter = mapStudent.find(1);
    if(iter != mapStudent.end())
       cout << iter->first << ", Find, the value is "<<iter->second<<endl;
    else
       cout<<"Do not Find"<<endl;
    return 0;
}
test/test_map2.c
New file
@@ -0,0 +1,79 @@
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
using namespace std::literals;
template<typename It>
void printInsertionStatus(It it, bool success)
{
    std::cout << "Insertion of " << it->first << (success ? " succeeded\n" : " failed\n");
}
int main()
{
    std::map<std::string, float> karasunoPlayerHeights;
    // Overload 3: insert from rvalue reference
    const auto [it_hinata, success] = karasunoPlayerHeights.insert({"Hinata"s, 162.8});
    printInsertionStatus(it_hinata, success);
    {
        // Overload 1: insert from lvalue reference
        const auto [it, success2] = karasunoPlayerHeights.insert(*it_hinata);
        printInsertionStatus(it, success2);
    }
    {
        // Overload 2: insert via forwarding to emplace
        const auto [it, success] = karasunoPlayerHeights.insert({"Kageyama", 180.6});
        printInsertionStatus(it, success);
    }
    {
        // Overload 6: insert from rvalue reference with positional hint
        const std::size_t n = std::size(karasunoPlayerHeights);
        const auto it = karasunoPlayerHeights.insert(it_hinata, {"Azumane"s, 184.7});
        printInsertionStatus(it, std::size(karasunoPlayerHeights) != n);
    }
    {
        // Overload 4: insert from lvalue reference with positional hint
        const std::size_t n = std::size(karasunoPlayerHeights);
        const auto it = karasunoPlayerHeights.insert(it_hinata, *it_hinata);
        printInsertionStatus(it, std::size(karasunoPlayerHeights) != n);
    }
    {
        // Overload 5: insert via forwarding to emplace with positional hint
        const std::size_t n = std::size(karasunoPlayerHeights);
        const auto it = karasunoPlayerHeights.insert(it_hinata, {"Tsukishima", 188.3});
        printInsertionStatus(it, std::size(karasunoPlayerHeights) != n);
    }
    auto node_hinata = karasunoPlayerHeights.extract(it_hinata);
    std::map<std::string, float> playerHeights;
    // Overload 7: insert from iterator range
    playerHeights.insert(std::begin(karasunoPlayerHeights), std::end(karasunoPlayerHeights));
    // Overload 8: insert from initializer_list
    playerHeights.insert({{"Kozume"s, 169.2}, {"Kuroo", 187.7}});
    // Overload 9: insert node
    const auto status = playerHeights.insert(std::move(node_hinata));
    printInsertionStatus(status.position, status.inserted);
    node_hinata = playerHeights.extract(status.position);
    {
        // Overload 10: insert node with positional hint
        const std::size_t n = std::size(playerHeights);
        const auto it = playerHeights.insert(std::begin(playerHeights), std::move(node_hinata));
        printInsertionStatus(it, std::size(playerHeights) != n);
    }
    // Print resulting map
    std::cout << std::left << '\n';
    for (const auto& [name, height] : playerHeights)
        std::cout << std::setw(10) << name << " | " << height << "cm\n";
}
test/test_right_walk
Binary files differ
test/test_right_walk.c
New file
@@ -0,0 +1,115 @@
#include "usg_common.h"        /* cos */
#include "graph.h"
#include "IndirectAlg.h"
using namespace std;
int test2() {
    // IndirectAlg indirectAlg({  {{0.0, 0.0}, {1000.0, 0.0}}, {{1000.0, 0.0}, {1000.0, 1000.0}}, {{1000.0, 1000.0}, {0.0, 1000.0}}, {{0.0, 1000.0}, {0.0, 0.0}} }, 5, {1, 1});
    IndirectAlg indirectAlg((std::initializer_list<Point>){{0.0, 0.0}, {1000.0, 0.0},  {1000.0, 1000.0}, {0.0, 1000.0} }, 5, {1, 1});
    int i = 0;
    time_t start_time;
    srand((unsigned) time(0));
    double rx, ry;
    bool isRetrograde;
    Point start = {0, 0};
    Record record;
    record.id = 1;
    record.timestamp = time(0);
    record.coordinate = start;
    time(&start_time);
    while(!(isRetrograde = indirectAlg.isRetrograde(record)) ) {
        rx = ((double)(rand()%10))/100000;
        ry = ((double)(rand()%10))/100000;
        //std::cout << timestamp << ":" <<  << "isRetrograde" << isRetrograde;
       // err_msg(0, "%ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
        record.timestamp = time(0);
        //if (difftime(time(0), start_time) > 1)
        if (i > 10)
        {
            record.coordinate = {record.coordinate.x - rx , record.coordinate.y - ry};
        } else {
            record.coordinate = {record.coordinate.x + rx , record.coordinate.y + ry};
        }
        if (i > 100)
            break;
        sleep(1);
        i++;
    }
    printf("return %ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
    return 0;
}
int main() {
    test2();
}
int test()
{
   // cout << epsilon << endl;
   // Vector3 a = new Vector3(1, 1, 1);
    // double param, result;
    // param = 0;
    // result = cos ( param * PI / 180.0 );
    // printf ("The cosine of %f degrees is %f.\n", param, result );
    // param = 60.0;
    // result = cos ( param * PI / 180.0 );
    // printf ("The cosine of %f degrees is %f.\n", param, result );
    // param = 90.0;
    // result = cos ( param * PI / 180.0 );
    // printf ("The cosine of %f degrees is %f.\n", param, result );
    // param = 100.0;
    // result = cos ( param * PI / 180.0 );
    // printf ("The cosine of %f degrees is %f.\n", param, result );
    // param = 180.0;
    // result = cos ( param * PI / 180.0 );
    // printf ("The cosine of %f degrees is %f.\n", param, result );
    // param = 360.0;
    // result = cos ( param * PI / 180.0 );
    // printf ("The cosine of %f degrees is %f.\n", param, result );
    // result = getAngle({3, 4}, {4, 3});
    // printf ("getAngle result is  %f.\n", result );
    // const initializer_list<Point> points =  { { 5.0, 5.0}, {5.0, 8.0}, {-10.0, 5.0}, {0.0, 5.0}, {10.0, 5.0}, {8.0, 5.0}, {10.0, 10.0} };
    // const Figure square = { "Square",
    //     {  {{0.0, 0.0}, {10.0, 0.0}}, {{10.0, 0.0}, {10.0, 10.0}}, {{10.0, 10.0}, {0.0, 10.0}}, {{0.0, 10.0}, {0.0, 0.0}} }
    // };
    // const Figure square_hole = { "Square hole",
    //     {  {{0.0, 0.0}, {10.0, 0.0}}, {{10.0, 0.0}, {10.0, 10.0}}, {{10.0, 10.0}, {0.0, 10.0}}, {{0.0, 10.0}, {0.0, 0.0}},
    //        {{2.5, 2.5}, {7.5, 2.5}}, {{7.5, 2.5}, {7.5, 7.5}}, {{7.5, 7.5}, {2.5, 7.5}}, {{2.5, 7.5}, {2.5, 2.5}}
    //     }
    // };
    // const Figure strange = { "Strange",
    //     {  {{0.0, 0.0}, {2.5, 2.5}}, {{2.5, 2.5}, {0.0, 10.0}}, {{0.0, 10.0}, {2.5, 7.5}}, {{2.5, 7.5}, {7.5, 7.5}},
    //        {{7.5, 7.5}, {10.0, 10.0}}, {{10.0, 10.0}, {10.0, 0.0}}, {{10.0, 0}, {2.5, 2.5}}
    //     }
    // };
    // const Figure exagon = { "Exagon",
    //     {  {{3.0, 0.0}, {7.0, 0.0}}, {{7.0, 0.0}, {10.0, 5.0}}, {{10.0, 5.0}, {7.0, 10.0}}, {{7.0, 10.0}, {3.0, 10.0}},
    //        {{3.0, 10.0}, {0.0, 5.0}}, {{0.0, 5.0}, {3.0, 0.0}}
    //     }
    // };
    // for(auto f : {square, square_hole, strange, exagon})
    //     f.check(points, cout);
    return EXIT_SUCCESS;
}
test/test_right_walk2
Binary files differ
test/test_right_walk2.c
New file
@@ -0,0 +1,60 @@
#include <usg_common.h>        /* cos */
#include <graph.h>
#include <IndirectAlg.h>
using namespace std;
int test2() {
    // IndirectAlg indirectAlg({  {{0.0, 0.0}, {1000.0, 0.0}}, {{1000.0, 0.0}, {1000.0, 1000.0}}, {{1000.0, 1000.0}, {0.0, 1000.0}}, {{0.0, 1000.0}, {0.0, 0.0}} }, 5, {1, 1});
    /**
     * 第一个参数@points  组成观测区域的彼此相邻的点
     * 第二个参数@_keepTime 保持时间
     * 第三个参数@_direction 正确行进的方向方向
     */
    IndirectAlg indirectAlg((std::initializer_list<Point>){{0.0, 0.0}, {1000.0, 0.0},  {1000.0, 1000.0}, {0.0, 1000.0} }, 5, {1, 1});
    int i = 0;
    // time_t start_time;
    srand((unsigned) time(0));
    double rx, ry;
    bool isRetrograde;
    //起点
    Point start = {0, 0};
    //传入的流数据记录信息Record
    Record record;
    record.id = 1; //目标ID
    record.timestamp = time(0); //时间戳
    record.coordinate = start; // 坐标
    // time(&start_time);
    //判断是否逆行
    while(!(isRetrograde = indirectAlg.isRetrograde(record)) ) {
        rx = ((double)(rand()%10))/100000;
        ry = ((double)(rand()%10))/100000;
        //std::cout << timestamp << ":" <<  << "isRetrograde" << isRetrograde;
       // err_msg(0, "%ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
        record.timestamp = time(0);
        //if (difftime(time(0), start_time) > 1)
        if (i > 10)
        {
            record.coordinate = {record.coordinate.x - rx , record.coordinate.y - ry};
        } else {
            record.coordinate = {record.coordinate.x + rx , record.coordinate.y + ry};
        }
        if (i > 100)
            break;
        sleep(1);
        i++;
    }
    printf("return %ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
    return 0;
}
int main() {
    test2();
}
test/test_right_walk3
Binary files differ
test/test_right_walk3.c
New file
@@ -0,0 +1,163 @@
#include <usg_common.h>        /* cos */
#include <graph.h>
#include <IndirectAlg.h>
#include <fstream>
using namespace std;
char *ltrim(char *str, const char *seps)
{
    size_t totrim;
    if (seps == NULL) {
        seps = "\t\n\v\f\r ";
    }
    totrim = strspn(str, seps);
    if (totrim > 0) {
        size_t len = strlen(str);
        if (totrim == len) {
            str[0] = '\0';
        }
        else {
            memmove(str, str + totrim, len + 1 - totrim);
        }
    }
    return str;
}
char *rtrim(char *str, const char *seps)
{
    int i;
    if (seps == NULL) {
        seps = "\t\n\v\f\r ";
    }
    i = strlen(str) - 1;
    while (i >= 0 && strchr(seps, str[i]) != NULL) {
        str[i] = '\0';
        i--;
    }
    return str;
}
char *trim(char *str, const char *seps)
{
    return ltrim(rtrim(str, seps), seps);
}
int test2() {
    // IndirectAlg indirectAlg({  {{0.0, 0.0}, {1000.0, 0.0}}, {{1000.0, 0.0}, {1000.0, 1000.0}}, {{1000.0, 1000.0}, {0.0, 1000.0}}, {{0.0, 1000.0}, {0.0, 0.0}} }, 5, {1, 1});
    /**
     * 第一个参数@points  组成观测区域的彼此相邻的点
     * 第二个参数@_keepTime 保持时间
     * 第三个参数@_direction 正确行进的方向方向
     */
    IndirectAlg indirectAlg((std::initializer_list<Point>){{0.0, 0.0}, {1000.0, 0.0},  {1000.0, 1000.0}, {0.0, 1000.0} }, 5, {1, 1});
    int i = 0;
    // time_t start_time;
    srand((unsigned) time(0));
    double rx, ry;
    bool isRetrograde;
    //起点
    Point start = {0, 0};
    //传入的流数据记录信息Record
    Record record;
    record.id = 1; //目标ID
    record.timestamp = time(0); //时间戳
    record.coordinate = start; // 坐标
    // time(&start_time);
    //判断是否逆行
    while(!(isRetrograde = indirectAlg.isRetrograde(record)) ) {
        rx = ((double)(rand()%10))/100000;
        ry = ((double)(rand()%10))/100000;
        //std::cout << timestamp << ":" <<  << "isRetrograde" << isRetrograde;
       // err_msg(0, "%ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
        record.timestamp = time(0);
        //if (difftime(time(0), start_time) > 1)
        if (i > 10)
        {
            record.coordinate = {record.coordinate.x - rx , record.coordinate.y - ry};
        } else {
            record.coordinate = {record.coordinate.x + rx , record.coordinate.y + ry};
        }
        if (i > 100)
            break;
        sleep(1);
        i++;
    }
    printf("return %ld : {%f, %f}  %d\n", record.timestamp, record.coordinate.x, record.coordinate.y, isRetrograde);
    return 0;
}
void test3() {
    std::ifstream fin("test3.txt");
    char line[1024];
    //std::string line;
    char *targetIdStr;
    char *timestampStr;
    char *targetStr;
    char *targetStrBegin;
    char *targetStrEnd;
    char *targetPointXstr;
    char *targetPointYstr;
//{"x":148,"y":45},{"x":148,"y":539},{"x":769,"y":539},{"x":769,"y":45}
    //{148, 45}, {148, 539},  {769, 539}, {769, 45}
    Record record;
    IndirectAlg indirectAlg((std::initializer_list<Point>){}, 3, {621, 0});
    // const char *delim = " ";
    while(fin.getline(line, 1024)) {
        // printf("line=%s\n", line);
        if(strlen(trim(line, NULL))== 0)
            continue;
        if(*line == '#') {
            continue;
        }
        targetStrBegin = strchr(line, '{');
        targetStrEnd = strchr(line, '}');
        *targetStrBegin = 0;
        *targetStrEnd = 0;
        targetIdStr  = strtok(line, " ");
        timestampStr = strtok(NULL, " ");
        targetStr = targetStrBegin + 1;
        targetPointXstr =  strtok(targetStr, " ");
        targetPointYstr = strtok(NULL, " ");
        //std::cout << targetIdStr << "," << timestampStr << ","  << targetPointXstr << ","  << targetPointYstr << std::endl;
        record.id = targetIdStr;
        record.timestamp = atol(timestampStr);
        record.coordinate.x =  strtod(targetPointXstr, 0);
        record.coordinate.y =  strtod(targetPointYstr, 0);
        if ( indirectAlg.isRetrograde(record)) {
             std::cout << record.id  << "," <<  record.timestamp << ","  << record.coordinate.x << ","  << record.coordinate.y << std::endl;
        }
        // while(token) {
        //     puts(token);
        //     token = strtok(NULL, " ");
        // }
        // printf("key = %s, value=%s\n", key, value);
    }
    fin.close();
    sleep(30);
}
int main() {
    test3();
}