对于太空游戏来说,这是一个非常困难的问题,即如何操纵可以在3D中平移和旋转的宇宙飞船.
宇宙飞船有n
各种位置和方向的喷气式飞机.
i
相对于宇宙飞船的CM ,-th jet的变换是常数= Ti
.
换句话说,所有喷射器都粘在船上并且不能旋转.
射流只能沿其轴线方向(绿色)向太空船施加力.
由于胶水,轴与飞船一起旋转.
所有喷射都可以Fi
在一定幅度(标量)上施加力(矢量fi
):
i
- 喷射可以仅在范围内施加力(Fi
= axis
x fi
)min_i<= fi <=max_i
.
两个min_i
和max_i
与已知值恒定.
需要明确的是,单位min_i
,fi
,max_i
是牛顿.
防爆.如果范围不包括0,则表示无法关闭喷嘴.
宇宙飞船的质量= m
和惯性张量= I
.
宇宙飞船的当前变换= Tran0
,velocity = V0
,angularVelocity = W0
.
宇宙飞船物理学家遵循众所周知的物理规则: -
Torque=r x F
F=ma
angularAcceleration = I^-1 x Torque
linearAcceleration = m^-1 x F
I
每个方向都有所不同,但为了简单起见,每个方向都有相同的值(球形).因此, …
我有一个函数User::func()
(回调),它将由模板类(Library<T>
)调用.
在开发的第一次迭代中,每个人都知道func()
只为这个目的服务.
几个月后,大多数成员忘记了什么func()
.
经过一些重构后,func()
有时会被一些程序员删除.
起初,我认为这根本不是问题.
但是,在我多次重新遇到这种模式之后,我想我需要一些反制措施.
如何优雅地记录它?(可爱&&简洁&&没有额外的CPU成本)
这是一个简化的代码: -
(现实世界的问题是散布10个以上的库文件和20多个用户文件以及40多个函数.)
Library.h
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
node->func(); //#1
}
};
Run Code Online (Sandbox Code Playgroud)
User.h
class User{
public: void func(){/** some code*/} //#1
//... a lot of other functions ...
// some of them are also callback of other libraries
};
Run Code Online (Sandbox Code Playgroud)
main.cpp中
int main(){
Library<User> li; .... ; li.utility();
}
Run Code Online (Sandbox Code Playgroud)
作为第一个解决方法,我倾向于添加这样的评论: -
class …
Run Code Online (Sandbox Code Playgroud) 这段代码可以在g ++(coliru)中很好地编译,但是在MSVC(Godbolt和我的VS2017)中却不能。
#include <type_traits>
#include <iostream>
template<class T> void f(){
constexpr bool b=std::is_same_v<T,int>; //#1
auto func_x=[&](){
if constexpr(b){ //#error
}else{
}
};
func_x();
}
int main(){
f<int>();
}
Run Code Online (Sandbox Code Playgroud)
(6):错误C2131:表达式未求值为常数
(6):注意:失败是由于在其生命周期之外读取变量导致的
(6):注意:请参见'this'的用法
哪一个(g ++或MSVC)错了?“ 请参阅'this'的用法 ”
是什么??this
在保留编译时保证的同时如何解决呢?
在我的真实情况下,b (#1)
一个复杂的语句取决于其他一些constexpr变量。
在我allocator
通过阅读一些文章
(cppreference和我们内存不足)来研究几天之后,
我对如何控制数据结构以某种方式分配内存感到困惑.
我很确定我误解了一些东西,
所以我将把剩下的问题分成很多部分,以便让我的错误更容易被引用.
这是我(错误)理解的: -
假设这B::generateCs()
是一个C
从列表中生成列表的函数CPrototype
.
在B::generateCs()
被使用B()
的构造函数: -
class C {/*some trivial code*/};
class CPrototype {/*some trivial code*/};
class B {
public:
std::vector<C> generateCs() {
std::vector<CPrototype> prototypes = getPrototypes();
std::vector<C> result; //#X
for(std::size_t n=0; n < prototypes.size(); n++) {
//construct real object (CPrototype->C)
result.push_back( makeItBorn(prototypes[n]) );
}
return result;
}
std::vector<C> bField; //#Y
B() {
this->bField = generateCs(); //#Y …
Run Code Online (Sandbox Code Playgroud) 我正在努力创造自己的boost::adaptors::transformed
.
这是相关的提升代码.
这是它的用法(由LogicStuff的SO答案修改): -
C funcPointer(B& b){
//"funcPointer" is function convert from "B" to "C"
return instance-of-C
}
MyArray<B> test; //<-- any type, must already have begin() & end()
for(C c : test | boost::adaptor::transformed(funcPointer)) {
//... something ....
}
Run Code Online (Sandbox Code Playgroud)
结果将与: -
for(auto b : test) {
C c = funcPointer(b);
//... something ...
}
Run Code Online (Sandbox Code Playgroud)
我创造了CollectAdapter
这样的目标boost::adaptor::transformed
.
它在大多数常见情况下都能正常工作
有问题的部分是CollectAdapter
- 我的图书馆的核心.
我不知道是否应该缓存collection_ …
在调试时,我目前处于这个(下一个)声明: -
system<System_Body>()->executeFracture(calculateFracture(data));
^^1 ^^2
Run Code Online (Sandbox Code Playgroud)
如何步入executeFracture()
或calculateFracture()
直接轻松(不更改代码)?
热键?延期?插入?
F11
,我必须先迈出第一步system<System_Body>()
.executeFracture()
并按下ctrl+F10
,但这不方便.MotKohn和TheUndeadFish建议使用步骤具体,谢谢!
另一个类似的线程(我刚才发现)告诉它的热键是Shift+Alt+F11
.
热键使选择弹出,很好.
现有答案(TheUndeadFish 's)要求我在弹出窗口中将鼠标移动到正确的选项.
(或按向上/向下选择)
我希望有一个更方便的方法,例如: -
calculateFracture
,所以插入符号(闪烁|)移动到它.calculateFracture()
立即进入.我有300多个班级.它们在某些方面有关系.
为简单起见,所有关系均为1:1.
这是一个示例图.
注意:对于某些情况,某些关系可能不存在.
例如,某些hen
与任何内容无关food
.
注2:没有链接=从不,例如每个egg
都与任何相关cage
.
永远不会添加/删除/查询这种关系.
如何优雅地存储它们之间的关系?
我的所有4个想法(下面)似乎都有缺点.
这是一个相关的问题,但是1:N只有1个关系.
这些是半伪代码.
我的第一个想法是互相添加指针.
Chick.h: -
class Egg;
class Food;
class Chick{ Egg* egg; Food* food;}
Run Code Online (Sandbox Code Playgroud)
Hen.h: -
class Egg; class Cage; class Food;
class Hen{ Egg* egg; Cage* cage; Food* food;}
Run Code Online (Sandbox Code Playgroud)
添加/删除关系和查询非常便宜,例如: -
int main(){
Hen* hen; ... Egg* egg=hen->egg;
}
Run Code Online (Sandbox Code Playgroud)
它运作良好,但随着我的程序的增长,我想要将它们分离.
粗略地说,Hen.h
不应该包含单词Egg
,反之亦然.
有很多想法,但似乎都没有.
我将展示每个解决方案的简短片段,然后总结问题末尾的利弊.
使用std::unordered_map
.
它成为我程序的瓶颈.(在发布模式下配置)
class Egg{}; …
Run Code Online (Sandbox Code Playgroud) 如何使适配器类适当地支持const和非const底层数据?
RigidBody
是描述对象物理属性的类.
这是它非常简化的版本(1D): -
class RigidBody{
float position=1;
public: float getPosition()const{ return position;}
public: void setPosition(float ppos){ position=ppos;}
};
Run Code Online (Sandbox Code Playgroud)
Adapter
封装RigidBody
.
它提供了一个小失真的功能get/set position
: -
class Adapter{
public: RigidBody* rigid; int offset=2;
public: float getPosition(){
return rigid->getPosition()+offset; //distort
}
public: void setPosition(float ppos){
return rigid->setPosition(ppos-offset); //distort
}
};
Run Code Online (Sandbox Code Playgroud)
我可以RigidBody
通过以下方式间接设定位置Adapter
: -
int main() {
RigidBody rigid;
Adapter adapter; //Edit: In real life, this type is a parameter of many function …
Run Code Online (Sandbox Code Playgroud) 我想知道两个3D凸包(vs )之间的碰撞位置的大概3D位置和 3D法线。 A
B
括号中的CPU显示了我完成的程序所需的相对CPU时间。
第一步,我使用一种非常便宜的算法- 分离轴定理。
例如,我将15轴用于2个多维数据集。(在实际情况下,形状会更复杂。)
如果至少有1个可以分开的轴,return "no-collide"
。
否则,请执行下一部分。
A
是否在内部B
。 B
是否在内部A
。 有一个奇怪的情况,例如https://gamedev.stackexchange.com/questions/75437/collision-detection-3d-rectangles-using-sat。我从那里偷了图像:
因此,我还需要edge vs edge。
A
对的边缘B
。检查顶点是否在内部B
。 A
。 哇,这是很多计算。
但是,还没有结束。
C++中没有类似的(Java)Collection概念.
我能理解其中的原因,但我想知道是否有任何方法可以优雅地伪造它.
我已经实现了很多自定义Collection
.
它们都具有Iterator
走时准确,类似std::vector
,std::unordered_set
等等.
他们是 MyArray<T>
,MyBinaryTree<T>
和MySet<T>
.
在这里,我将展示一个工作代码,显示我想要伪造它的位置.
假设我有两个级别的程序:库和用户.
它只做一件事 - User
命令Library
吃掉Orange*
桶里的所有东西.
Library.h
class Library{
public: static void eatAll(const MyArray<Orange*>& bucket);
};
Run Code Online (Sandbox Code Playgroud)
Library.cpp
#include "Orange.h"
void Library::eatAll(const MyArray<Orange*>& bucket){
for(auto orange:bucket){
orange->eaten();
}
}
Run Code Online (Sandbox Code Playgroud)
User.h
MyArray<Orange*> bucket;
Library::eatAll(bucket);
Run Code Online (Sandbox Code Playgroud)
没关系.
现在,我Library::eatAll
也想支持MyBinaryTree<Orange*>
,我有一些不太理想的方法,如下所示.
MyBinaryTree<T>
和MyArray<Orange*>
(及它们的迭代器)继承自一个新类Collection<T>
(和CollectionIterator<T>
). c++ ×9
c++11 ×3
adapter ×2
c++14 ×2
game-physics ×2
templates ×2
algorithm ×1
allocation ×1
boost ×1
c++17 ×1
callback ×1
const ×1
containers ×1
convex ×1
database ×1
function ×1
if-constexpr ×1
iterator ×1
lambda ×1
memory ×1
one-to-one ×1
path-finding ×1
readability ×1
relationship ×1