diff --git a/cg/geometry.md b/cg/geometry.md index 811201b..737614f 100644 --- a/cg/geometry.md +++ b/cg/geometry.md @@ -9,23 +9,10 @@ - [Rigid Geometric Algebra -- RGA](https://rigidgeometricalgebra.org/wiki/index.php?title=Main_Page) - [A C++ library that implements much of this math is available under the MIT license on GitHub](https://github.com/EricLengyel/Terathon-Math-Library) -## Isogeometric Anylasis -CAD/CAE领域中的等几何分析,等几何分析目前是被视作CAE最具革命性的突破。 - -CAD的开花理论, -由Bezier Spline,推广未B样条B-Spline曲线和曲面,目前非均匀有理B样条曲面成为工业标准,2000Tom Sederberg博士进一步推广为T样条曲面。 - -在传统NURBS(non-uniform rational B-Spline surface)上,节点细化是全局的,即我们在一处添加节点,都需要保持节点构成四边形网格,因此需要沿着曲面上的一条曲线添加节点。很多时候,我们只希望局部改变NURBS的节点结构,不希望影响全局 - -几乎所有的物理定律都是由偏微分方程来描述。各种物理现象的数值模拟等价于在几何模型上求解各种偏微分方程。计算机辅助工程 CAE(Computer Aided Engineering)的核心就是在几何体上进行多物理场数值模拟。1940年代由克朗(Courant)等应用数学家发展起来的有限元方法(Finite Element Method)是CAE中最为普遍的方法,我国的数学家冯康也独立地奠定了有限元的理论基础。 - -传统的有限元方法是将几何体进行三角剖分,然后在三角剖分上建立基函数。有限元算法中,我们在每个单元(四面体)上计算刚度矩阵,然后再组装成整体的刚度矩阵。传统的CAD工业中,所有的几何体都被表示成NURBS曲面;而在传统的CAE工业中,几何体被表示为网格剖分,很多时候是三角剖分。将CAD模型转换成三角剖分是整个数字模拟仿真流程中最为耗时、耗费计算资源的步骤,一般占所有计算时间的以上。同时,网格离散会带来几何误差,这是影响仿真问题精度的一个关键因素。 - -2005年,Tom Hughes博士提出了等几何分析的思想(isogeometric analysis),核心是采用统一的样条语言来表达几何形状和物理场:利用平面NURBS参数曲面或者体NURBS参数体积作为计算域,计算单元为节点区间对应的曲面单元或者体单元;以NURBS基函数作为物理场的基函数(形函数),以控制顶点的物理数学分量作为未知变量。这样,形状几何与分析几何在同一样条空间,避免了数据交换;在精确CAD几何上进行仿真计算,避免了几何离散误差;在同样自由度下,达到较高计算精度,或者在同样的精度下,需要较少的自由度。同时,物理仿真保持了光滑性。从工程角度而言,等几何分析与传统的有限元方法兼容,等几何分析可以集成到现有的有限元环境之中。 - -虽然等几何分析具有很多传统方法无法比拟的优点,但是等几何分析并没有被工业界广泛采纳,核心在于传统CAD工业中的样条曲面无法满足等几何分析的要求。传统NURBS大量应用裁剪样条,裁剪样条无法分解成规则单元,需要重新构造;传统NURBS缺乏水密性,存在大量缝隙,因此有很多弥补缝隙的碎片样条,需要融合成整片样条;最为致命的问题是传统CAD模型只表达了几何体的边界曲面,而等几何分析需要将整个实体的内部也表达成样条。 +- [等几何技术](/cg/mesh/isogeometric.md) ## 参考 + - [代数几何小科普3:怎么知道方程(组)有解? ](https://blog.sciencenet.cn/blog-1646100-818073.html) - [Triangulate Efficient Triangulation Algorithm Suitable for Terrain Modelling or An Algorithm for Interpolating Irregularly-Spaced Data with Applications in Terrain Modelling](http://paulbourke.net/papers/triangulate/) - [多边形网格算法](http://paulbourke.net/geometry/polygonmesh/) @@ -34,3 +21,5 @@ CAD的开花理论, - [计算几何第四周:维诺图](https://zhuanlan.zhihu.com/p/33896575) - [Lattice学习笔记01:格的简介](https://zhuanlan.zhihu.com/p/161411204) - [How to make an infinite grid无限网格](http://asliceofrendering.com/scene%20helper/2020/01/05/InfiniteGrid/) + +- [Macad|3D is a free and open-source 3D construction program which implements easy-to-handle workflows specific to the model making hobbyist. Macad|3D is mainly based on the technologies .Net, C#, C++/CLI and OpenCASCADE Technology (OCCT). ](https://github.com/Macad3D/Macad3D) \ No newline at end of file diff --git a/cg/mesh/isogeometric.md b/cg/mesh/isogeometric.md new file mode 100644 index 0000000..1dbf7eb --- /dev/null +++ b/cg/mesh/isogeometric.md @@ -0,0 +1,24 @@ +# Isogeometric + +## Isogeometric Anylasis + +等几何分析始于Thomas Hughes教授参与关于从CAD模型创建有限元模型的研究。研究的要点表达了这样一个主题:尽管对网格生成进行了多年的研究,但CAD到Mesh创建问题依然是有效使用FEA(有限元分析)的重大瓶颈,对于复杂的工程设计来说,这个问题似乎越来越严重。 + +CAD/CAE领域中的等几何分析,等几何分析目前是被视作CAE最具革命性的突破。 + +CAD的开花理论, +由Bezier Spline,推广未B样条B-Spline曲线和曲面,目前非均匀有理B样条曲面成为工业标准,2000Tom Sederberg博士进一步推广为T样条曲面。 + +在传统NURBS(non-uniform rational B-Spline surface)上,节点细化是全局的,即我们在一处添加节点,都需要保持节点构成四边形网格,因此需要沿着曲面上的一条曲线添加节点。很多时候,我们只希望局部改变NURBS的节点结构,不希望影响全局 + +几乎所有的物理定律都是由偏微分方程来描述。各种物理现象的数值模拟等价于在几何模型上求解各种偏微分方程。计算机辅助工程 CAE(Computer Aided Engineering)的核心就是在几何体上进行多物理场数值模拟。1940年代由克朗(Courant)等应用数学家发展起来的有限元方法(Finite Element Method)是CAE中最为普遍的方法,我国的数学家冯康也独立地奠定了有限元的理论基础。 + +传统的有限元方法是将几何体进行三角剖分,然后在三角剖分上建立基函数。有限元算法中,我们在每个单元(四面体)上计算刚度矩阵,然后再组装成整体的刚度矩阵。传统的CAD工业中,所有的几何体都被表示成NURBS曲面;而在传统的CAE工业中,几何体被表示为网格剖分,很多时候是三角剖分。将CAD模型转换成三角剖分是整个数字模拟仿真流程中最为耗时、耗费计算资源的步骤,一般占所有计算时间的以上。同时,网格离散会带来几何误差,这是影响仿真问题精度的一个关键因素。 + +2005年,Tom Hughes博士提出了等几何分析的思想(isogeometric analysis),核心是采用统一的样条语言来表达几何形状和物理场:利用平面NURBS参数曲面或者体NURBS参数体积作为计算域,计算单元为节点区间对应的曲面单元或者体单元;以NURBS基函数作为物理场的基函数(形函数),以控制顶点的物理数学分量作为未知变量。这样,形状几何与分析几何在同一样条空间,避免了数据交换;在精确CAD几何上进行仿真计算,避免了几何离散误差;在同样自由度下,达到较高计算精度,或者在同样的精度下,需要较少的自由度。同时,物理仿真保持了光滑性。从工程角度而言,等几何分析与传统的有限元方法兼容,等几何分析可以集成到现有的有限元环境之中。 + +虽然等几何分析具有很多传统方法无法比拟的优点,但是等几何分析并没有被工业界广泛采纳,核心在于传统CAD工业中的样条曲面无法满足等几何分析的要求。传统NURBS大量应用裁剪样条,裁剪样条无法分解成规则单元,需要重新构造;传统NURBS缺乏水密性,存在大量缝隙,因此有很多弥补缝隙的碎片样条,需要融合成整片样条;最为致命的问题是传统CAD模型只表达了几何体的边界曲面,而等几何分析需要将整个实体的内部也表达成样条。 + +## 参考 + +- [等几何分析:从CAD到CAE的另一条路](https://mp.weixin.qq.com/s/ELmpeERmjF8Tou7OaS3P0A) \ No newline at end of file diff --git a/cg/threejs/grid.md b/cg/threejs/grid.md index 9e65705..feb7c04 100644 --- a/cg/threejs/grid.md +++ b/cg/threejs/grid.md @@ -4,6 +4,9 @@ - [Grids](https://godotshaders.com/snippet/grids/) - [Shadertoy: Grid Shader](https://worldofzero.com/posts/shadertoy-grid-shader/) - [Anti-Aliased Grid Shader](https://madebyevan.com/shaders/grid/) +- [How to achieve this material effect](https://discourse.threejs.org/t/how-to-achieve-this-material-effect-gif-image/1270/5) +- [Help with GridHelper - 3d coordinates](https://discourse.threejs.org/t/help-with-gridhelper-3d-coordinates/27336) +- [【源码】效果最好的网格Shader(迄今为止)](https://mp.weixin.qq.com/s/WJLwJMdvug98QWyFvV4e7A) ## 透视下 diff --git a/cg/threejs/index.md b/cg/threejs/index.md index 18b4da8..5297e23 100644 --- a/cg/threejs/index.md +++ b/cg/threejs/index.md @@ -1,5 +1,6 @@ # Threejs +- [问题集](/cg/threejs/use.md) - [乱记](/cg/threejs/threejs.md) - [Bump map](/cg/threejs/bumpmap.md) - [RayCaster](/cg/threejs/raycaster.md) diff --git a/cg/threejs/material.md b/cg/threejs/material.md index f13165f..83ab5b1 100644 --- a/cg/threejs/material.md +++ b/cg/threejs/material.md @@ -14,3 +14,13 @@ ```js ``` + +## fog + +The fog is a low-res RenderTarget, i use the height of the terrain (contribution inceasing by distance) and depth-buffer in the post shader to blend it with the atmosphere then, which is rendererd in a separate smaller target. So you basically render the fog in a mask to blend the scene with the background if any. + +For extending the default fog in the shaders without any postprocessing, you could use just the Y axis for the height if that already fits your needs. + +It would require some changes to use this with the THREE.EffectComposer, sorry. I’m using a custom framework on top of THREE, not the EfffectComposer for example. + +- [描述fog的一个思路应用,效果很好](https://discourse.threejs.org/t/tesseract-open-world-planetary-engine/1473/7) \ No newline at end of file diff --git a/cg/threejs/use.md b/cg/threejs/use.md new file mode 100644 index 0000000..57069cf --- /dev/null +++ b/cg/threejs/use.md @@ -0,0 +1,12 @@ +# 问题集 + +## 2024-7-19 + +接手公司项目时,使用他们的代码拷贝过来,产生了一个问题,就是渲染时牙龈边沿处的跳动。 + +牙龈根据牙齿数据来生成,目前存在牙龈穿过牙齿的现象。 + +### flickering + +渲染边沿出现跳动flicker的现象通常由几个常见的原因组成 +- z-fighting, 是webgl常见的问题,当两个表面或多个表面非常接近时,它们的深度值可能会重叠,导致在渲染时不知道切换那个表面,可以增加一个偏移来避免 \ No newline at end of file diff --git a/cg/tools/webgl.md b/cg/tools/webgl.md index fe5918f..fb717e1 100644 --- a/cg/tools/webgl.md +++ b/cg/tools/webgl.md @@ -1,4 +1,4 @@ -# WebGL +# [WebGL](https://registry.khronos.org/webgl/specs/latest/) - [threejs](https://threejs.org/) - [笔记](/cg/threejs/index.md) diff --git a/cpl/cplusplus.md b/cpl/cplusplus.md index 8d7ca35..dca9672 100644 --- a/cpl/cplusplus.md +++ b/cpl/cplusplus.md @@ -4,6 +4,8 @@ - [The C++ Core Guidelines are a collaborative effort led by Bjarne Stroustrup, much like the C++ language itself. They are the result of many person-years of discussion and design across a number of organizations.](https://github.com/isocpp/CppCoreGuidelines) - [The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the C++ Core Guidelines maintained by the Standard C++ Foundation. This repo contains Microsoft's implementation of GSL.](https://github.com/Microsoft/GSL) +- [TMP -- Template Meta Programming](/cpl/cpp/tmp.md) + ## 语言特性 ### 头文件 @@ -111,177 +113,6 @@ auto& p = spA; // 引用 auto p = spA; // 赋值 ``` - -## TMP(template metaprogramming) - -可参考的内容 - -- [关于C++TMP比较新的解释,叫全面些](https://www.3dgep.com/beginning-cpp-template-programming/) - -C++ allows template metaprogramming (TMP), a technique in which so-called templates are used by a compiler to generate temporary source code that is merged with the rest of the source code and then compiled - -最初模板编程是指控制代码生成来实现泛型,现在的模板更多指泛型约束、编译期计算、对类型做计算。 - -### **代码生成** - -C语言使用宏来实现泛型,原理就是替换宏参数,属于编译期的字符串拼接 -C语言没有模板是因为其语言抽象能力不够,相比C++的抽象能力模板template来实现泛型,宏的缺点都解决掉了。 - -### **对类型约束** - -函数重载是代码生成的一种方案,template就是先处理函数重载和隐式类型转换上花掉很多时间,报错也是一大推的根本原因。 - -标准库已经实现了很多的重载函数,这也是很多公司不使用标准库的原因吧 - -模板相对于宏的两个明显优势是 -- 自动类型推导 -- 隐式实例化 - -模板先推导参数,成功后就实例化,参数推导的报错提示很明显,实例化的报错提示就很复杂了,考虑标准库内部的实现与命名规则了。 - -类型约束就是在自动类型推导时减少匹配的工作,但约束语法时C++20才加入的.在此之前只能通过一种叫做SFINAE(Substitution failure is not an error)的技术来实现 -```c++ -struct A{}; -template -void print1(T x) { - std::cout << x << std::endl; -} -// before c++ 20 -template())> -void print2(T x) { - std::cout << x << std::endl; -} -// c++20 -template -requires (T x) { std::cout << x;} -void print2(T x) { - std::cout << x << std::endl; -} -``` -其他语言如C#和rust,对泛型的约束是通过where来表达的。 - -### **编译期计算** - -- 编译器对常量表达式的优化,如C函数的strlen,在C++中strlen是constexpr的 -- 为减少运行时开销,会提前算好一些数据,典型的例子是计算三角函数表这种常量表 - -C++的编译期计算有明确的语义保证,并且内嵌于语言中,能和其他部分交互,通过模板元编程进行编译期计算。从历史上看,TMP是一个偶然事件,在标准化C++语言的过程中发现它的模板系统恰好是图灵完备的,即原则上能够计算任何可计算的东西。 - -```c++ -template -struct Factorial { - enum { value = N * Factorial::value }; -}; -template<> -struct Factorial<0> { - enum { value = 1 }; -}; -std::cout << Factorial<5>::value << std::endl; -``` -这是C++11之前的,之后引入了constexpr关键字,可以表示编译期常量这一概念了 -```c++ -template -struct Factorial { - constexpr static int value = N * Factorial::value; -}; -template<> -struct Factorial<0> { - constexpr static int value = 1; -}; -``` -编译期的计算仍然使用模板来,这样的代码可读性较低,主要原因有 -- 模板参数只能是编译期常量,没有编译期变量的概念 -- 只能递归而不能循环计算 - -不能满足上面的编程语言也有,如Haskell没有变量和循环,但是它有强大的模式匹配.这就是constexpr关键字的引入问题 -```c++ -constexpr std::size_t factorial(std::size_t N) { - std::size_t result = 1; - for (std::size_t i=1;i<=N;++i) { - result *= i; - } - return result; -} -``` -这也是C++20之后几乎所有的标准库函数都是constexpr写的,比如编译期排序 -```c++ -constexpr auto sort(auto &&range) { - std::sort(std::begin(range), std::end(range)); - return range; -} -int main() { - constexpr auto arr = sort(std::array{1,3,4,2,5}); - for (auto i : arr) std::cout << i << std::endl; -} -``` -允许一个运行期函数前面直接加上constexpr关键字修饰,表示函数既可以在运行期调用,也可以在编译期调用.如果只想在编译期执行函数,使用关键字consteval来修饰. - -### **对类型做计算与编译期常量** - -在别的编程语言中类型大多是运行时的, C++允许在编译期对类型进行操作,但是类型不能作为普通值,只能作为模板参数。 - -使用std::variant时,需要从一个类型列表里(variant的模板参数)里面根据类型返回一个索引。 - -对类型做计算不得不用模板元编程,需要在编译期计算的同时实例化模板也得使用模板元编程。 - -把类型当成值的改动是完全不可接受的unacceptable的,这是静态语言的特性,而像rust这样是完全不支持的。但有取巧的方法,把类型映射到编译期确定的值,由于字符串是值,只对字符串进行计算。[C++23的typeid实现类似的映射,而不使用字符串映射。](https://godbolt.org/z/GK4KjqKMc) - -一个较新的编程语言[zig](https://ziglang.org/),它解决了上述的问题,支持编译期的变量,还支持类型作为一等公民(type as value)进行操作,得益于zig独特的comptime机制,被它标记的变量或代码块都在编译期执行的。 - -### 额外其他 - -- 首先满足正确性而非效率性 - -在一些数据范围小答案可以枚举,且时间上较为苛刻的,使用暴力枚举得出答案,将答案写入数组中。是指先生成一些数据可直接使用,减少运行的时间,对计算量大的可以这样优化。别人把特定计算放在一些文件中,部署出去的程序就跑得飞快,其他人还好奇为什么你的就这么快。 - -### NTTP - -NTTP-non-type template parameters -```c++ -template -struct string_literal { - // str is a reference to an array N of constant char - constexpr string_literal(char const (&str)[N]) { - std::copy_n(str, N, value); - } - char value[N]; -} -``` - -### 解耦 -模板用来解耦, -如果send函数的逻辑复制,需要抽离出来复用,这时候就可以考虑使用模板来解耦,还可以避免相互依赖问题 -```c++ -// -class Connection { -public: - void send() { - Helper helper(this); - helper.send(); - } -private: - friend class Helper; // 为了Helper访问私有对象 - std::string buf; -} -``` -```c++ -// helper.hpp -template -class Helper { -public: - Helper(T *t) : buf(t->buf) {} - void send() { std::cout << buf << std::endl; } -private: - std::string& buf; -} -// 因为模板类,需要填写模板参数,可以使用C++17的deduction guide来消除这个模板参数 -template -Helper(T *t) -> Helper; // deduction guide c++17 -``` - -[**Deduction Guide**推断指引,CTAD-class template argument deduction](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction)是C++17的新语法,当用类模板新建一个类时,希望编译器通过给定的规则创建与构造器传入参数对应的模板类型时, -给定的规则就是推断指引。当模板名称显示为推导类类型的类型说明符时,使用推断指引。 - ## 其他 ### Fiber @@ -325,7 +156,11 @@ base + sizeof * 偏移量,数组指针好像就是这样的,用*(a+b)访 ## 观点 -### 里缪 -#### 2024 +### 2024-7-22 +若是系统设计,DP 这些只能应对局部逻辑,还需要去了解一些掌握全局的常用架构,比如 EDA, LA, MA, MVC, SA…… +设计不是软件方面的事,感觉重要的还是问题拆解和组合能力,抽象分析能力,这些不是技术书能包含的 +能够反熵增的设计,就是好设计。能够一直起作用的设计,就是好设计。只要问题的范畴够小,再烂的设计,能满足需求也是好设计。 +抽象搞不好,逻辑就不清晰,只能写一大堆臃肿不明所以的代码 +### 2024 > 我看标准的这些机制设计和其他一些架构,其中很重要的一条原则就是追求一致性。不仅是美学上的追求,一旦符合这种一致性,系统本身就具备适应变化的能力,从而能够抵抗非连续性问题。一切本质的东西都很简单,且具有美感。设计之初就追求一致性,本质是一种多阶思维,看似麻烦,往往能够解决很多未能提前发现的问题。 >> 很多架构都是一致性的体现,一个项目之初如果不用架构,后面慢慢修改抽象,不断演进最后发现跟已有架构一个思路 \ No newline at end of file diff --git a/cpl/cpp/tmp.md b/cpl/cpp/tmp.md new file mode 100644 index 0000000..f4874b0 --- /dev/null +++ b/cpl/cpp/tmp.md @@ -0,0 +1,179 @@ +# Template Meta Programming + + +## [概念] +- [关于C++TMP比较新的解释,叫全面些](https://www.3dgep.com/beginning-cpp-template-programming/) + +C++ allows template metaprogramming (TMP), a technique in which so-called templates are used by a compiler to generate temporary source code that is merged with the rest of the source code and then compiled + +最初模板编程是指控制代码生成来实现泛型,现在的模板更多指泛型约束、编译期计算、对类型做计算。 + +### **代码生成** + +C语言使用宏来实现泛型,原理就是替换宏参数,属于编译期的字符串拼接 +C语言没有模板是因为其语言抽象能力不够,相比C++的抽象能力模板template来实现泛型,宏的缺点都解决掉了。 + +### **对类型约束** + +函数重载是代码生成的一种方案,template就是先处理函数重载和隐式类型转换上花掉很多时间,报错也是一大推的根本原因。 + +标准库已经实现了很多的重载函数,这也是很多公司不使用标准库的原因吧 + +模板相对于宏的两个明显优势是 +- 自动类型推导 +- 隐式实例化 + +模板先推导参数,成功后就实例化,参数推导的报错提示很明显,实例化的报错提示就很复杂了,考虑标准库内部的实现与命名规则了。 + +类型约束就是在自动类型推导时减少匹配的工作,但约束语法时C++20才加入的.在此之前只能通过一种叫做SFINAE(Substitution failure is not an error)的技术来实现 +```c++ +struct A{}; +template +void print1(T x) { + std::cout << x << std::endl; +} +// before c++ 20 +template())> +void print2(T x) { + std::cout << x << std::endl; +} +// c++20 +template +requires (T x) { std::cout << x;} +void print2(T x) { + std::cout << x << std::endl; +} +``` +其他语言如C#和rust,对泛型的约束是通过where来表达的。 + +### **编译期计算** + +- 编译器对常量表达式的优化,如C函数的strlen,在C++中strlen是constexpr的 +- 为减少运行时开销,会提前算好一些数据,典型的例子是计算三角函数表这种常量表 + +C++的编译期计算有明确的语义保证,并且内嵌于语言中,能和其他部分交互,通过模板元编程进行编译期计算。从历史上看,TMP是一个偶然事件,在标准化C++语言的过程中发现它的模板系统恰好是图灵完备的,即原则上能够计算任何可计算的东西。 + +```c++ +template +struct Factorial { + enum { value = N * Factorial::value }; +}; +template<> +struct Factorial<0> { + enum { value = 1 }; +}; +std::cout << Factorial<5>::value << std::endl; +``` +这是C++11之前的,之后引入了constexpr关键字,可以表示编译期常量这一概念了 +```c++ +template +struct Factorial { + constexpr static int value = N * Factorial::value; +}; +template<> +struct Factorial<0> { + constexpr static int value = 1; +}; +``` +编译期的计算仍然使用模板来,这样的代码可读性较低,主要原因有 +- 模板参数只能是编译期常量,没有编译期变量的概念 +- 只能递归而不能循环计算 + +不能满足上面的编程语言也有,如Haskell没有变量和循环,但是它有强大的模式匹配.这就是constexpr关键字的引入问题 +```c++ +constexpr std::size_t factorial(std::size_t N) { + std::size_t result = 1; + for (std::size_t i=1;i<=N;++i) { + result *= i; + } + return result; +} +``` +这也是C++20之后几乎所有的标准库函数都是constexpr写的,比如编译期排序 +```c++ +constexpr auto sort(auto &&range) { + std::sort(std::begin(range), std::end(range)); + return range; +} +int main() { + constexpr auto arr = sort(std::array{1,3,4,2,5}); + for (auto i : arr) std::cout << i << std::endl; +} +``` +允许一个运行期函数前面直接加上constexpr关键字修饰,表示函数既可以在运行期调用,也可以在编译期调用.如果只想在编译期执行函数,使用关键字consteval来修饰. + +### **对类型做计算与编译期常量** + +在别的编程语言中类型大多是运行时的, C++允许在编译期对类型进行操作,但是类型不能作为普通值,只能作为模板参数。 + +使用std::variant时,需要从一个类型列表里(variant的模板参数)里面根据类型返回一个索引。 + +对类型做计算不得不用模板元编程,需要在编译期计算的同时实例化模板也得使用模板元编程。 + +把类型当成值的改动是完全不可接受的unacceptable的,这是静态语言的特性,而像rust这样是完全不支持的。但有取巧的方法,把类型映射到编译期确定的值,由于字符串是值,只对字符串进行计算。[C++23的typeid实现类似的映射,而不使用字符串映射。](https://godbolt.org/z/GK4KjqKMc) + +一个较新的编程语言[zig](https://ziglang.org/),它解决了上述的问题,支持编译期的变量,还支持类型作为一等公民(type as value)进行操作,得益于zig独特的comptime机制,被它标记的变量或代码块都在编译期执行的。 + +### 额外其他 + +- 首先满足正确性而非效率性 + +在一些数据范围小答案可以枚举,且时间上较为苛刻的,使用暴力枚举得出答案,将答案写入数组中。是指先生成一些数据可直接使用,减少运行的时间,对计算量大的可以这样优化。别人把特定计算放在一些文件中,部署出去的程序就跑得飞快,其他人还好奇为什么你的就这么快。 + +### NTTP + +NTTP-non-type template parameters +```c++ +template +struct string_literal { + // str is a reference to an array N of constant char + constexpr string_literal(char const (&str)[N]) { + std::copy_n(str, N, value); + } + char value[N]; +} +``` + +### 解耦 +模板用来解耦, +如果send函数的逻辑复制,需要抽离出来复用,这时候就可以考虑使用模板来解耦,还可以避免相互依赖问题 +```c++ +// +class Connection { +public: + void send() { + Helper helper(this); + helper.send(); + } +private: + friend class Helper; // 为了Helper访问私有对象 + std::string buf; +} +``` +```c++ +// helper.hpp +template +class Helper { +public: + Helper(T *t) : buf(t->buf) {} + void send() { std::cout << buf << std::endl; } +private: + std::string& buf; +} +// 因为模板类,需要填写模板参数,可以使用C++17的deduction guide来消除这个模板参数 +template +Helper(T *t) -> Helper; // deduction guide c++17 +``` + +[**Deduction Guide**推断指引,CTAD-class template argument deduction](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction)是C++17的新语法,当用类模板新建一个类时,希望编译器通过给定的规则创建与构造器传入参数对应的模板类型时, +给定的规则就是推断指引。当模板名称显示为推导类类型的类型说明符时,使用推断指引。 + +## 观点 + +### 2024-7-23 +容器,类型容器,相当于只是占位符 +```cpp +template struct type_list {}; +``` +在这个容器上添加算法来处理,理解这一步很重要,看成一个对象,往对象里面加东西。在过去很长时间内,我没能理解模板编程的逻辑。 +这就像抽象代数一样,编译器对类型进行处理,生成(得到)各种各样的类型容器。 \ No newline at end of file diff --git a/exercises/numerical.calculation.md b/exercises/numerical.calculation.md index a794a80..50752dd 100644 --- a/exercises/numerical.calculation.md +++ b/exercises/numerical.calculation.md @@ -19,4 +19,16 @@ $$ 通常会收敛到最近的根,但也有例外,会导致得不到解 -- [牛顿拉夫森方法的意外之喜--分形图形](https://mp.weixin.qq.com/s/vjteWAtDAVHXfRwKE_DeSw) \ No newline at end of file +- [牛顿拉夫森方法的意外之喜--分形图形](https://mp.weixin.qq.com/s/vjteWAtDAVHXfRwKE_DeSw) + +## 数值积分 + +### Newton-Leibniz定积分 +空间曲线弧长、质心和惯性张量矩阵的计算都需要计算定积分,定积分的计算一般是通过Newton-Leibniz公式,找出被积函数的原函数来计算。但是在许多实际计算问题中,往往难以运用上述方法来求积分,因为有些被积函数找不到原函数。或者无完整的表达式而仅是由实验测量或计算给出的若干离散点上的量值。 + +### Gauss积分 + +Gauss型求积算法是数值稳定的,且对有限闭区间上的连续函数,Gauss求积的数值随节点数目的增加而收敛到准确积分值 。 + +- [高斯积分](http://staff.ustc.edu.cn/~rui/textbooks/nm/slides/num-integration-gauss.html#/16) +- [第四章 数值积分与数值微分 朱升峰 华东师范大学 数学科学学院](https://math.ecnu.edu.cn/~sfzhu/course/NumerAnal/NumerInt3.pdf) \ No newline at end of file diff --git a/index/online.md b/index/online.md index 5f20cfb..eb7126a 100644 --- a/index/online.md +++ b/index/online.md @@ -12,6 +12,9 @@ - [ Source repo for the book gameprogrammingpatterns.com ](https://github.com/munificent/game-programming-patterns) - [online-free](http://gameprogrammingpatterns.com/contents.html) +- [WebGL Report](https://webglreport.com/) +- [WebGPU Report](https://webgpureport.org/) + ## Blogs - [Long Luo, 一个严肃的程序员](http://www.longluo.me/) diff --git a/web/library.md b/web/library.md index 09b4505..cd00abc 100644 --- a/web/library.md +++ b/web/library.md @@ -93,6 +93,19 @@ new Promise(()=>{ ## [node-gyp](https://github.com/nodejs/node-gyp) node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It contains a vendored copy of the gyp-next project that was previously used by the Chromium team and extended to support the development of Node.js native addons. +## [PartyKit simplifies developing multiplayer applications.](https://github.com/partykit/partykit) +With PartyKit, you can focus on building multiplayer apps or adding real-time experiences to your existing projects with as little as one line of code. Meanwhile, PartyKit will handle operational complexity and real-time infrastructure scaling. + +- [doc](https://docs.partykit.io/) + +## [reveal.js](https://revealjs.com/) + +用来做PPT展示内容的。非常适合文档展示的。 + +reveal.js is an open source HTML presentation framework. + +- [github](https://github.com/hakimel/reveal.js) + ## [UMI](https://umijs.org/) - [笔记](/articles/2024/umi.md) diff --git a/web/pkg.md b/web/pkg.md index 1a2e371..6603b28 100644 --- a/web/pkg.md +++ b/web/pkg.md @@ -64,6 +64,7 @@ pnpm store prune // 删除缓存 pnpm add react -w // 全局公共依赖 pnpm add react --filter pkg1 // 指定项目按照 pnpm config set store-dir e:\dev-data\.pnpm-store\v3 --global // 设置存储目录 +pnpm --registry https://registry.npm.taobao.org install // 临时使用其他源按照 ``` ### [Yarn is a package manager](https://yarnpkg.com/)