Browse Source

simple test case & debug & luanch.json

master
gjj 4 months ago
parent
commit
0820d15b75
  1. 724
      .clang-format
  2. 64
      .clang-tidy
  3. 2
      CMakeLists.txt
  4. 3
      include/common.hpp
  5. 81
      include/line.hpp
  6. 20
      include/solid.hpp
  7. 26
      include/vec.hpp
  8. 26
      main.cpp

724
.clang-format

@ -1,362 +1,362 @@
---
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: LLVM
Language: Cpp
# this style configuration is based on google style configuration.
# The following configuration is different from the basic configuration.
# 缩进宽度
IndentWidth: 4
# 访问权限说明符(public/private等)的偏移
AccessModifierOffset: -4
# # 开括号(开圆括号、尖括号、方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
# AlignAfterOpenBracket: Align
# # 连续赋值时,对齐所有等号
# AlignConsecutiveAssignments: false
# # 连续声明时,对齐所有声明的变量名
# AlignConsecutiveDeclarations: false
# 反斜杆换行的对齐方式
# -- DontAlign - 不进行对齐
# -- Left - 反斜杠靠左对齐
# -- Right - 反斜杠靠右对齐
# AlignEscapedNewlines: Right
# 二元、三元表达式的对齐方式(当表达式需要占用多行时)
# -- DontAlign - 不进行对齐
# -- Align - 从操作符开始对齐
# -- AlignAfterOperator - 从操作数开始对齐
AlignOperands: true
# # 是否对齐行尾注释
# AlignTrailingComments: true
# # 函数声明的所有参数在放在下一行
# AllowAllParametersOfDeclarationOnNextLine: false
# # 是否允许短的代码块放在同一行
# AllowShortBlocksOnASingleLine: false
# # 短的case标签和语句放在同一行
# AllowShortCaseLabelsOnASingleLine: true
# # 短的函数放在同一行
# -- None - 不把短的函数放在同一行
# -- InlineOnly - 只把类内的内联函数放在同一行,全局的空函数不放在同一行
# -- Empty - 只把空的函数放在同一行
# -- Inline - 把类内的内联函数放在同一行,全局的空函数不放在同一行
# -- All - 都允许放在同一行
AllowShortFunctionsOnASingleLine: InlineOnly
# # 短的if语句保持在同一行
# AllowShortIfStatementsOnASingleLine: true
# # 短的循环保持在同一行
# AllowShortLoopsOnASingleLine: true
# # 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数),
# # AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
# AlwaysBreakAfterReturnType: None
# # 总是在多行string字面量前换行
# AlwaysBreakBeforeMultilineStrings: true
# # 总是在template声明后换行
AlwaysBreakTemplateDeclarations: true
# # 函数调用时,参数的放置规则
# -- false - 参数要么放在同一行,要么每个参数占用一行
# -- true - 不做强制要求
# BinPackArguments: true
# 函数声明、定义时,参数的放置规则
# -- false - 参数要么放在同一行,要么每个参数占用一行
# -- true - 不做强制要求
# BinPackParameters: true
# 大括号放置风格
# -- Attach - 大括号紧随前方内容,放在同一行
# -- Linux - 与 Attach 类似,除了 函数、命名空间、类定义 的大括号放在下一行
# -- Mozilla - 与 Attach 类似,除了枚举、函数、结构(class\struct\union)的大括号放在下一行
# -- Stroustrup - 与 Attach 类似,但函数定义前、catch前方、else前方的"{}"放在单独一行
# -- Allman - 总是换行
# -- Whitesmiths - 类似 Allman,但"{}"和内部的语句对齐到同样位置
# -- GNU - 总是换行,但在控制语句后的"{}"总是对齐到下一个位置
# -- WebKit - 与 Attach 类似,但在函数定义前换行
# -- Custom - 依赖 BraceWrapping
# 注:这里认为语句块也属于函数
BreakBeforeBraces: Attach
# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
# class定义后面
AfterClass: false
# 控制语句后面
AfterControlStatement: false
# enum定义后面
AfterEnum: false
# 函数定义后面
AfterFunction: true
# 命名空间定义后面
AfterNamespace: true
# ObjC定义后面
AfterObjCDeclaration: false
# struct定义后面
AfterStruct: false
# union定义后面
AfterUnion: false
# extern之后
AfterExternBlock: true
# catch之前
BeforeCatch: false
# else之前
BeforeElse: false
# 继续缩进大括号
IndentBraces: false
# 分离空函数
# # 当空白函数的"{}"和函数名称不需要放在同一行时,是否拆分函数体
SplitEmptyFunction: true
# 分离空语句
# # 当空白结构(class\struct\union)的"{}"需要放在单独的行时,是否拆分"{}"
SplitEmptyRecord: true
# 分离空命名空间
# # 当空白的命名空间的"{}"需要放在单独的行时,是否拆分"{}"
SplitEmptyNamespace: true
# # 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: NonAssignment
# BreakBeforeInheritanceComma: false
# # 在三元运算符前换行
# 当三元表达式不能放在同一行时,是否在三元操作符前方换行
# -- true - 操作符位于新行的首部
# -- false - 操作符位于上一行的尾部
BreakBeforeTernaryOperators: true
# BreakConstructorInitializersBeforeComma: false
# # 构造函数初始化列表分割方式
# -- BeforeColon - 在冒号 ':' 前方分割,冒号位于行首,逗号','位于行尾
# -- BeforeComma - 在冒号和逗号前方分割,冒号和逗号都位于行首,并且对齐
# -- AfterColon - 在冒号和逗号后方分割,冒号和逗号位于行尾
BreakConstructorInitializers: BeforeColon
# # 是否在每个java注解后方换行
# BreakAfterJavaFieldAnnotations: false
# # 是否分割过长的字符串
# BreakStringLiterals: false
# # 每行字符长度的限制,0表示没有限制
ColumnLimit: 100
# # 用于匹配注释信息的正则表达式,被匹配的行不会做任何修改
# CommentPragmas: '^ IWYU pragma:'
# 是否压缩紧接的命名空间
# -- true - 将紧跟的命名空间放在同一行
# -- false - 每个命名空间位于新的一行
CompactNamespaces: false
# # 构造函数的初始化列表要么都在同一行,要么都各自一行
# -- true - 如果可能,初始化列表放在同一行;如果不满足长度选择,则每个单独放一行
# -- false - 初始化列表可以随意放置
# ConstructorInitializerAllOnOneLineOrOnePerLine: false
# # 构造函数的初始化列表和基类集成列表的对齐宽度
ConstructorInitializerIndentWidth: 4
# # 延续语句的对齐宽度
ContinuationIndentWidth: 4
# # 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true
# 是否自动分析指针的对齐方式
# -- true - 自动分析并使用指针的对齐方式,若无法分析,则使用 PointerAlignment
# -- false - 不自动分析
# DerivePointerAlignment: true
# 是否禁用格式化
DisableFormat: false
# ExperimentalAutoDetectBinPacking: false
# 是否自动修正命名空间的结束注释
# -- true - 在短的命名空间尾部,自动添加或修改错误的命名空间结束注释
# -- false - 不自动修正
FixNamespaceComments: true
# foreach 循环
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
# 多个 include 块(有空行分隔的include)排序时的分组规则
# -- Preserve - 保留原有的块分隔,各自排序
# -- Merge - 将所有的块视为同一个,然后进行排序
# -- Regroup - 将所有的块视为同一个进行排序,然后按照 IncludeCategories 的规则进行分组
IncludeBlocks: Preserve
# IncludeCategories:
# - Regex: '^<ext/.*\.h>'
# Priority: 2
# - Regex: '^<.*\.h>'
# Priority: 1
# - Regex: '^<.*'
# Priority: 2
# - Regex: '.*'
# Priority: 3
# IncludeIsMainRegex: '([-_](test|unittest))?$'
# # 缩进case标签
# -- true - case 不与 switch 对齐
# -- false - case 和 switch 对齐
IndentCaseLabels: true
# 预处理命令(#if\#ifdef\#endif等)的缩进规则
# -- None - 不进行缩进
# -- AfterHash - 在前导'#'后缩进,'#'放在最左侧,之后的语句参与缩进
# -- BeforeHash - 在前导'#'前进行缩进
IndentPPDirectives: AfterHash
# # 函数返回类型换行时,缩进函数声明或函数定义的函数名
# IndentWrappedFunctionNames: false
# JavaScript 中的字符串引号规则
# -- Leave - 保持原样
# -- Single - 全部使用单引号
# -- Double - 全部使用双引号
JavaScriptQuotes: Leave
# 是否在 JavaScript 的 import/export 语句后换行
# JavaScriptWrapImports: true
# # 保留在块开始处的空行
# -- true - 保留块起始的空行
# -- false - 删除块起始的空行
KeepEmptyLinesAtTheStartOfBlocks: true
# 用于识别宏定义型块起始的正则表达式
# MacroBlockBegin: ''
# 用于识别宏定义型块结束的正则表达式
# MacroBlockEnd: ''
# # 连续空行的最大数量
MaxEmptyLinesToKeep: 1
# # 命名空间内部的缩进规则
# -- None - 都不缩进
# -- Inner - 只缩进嵌套的命名空间内容
# -- All - 缩进所有命名空间内容
NamespaceIndentation: Inner
# Objective-C 相关配置
# ObjCBlockIndentWidth: 2
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: false
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 1
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakString: 1000
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 200
# # 指针和引用(*和&)的对齐规则
# -- Left - * 靠近左侧
# -- Right - * 靠近右侧
# -- Middle - * 放在中间
# NOTE : 在 SpaceAroundPointerQualifiers 为 Default,
# 且 DerivePointerAlignment 失效后启用
PointerAlignment: Right
# RawStringFormats:
# - Delimiter: pb
# Language: TextProto
# BasedOnStyle: google
# # 重新排版注释
ReflowComments: false
# # 重新排序#include
# -- Never - 不进行排序
# -- CaseSensitive - 排序时大小写敏感
# -- CaseInsensitive - 排序时大小写不敏感
SortIncludes: false
# java 中静态 import 的排序规则
# -- Before - 静态放在非静态前方
# -- After - 静态放在非静态后方
# SortJavaStaticImport: Before
# # 重新排序using声明
SortUsingDeclarations: false
# # 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false
# # 在Template关键字后面添加空格
SpaceAfterTemplateKeyword: true
# # 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true
# # 在 C++11 的初始化列表前加空格
# SpaceBeforeCpp11BracedList: true
# 在构造函数的初始化冒号":"前加空格
# SpaceBeforeCtorInitializerColon: true
# 在构造函数的继承冒号":"前加空格
# SpaceBeforeInheritanceColon: true
# 小括号"()"前加空格的规则
# -- Never - 从不加空格
# -- ControlStatements - 只在控制语句(for/if/while...)时加空格
# -- ControlStatementsExceptForEachMacros - 类型 ControlStatements,只是不再 ForEach 后加空格
# -- Always - 总是添加空格
# -- NonEmptyParentheses - 类似 Always,只是不再空白括号前加空格
SpaceBeforeParens: ControlStatements
# 在 for 循环的冒号":"前加空格
# SpaceBeforeRangeBasedForLoopColon: true
# # 在空白的小括号"()"中添加空格
SpaceInEmptyParentheses: false
# # 在行尾的注释前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1
# # 在尖括号的"<"后,和">"前添加空格
SpacesInAngles: false
# # 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true
# # 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false
# # 在圆括号的"("后,和")"前添加空格
SpacesInParentheses: false
# 在中括号中加空格
# 当中括号内没有数据时,不受本规则影响(如空白的lambda 捕获表、不定长度的数组声明)
SpacesInSquareBrackets: false
# 语言标准: Cpp03, Cpp11, Auto
Standard: Auto
# # tab宽度
TabWidth: 4
# # 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never
---
---
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: LLVM
Language: Cpp
# this style configuration is based on google style configuration.
# The following configuration is different from the basic configuration.
# 缩进宽度
IndentWidth: 4
# 访问权限说明符(public/private等)的偏移
AccessModifierOffset: -4
# # 开括号(开圆括号、尖括号、方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
# AlignAfterOpenBracket: Align
# # 连续赋值时,对齐所有等号
# AlignConsecutiveAssignments: false
# # 连续声明时,对齐所有声明的变量名
# AlignConsecutiveDeclarations: false
# 反斜杆换行的对齐方式
# -- DontAlign - 不进行对齐
# -- Left - 反斜杠靠左对齐
# -- Right - 反斜杠靠右对齐
# AlignEscapedNewlines: Right
# 二元、三元表达式的对齐方式(当表达式需要占用多行时)
# -- DontAlign - 不进行对齐
# -- Align - 从操作符开始对齐
# -- AlignAfterOperator - 从操作数开始对齐
AlignOperands: true
# # 是否对齐行尾注释
# AlignTrailingComments: true
# # 函数声明的所有参数在放在下一行
# AllowAllParametersOfDeclarationOnNextLine: false
# # 是否允许短的代码块放在同一行
# AllowShortBlocksOnASingleLine: false
# # 短的case标签和语句放在同一行
# AllowShortCaseLabelsOnASingleLine: true
# # 短的函数放在同一行
# -- None - 不把短的函数放在同一行
# -- InlineOnly - 只把类内的内联函数放在同一行,全局的空函数不放在同一行
# -- Empty - 只把空的函数放在同一行
# -- Inline - 把类内的内联函数放在同一行,全局的空函数不放在同一行
# -- All - 都允许放在同一行
AllowShortFunctionsOnASingleLine: InlineOnly
# # 短的if语句保持在同一行
# AllowShortIfStatementsOnASingleLine: true
# # 短的循环保持在同一行
# AllowShortLoopsOnASingleLine: true
# # 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数),
# # AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
# AlwaysBreakAfterReturnType: None
# # 总是在多行string字面量前换行
# AlwaysBreakBeforeMultilineStrings: true
# # 总是在template声明后换行
AlwaysBreakTemplateDeclarations: true
# # 函数调用时,参数的放置规则
# -- false - 参数要么放在同一行,要么每个参数占用一行
# -- true - 不做强制要求
# BinPackArguments: true
# 函数声明、定义时,参数的放置规则
# -- false - 参数要么放在同一行,要么每个参数占用一行
# -- true - 不做强制要求
# BinPackParameters: true
# 大括号放置风格
# -- Attach - 大括号紧随前方内容,放在同一行
# -- Linux - 与 Attach 类似,除了 函数、命名空间、类定义 的大括号放在下一行
# -- Mozilla - 与 Attach 类似,除了枚举、函数、结构(class\struct\union)的大括号放在下一行
# -- Stroustrup - 与 Attach 类似,但函数定义前、catch前方、else前方的"{}"放在单独一行
# -- Allman - 总是换行
# -- Whitesmiths - 类似 Allman,但"{}"和内部的语句对齐到同样位置
# -- GNU - 总是换行,但在控制语句后的"{}"总是对齐到下一个位置
# -- WebKit - 与 Attach 类似,但在函数定义前换行
# -- Custom - 依赖 BraceWrapping
# 注:这里认为语句块也属于函数
BreakBeforeBraces: Attach
# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
# class定义后面
AfterClass: false
# 控制语句后面
AfterControlStatement: false
# enum定义后面
AfterEnum: false
# 函数定义后面
AfterFunction: true
# 命名空间定义后面
AfterNamespace: true
# ObjC定义后面
AfterObjCDeclaration: false
# struct定义后面
AfterStruct: false
# union定义后面
AfterUnion: false
# extern之后
AfterExternBlock: true
# catch之前
BeforeCatch: false
# else之前
BeforeElse: false
# 继续缩进大括号
IndentBraces: false
# 分离空函数
# # 当空白函数的"{}"和函数名称不需要放在同一行时,是否拆分函数体
SplitEmptyFunction: true
# 分离空语句
# # 当空白结构(class\struct\union)的"{}"需要放在单独的行时,是否拆分"{}"
SplitEmptyRecord: true
# 分离空命名空间
# # 当空白的命名空间的"{}"需要放在单独的行时,是否拆分"{}"
SplitEmptyNamespace: true
# # 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: NonAssignment
# BreakBeforeInheritanceComma: false
# # 在三元运算符前换行
# 当三元表达式不能放在同一行时,是否在三元操作符前方换行
# -- true - 操作符位于新行的首部
# -- false - 操作符位于上一行的尾部
BreakBeforeTernaryOperators: true
# BreakConstructorInitializersBeforeComma: false
# # 构造函数初始化列表分割方式
# -- BeforeColon - 在冒号 ':' 前方分割,冒号位于行首,逗号','位于行尾
# -- BeforeComma - 在冒号和逗号前方分割,冒号和逗号都位于行首,并且对齐
# -- AfterColon - 在冒号和逗号后方分割,冒号和逗号位于行尾
BreakConstructorInitializers: BeforeColon
# # 是否在每个java注解后方换行
# BreakAfterJavaFieldAnnotations: false
# # 是否分割过长的字符串
# BreakStringLiterals: false
# # 每行字符长度的限制,0表示没有限制
ColumnLimit: 100
# # 用于匹配注释信息的正则表达式,被匹配的行不会做任何修改
# CommentPragmas: '^ IWYU pragma:'
# 是否压缩紧接的命名空间
# -- true - 将紧跟的命名空间放在同一行
# -- false - 每个命名空间位于新的一行
CompactNamespaces: false
# # 构造函数的初始化列表要么都在同一行,要么都各自一行
# -- true - 如果可能,初始化列表放在同一行;如果不满足长度选择,则每个单独放一行
# -- false - 初始化列表可以随意放置
# ConstructorInitializerAllOnOneLineOrOnePerLine: false
# # 构造函数的初始化列表和基类集成列表的对齐宽度
ConstructorInitializerIndentWidth: 4
# # 延续语句的对齐宽度
ContinuationIndentWidth: 4
# # 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true
# 是否自动分析指针的对齐方式
# -- true - 自动分析并使用指针的对齐方式,若无法分析,则使用 PointerAlignment
# -- false - 不自动分析
# DerivePointerAlignment: true
# 是否禁用格式化
DisableFormat: false
# ExperimentalAutoDetectBinPacking: false
# 是否自动修正命名空间的结束注释
# -- true - 在短的命名空间尾部,自动添加或修改错误的命名空间结束注释
# -- false - 不自动修正
FixNamespaceComments: true
# foreach 循环
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
# 多个 include 块(有空行分隔的include)排序时的分组规则
# -- Preserve - 保留原有的块分隔,各自排序
# -- Merge - 将所有的块视为同一个,然后进行排序
# -- Regroup - 将所有的块视为同一个进行排序,然后按照 IncludeCategories 的规则进行分组
IncludeBlocks: Preserve
# IncludeCategories:
# - Regex: '^<ext/.*\.h>'
# Priority: 2
# - Regex: '^<.*\.h>'
# Priority: 1
# - Regex: '^<.*'
# Priority: 2
# - Regex: '.*'
# Priority: 3
# IncludeIsMainRegex: '([-_](test|unittest))?$'
# # 缩进case标签
# -- true - case 不与 switch 对齐
# -- false - case 和 switch 对齐
IndentCaseLabels: true
# 预处理命令(#if\#ifdef\#endif等)的缩进规则
# -- None - 不进行缩进
# -- AfterHash - 在前导'#'后缩进,'#'放在最左侧,之后的语句参与缩进
# -- BeforeHash - 在前导'#'前进行缩进
IndentPPDirectives: AfterHash
# # 函数返回类型换行时,缩进函数声明或函数定义的函数名
# IndentWrappedFunctionNames: false
# JavaScript 中的字符串引号规则
# -- Leave - 保持原样
# -- Single - 全部使用单引号
# -- Double - 全部使用双引号
JavaScriptQuotes: Leave
# 是否在 JavaScript 的 import/export 语句后换行
# JavaScriptWrapImports: true
# # 保留在块开始处的空行
# -- true - 保留块起始的空行
# -- false - 删除块起始的空行
KeepEmptyLinesAtTheStartOfBlocks: true
# 用于识别宏定义型块起始的正则表达式
# MacroBlockBegin: ''
# 用于识别宏定义型块结束的正则表达式
# MacroBlockEnd: ''
# # 连续空行的最大数量
MaxEmptyLinesToKeep: 1
# # 命名空间内部的缩进规则
# -- None - 都不缩进
# -- Inner - 只缩进嵌套的命名空间内容
# -- All - 缩进所有命名空间内容
NamespaceIndentation: Inner
# Objective-C 相关配置
# ObjCBlockIndentWidth: 2
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: false
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 1
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakString: 1000
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 200
# # 指针和引用(*和&)的对齐规则
# -- Left - * 靠近左侧
# -- Right - * 靠近右侧
# -- Middle - * 放在中间
# NOTE : 在 SpaceAroundPointerQualifiers 为 Default,
# 且 DerivePointerAlignment 失效后启用
PointerAlignment: Right
# RawStringFormats:
# - Delimiter: pb
# Language: TextProto
# BasedOnStyle: google
# # 重新排版注释
ReflowComments: false
# # 重新排序#include
# -- Never - 不进行排序
# -- CaseSensitive - 排序时大小写敏感
# -- CaseInsensitive - 排序时大小写不敏感
SortIncludes: false
# java 中静态 import 的排序规则
# -- Before - 静态放在非静态前方
# -- After - 静态放在非静态后方
# SortJavaStaticImport: Before
# # 重新排序using声明
SortUsingDeclarations: false
# # 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false
# # 在Template关键字后面添加空格
SpaceAfterTemplateKeyword: true
# # 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true
# # 在 C++11 的初始化列表前加空格
# SpaceBeforeCpp11BracedList: true
# 在构造函数的初始化冒号":"前加空格
# SpaceBeforeCtorInitializerColon: true
# 在构造函数的继承冒号":"前加空格
# SpaceBeforeInheritanceColon: true
# 小括号"()"前加空格的规则
# -- Never - 从不加空格
# -- ControlStatements - 只在控制语句(for/if/while...)时加空格
# -- ControlStatementsExceptForEachMacros - 类型 ControlStatements,只是不再 ForEach 后加空格
# -- Always - 总是添加空格
# -- NonEmptyParentheses - 类似 Always,只是不再空白括号前加空格
SpaceBeforeParens: ControlStatements
# 在 for 循环的冒号":"前加空格
# SpaceBeforeRangeBasedForLoopColon: true
# # 在空白的小括号"()"中添加空格
SpaceInEmptyParentheses: false
# # 在行尾的注释前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1
# # 在尖括号的"<"后,和">"前添加空格
SpacesInAngles: false
# # 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true
# # 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false
# # 在圆括号的"("后,和")"前添加空格
SpacesInParentheses: false
# 在中括号中加空格
# 当中括号内没有数据时,不受本规则影响(如空白的lambda 捕获表、不定长度的数组声明)
SpacesInSquareBrackets: false
# 语言标准: Cpp03, Cpp11, Auto
Standard: Auto
# # tab宽度
TabWidth: 4
# # 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never
---

64
.clang-tidy

@ -1,33 +1,33 @@
Checks: "
-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
performance-*,
readability-*,
-readability-braces-around-statements,
-readability-magic-numbers,
-readability-identifier-length,
misc-*,
-misc-non-private-member-variables-in-classes,
clang-analyzer-*,
clang-diagnostic-*,
cppcoreguidelines-*,
modernize-*,
performance-unnecessary-value-param,
modernize-pass-by-value,
-modernize-use-trailing-return-type,
-cppcoreguidelines-magic-numbers,
-cppcoreguidelines-init-variables,
-cppcoreguidelines-pro-type-member-init,
"
CheckOptions:
- key: misc-non-private-member-variables-in-classes.Level
value: None
WarningsAsErrors: ''
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
Checks: "
-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
performance-*,
readability-*,
-readability-braces-around-statements,
-readability-magic-numbers,
-readability-identifier-length,
misc-*,
-misc-non-private-member-variables-in-classes,
clang-analyzer-*,
clang-diagnostic-*,
cppcoreguidelines-*,
modernize-*,
performance-unnecessary-value-param,
modernize-pass-by-value,
-modernize-use-trailing-return-type,
-cppcoreguidelines-magic-numbers,
-cppcoreguidelines-init-variables,
-cppcoreguidelines-pro-type-member-init,
"
CheckOptions:
- key: misc-non-private-member-variables-in-classes.Level
value: None
WarningsAsErrors: ''
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
FormatStyle: file

2
CMakeLists.txt

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25)
project(PMClassifier)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
include_directories(./include)

3
include/common.hpp

@ -1,12 +1,11 @@
#pragma once
#include "real.hpp"
#include <limits>
#include <numbers>
#include <cmath>
enum PtBoundaryRelation { Inside = -1, OnBoundary, Outside = 1 };
const real PI = std::numbers::pi;
const real PI = 3.141592653589793238462643383279502884Q;
const real PI2 = 2 * PI;
const real EPS = std::numeric_limits<real>::epsilon() * 1e2;
const real EPS_END_PARAM = std::numeric_limits<real>::epsilon() * 1e3;

81
include/line.hpp

@ -10,8 +10,6 @@
#include <iostream>
#include <limits.h>
#include <limits>
#include <memory>
#include <numbers>
#include <vector>
// class ILineParam {
@ -45,17 +43,17 @@ public:
ILine(ILine &&) = default;
ILine &operator=(ILine &&) = default;
virtual Vec3 eval(real t) = 0;
virtual Vec3 eval(real t) const = 0;
virtual Vec3 der1(real t) = 0;
virtual Vec3 der1(real t) const = 0;
virtual Vec3 der2(real t) = 0;
virtual Vec3 der2(real t) const = 0;
virtual Vec3 tangent(real t) = 0;
virtual Vec3 tangent(real t) const = 0;
virtual Vec3 normal(real t, const Vec3 &tan = -1.) = 0;
virtual Vec3 normal(real t, const Vec3 &tan = -1.) const = 0;
virtual ClosestDescOnSeg getClosestParam(const Vec3 &p) = 0;
virtual ClosestDescOnSeg getClosestParam(const Vec3 &p) const = 0;
[[nodiscard]] virtual bool isEndParam(real t) const = 0;
};
@ -96,7 +94,7 @@ struct AA {
void print() const { std::cout << a << " " << b << std::endl; }
};
const real DISC_ARC_ANGLE = std::numbers::pi * 0.125;
const real DISC_ARC_ANGLE = PI * 0.125;
class Polyline : public ILine {
public:
@ -105,11 +103,12 @@ public:
_refNormal(refNormal.normalize()) {
assert(_points.size() >= 2);
if (closed) {
assert(_points.size() == _points.size());
assert(_points.size() == _bugles.size());
} else {
assert(_points.size() - 1 == _points.size());
assert(_points.size() - 1 == _bugles.size());
}
circularArcs.resize(_bugles.size());
initSegInfo();
}
[[nodiscard]] const Pt3Array &getPoints() const { return _points; }
@ -139,12 +138,12 @@ public:
}
}
Vec3 eval(real t) override {
if (circularArcs.empty())
initSegInfo();
Vec3 eval(real t) const override {
// if (circularArcs.empty())
// initSegInfo();
int seg = static_cast<int>(t);
if (isEqual(_bugles[seg], 0)) {
return _points[seg] + (_points[(seg + 1) % _bugles.size()] - _points[seg]) * (t - seg);
return _points[seg] + (_points[(seg + 1) % _points.size()] - _points[seg]) * (t - seg);
}
real tOnSeg = t - seg;
const auto &arc = circularArcs[seg];
@ -152,12 +151,10 @@ public:
return arc.center + arc.radius * (arc.u * std::cos(phi) + arc.v * std::sin(phi));
}
Vec3 der1(real t) override {
if (circularArcs.empty())
initSegInfo();
Vec3 der1(real t) const override {
int seg = static_cast<int>(t);
if (isEqual(_bugles[seg], 0)) {
return _points[(seg + 1) % _bugles.size()] - _points[seg];
return _points[(seg + 1) % _points.size()] - _points[seg];
}
real tOnSeg = t - seg;
const auto &arc = circularArcs[seg];
@ -165,21 +162,22 @@ public:
return arc.radius * (arc.u * -std::sin(phi) + arc.v * std::cos(phi));
}
Vec3 der2(real t) override {
if (circularArcs.empty())
initSegInfo();
Vec3 der2(real t) const override {
int seg = static_cast<int>(t);
assert(!isEqual(_bugles[seg], 0));
if (isEqual(_bugles[seg], 0)) {
int aaa = 1;
}
// assert(!isEqual(_bugles[seg], 0));
real tOnSeg = t - seg;
const auto &arc = circularArcs[seg];
real phi = tOnSeg * arc.theta;
return -arc.radius * (arc.u * std::cos(phi) + arc.v * std::cos(phi));
}
Vec3 tangent(real t) override { return der1(t).normalize(); }
Vec3 tangent(real t) const override { return der1(t).normalize(); }
// TODO: 试试https://www.jianshu.com/p/9e4877e3965e算出来的结果
Vec3 normal(real t, [[maybe_unused]] const Vec3 &tan = -1.) override {
if (!isEqual(_bugles[static_cast<int>(t)], 0)) {
Vec3 normal(real t, [[maybe_unused]] const Vec3 &tan = -1.) const override {
if (isEqual(_bugles[static_cast<int>(t)], 0)) {
return -circularArcs[static_cast<int>(t)].inCircleDir;
}
// 只有对于圆弧这样的特殊曲线是这样
@ -247,9 +245,7 @@ public:
// return {closestParam, closestDis};
// }
ClosestDescOnSeg getClosestParam(const Vec3 &p) override {
if (circularArcs.empty())
initSegInfo();
ClosestDescOnSeg getClosestParam(const Vec3 &p) const override {
ClosestDescOnSeg closestDes{};
for (int i = 0; i < _bugles.size(); ++i) {
const Vec3 &a = _points[i];
@ -280,7 +276,7 @@ public:
real cosTheta = (oa).dot(oClsPt) / R2;
real theta = std::acos(cosTheta); // [0, pi]
if ((oa.cross(oClsPt)).dot(_refNormal) < 0) {
theta = 2 * std::numbers::pi - theta;
theta = PI2 - theta;
}
closestDes.t = i + theta / arc.theta;
}
@ -370,24 +366,24 @@ public:
// _k = _4pi2r / (advancePerRound * advancePerRound + _4pi2r * _r);
_arcDeltaMaxFactor = _4pi2r / (advancePerRound * advancePerRound + _4pi2r * _r) * ONE_EIGHT;
}
Vec3 eval(real t) override {
Vec3 eval(real t) const override {
real theta = _frequency * t;
return _axisStart + _axisDir * t + (_u * std::cos(theta) + _v * std::sin(theta)) * _r;
};
Vec3 der1(real param) override {
Vec3 der1(real param) const override {
real theta = _frequency * param;
return _axisDir + _2pir_p * (_v * std::cos(theta) - _u * std::sin(theta));
};
Vec3 der2(real param) override {
Vec3 der2(real param) const override {
real theta = _frequency * param;
return -_4pi2r_p2 * (_u * std::cos(theta) + _v * std::sin(theta));
};
Vec3 tangent(real t) override { return der1(t).normalize(); }
Vec3 tangent(real t) const override { return der1(t).normalize(); }
Vec3 normal(real t, const Vec3 &tan = -1.) override {
Vec3 normal(real t, const Vec3 &tan = -1.) const override {
Vec3 der2Vec = this->der2(t);
if (tan == -1.) {
Vec3 realTan = tangent(t);
@ -396,7 +392,7 @@ public:
return (der2Vec - der2Vec.dot(tan) * tan).normalize();
}
ClosestDescOnSeg getClosestParam(const Vec3 &p) override {
ClosestDescOnSeg getClosestParam(const Vec3 &p) const override {
// discretization and traversal
real startT = 0;
real endT = SEG_T;
@ -490,7 +486,6 @@ public:
ArcLine(const Vec3 &a, const Vec3 &b, real bugle, const Vec3 &refNormal)
// : _a(a), _b(b), _bugle(bugle), _refNormal(refNormal.normalize()) {}
: Polyline(Pt3Array{{a, b}}, std::vector<real>{bugle}, refNormal, false) {}
ClosestDescOnSeg getClosestParam(const Vec3 &p) override { return {}; };
[[nodiscard]] const std::vector<real> &getBugles() const = delete;
[[nodiscard]] const real &getBugle() const { return _bugles[0]; }
@ -502,15 +497,15 @@ public:
class PolynomialLine : public ILine {
public:
Vec3 eval(real t) override { return {}; };
Vec3 eval(real t) const override { return {}; };
Vec3 der1(real t) override { return {}; };
Vec3 der1(real t) const override { return {}; };
Vec3 der2(real t) override { return {}; };
Vec3 der2(real t) const override { return {}; };
Vec3 tangent(real t) override { return {}; }
Vec3 tangent(real t) const override { return {}; }
Vec3 normal(real t, const Vec3 &tan = -1.) override { return {}; }
Vec3 normal(real t, const Vec3 &tan = -1.) const override { return {}; }
ClosestDescOnSeg getClosestParam(const Vec3 &p) override { return {}; };
ClosestDescOnSeg getClosestParam(const Vec3 &p) const override { return {}; };
};

20
include/solid.hpp

@ -19,7 +19,7 @@ public:
ISolid(ISolid &&) = default;
ISolid &operator=(ISolid &&) = default;
virtual real sdf(const Vec3 &p) = 0;
virtual real sdf(const Vec3 &p) const = 0;
};
inline Vec2 get2DRepOf3DPt(const Vec3 &pt3D, const Vec3 &u, const Vec3 &v, const Vec3 &localO) {
Vec3 OP = pt3D - localO;
@ -74,10 +74,10 @@ public:
for (int j = 0; j < segCount; ++j) {
// TODO:
_localProfiles2D[i][j] =
get2DRepOf3DPt(profile.getPoints()[j] - q, normal, _biNormalStartPt, q);
get2DRepOf3DPt(profile.getPoints()[j], normal, _biNormalStartPt, q);
auto &arc2d = _localArcs2d[i][j];
const auto &arc3d = profile.getCircularArcs()[j];
arc2d.center = get2DRepOf3DPt(arc3d.center - q, normal, _biNormalStartPt, q);
arc2d.center = get2DRepOf3DPt(arc3d.center, normal, _biNormalStartPt, q);
arc2d.inCircleDir = get2DRepOf3DDir(arc3d.inCircleDir, normal, _biNormalStartPt);
arc2d.radius = arc3d.radius;
arc2d.theta = arc3d.theta;
@ -86,7 +86,7 @@ public:
}
}
real sdf(const Vec3 &p) override {
real sdf(const Vec3 &p) const override {
ClosestDescOnSeg closestDescToAxis = _axis.getClosestParam(p);
// TNB coordinate system
auto t = closestDescToAxis.t;
@ -118,9 +118,9 @@ public:
}
private:
virtual std::array<Vec3, 3> getTBN(const Vec3 &p, const Vec3 &q, real t) = 0;
virtual std::array<Vec3, 3> getTBN(const Vec3 &p, const Vec3 &q, real t) const = 0;
inline ClosestDescOnSeg disProfile2D(const Vec2 &p2D) {
inline ClosestDescOnSeg disProfile2D(const Vec2 &p2D) const {
ClosestDescOnSeg closestDescToProfile{};
for (int i = 0; i < _localArcs2d.size(); ++i) {
ClosestDescOnSeg closestDescTemp = disLoop2D(p2D, _localProfiles2D[i], _localArcs2d[i]);
@ -131,7 +131,7 @@ private:
return closestDescToProfile;
}
inline PtBoundaryRelation pmcProfile2d(const Vec2 &p2D) {
inline PtBoundaryRelation pmcProfile2d(const Vec2 &p2D) const {
// PMC
for (int i = 0; i < _localArcs2d.size(); ++i) {
PtBoundaryRelation relationTmp = pmcLoop2d(p2D, _localProfiles2D[i], _localArcs2d[i]);
@ -205,7 +205,7 @@ private:
for (int i = 0; i < segCount; ++i) {
const Vec2 &a = loop2D[i];
const Vec2 &b = loop2D[(i + 1) % segCount];
assert(isPointOnSegment(p, a, b));
assert(!isPointOnSegment(p, a, b));
// if (isPointOnSegment(p2D, a, b))
// {
// onSegIdx = i;
@ -327,7 +327,7 @@ public:
assert(_biNormalStartPt.isParallel(_axis.getRefNormal()));
}
std::array<Vec3, 3> getTBN(const Vec3 &p, const Vec3 &q, real t) override {
std::array<Vec3, 3> getTBN(const Vec3 &p, const Vec3 &q, real t) const override {
if (!_axis.isEndParam(t) && std::abs(t - std::round(t)) < EPS) {
// 衔接点处(注意排除断点处)
// p到圆弧平面的投影
@ -387,7 +387,7 @@ public:
: IExtrudedSolidBase(std::move(profiles), std::move(axis), rScale) {}
std::array<Vec3, 3> getTBN([[maybe_unused]] const Vec3 &a, [[maybe_unused]] const Vec3 &b,
real t) override {
real t) const override {
Vec3 tangent = _axis.tangent(t);
Vec3 normal = _axis.normal(t);
return {tangent, normal, tangent.cross(normal)};

26
include/vec.hpp

@ -5,9 +5,10 @@
#include <cmath>
#include <array>
#include <assert.h>
#include <cstddef>
#include <ostream>
#include <vector>
#include <stdexcept>
#include <concepts>
template <typename Derived, size_t N>
class VecBase {
@ -110,6 +111,16 @@ public:
return true;
}
friend std::ostream& operator<<(std::ostream& os, const VecBase& vec) {
os << "Vec" << N << "(";
for (size_t i = 0; i < N; ++i) {
os<<vec[i];
if (i<N-1) os<<", ";
}
os<<")";
return os;
}
Derived operator-() const { return static_cast<Derived>(*this * -1); }
};
@ -181,19 +192,6 @@ public:
using Pt3Array = std::vector<Vec3>;
using Pt2Array = std::vector<Vec2>;
template <typename T>
concept IsVec2 = requires(T t) {
t.x();
t.y();
};
template <typename T>
concept IsVec3 = requires(T t) {
t.x();
t.y();
t.z();
};
//class Vec3 {
//public:
// real x, y, z;

26
main.cpp

@ -1,18 +1,20 @@
#include <iostream>
#include "line.hpp"
#include "solid.hpp"
// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
int main() {
Polyline axis{{}, {}, Vec3()};
ExtrudedSolidPolyline a({axis}, axis);
const Vec3 queryP = Vec3();
auto f = a.sdf(queryP);
void testPrint(const ISolid &solid, const Vec3 &queryPt) {
std::cout << "sdf on " << queryPt << " = " << solid.sdf(queryPt) << std::endl;
}
return 0;
void caseCyliner() {
Polyline profile{{{-1, 0., 0}, {1., 0., 0.}}, {1., 1.}, {0, 0, -1}, true};
Polyline axis{{{0, 0, 0}, {0, 0, 2}}, {0}, {0, 1, 0}};
ExtrudedSolidPolyline extrusion({profile}, axis);
testPrint(extrusion, {1, 2, 1});
testPrint(extrusion, {1, 2, -1});
}
// TIP See CLion help at <a
// href="https://www.jetbrains.com/help/clion/">jetbrains.com/help/clion/</a>.
// Also, you can try interactive lessons for CLion by selecting
// 'Help | Learn IDE Features' from the main menu.
int main() {
caseCyliner();
return 0;
}
Loading…
Cancel
Save