小编jav*_*ver的帖子

宇宙飞船推进的AI:在位置= 0和角度= 0的情况下着陆3D船

对于太空游戏来说,这是一个非常困难的问题,即如何操纵可以在3D中平移和旋转的宇宙飞船.

宇宙飞船有n各种位置和方向的喷气式飞机.

i相对于宇宙飞船的CM ,-th jet的变换是常数= Ti.

  • 变换是位置和方向的元组(四元数或矩阵3x3或更不优选的欧拉角).
  • 转换也可以用单个矩阵4x4表示.

换句话说,所有喷射器都粘在船上并且不能旋转.

射流只能沿其轴线方向(绿色)向太空船施加力.
由于胶水,轴与飞船一起旋转.

在此输入图像描述

所有喷射都可以Fi在一定幅度(标量)上施加力(矢量fi):
i- 喷射可以仅在范围内施加力(Fi= axisx fi)min_i<= fi <=max_i.
两个min_imax_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每个方向都有所不同,但为了简单起见,每个方向都有相同的值(球形).因此, …

artificial-intelligence path-finding game-physics

33
推荐指数
2
解决办法
888
查看次数

如何自我记录模板库类调用的回调函数?

我有一个函数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)

我糟糕的解决方案

1.评论/文件

作为第一个解决方法,我倾向于添加这样的评论: -

class …
Run Code Online (Sandbox Code Playgroud)

c++ maintainability templates readability callback

19
推荐指数
1
解决办法
698
查看次数

在lambda内部捕获的Constexpr变量失去了其解释性

这段代码可以在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变量。

c++ lambda language-lawyer c++17 if-constexpr

19
推荐指数
2
解决办法
867
查看次数

我应该将allocator作为函数参数传递吗?(我对分配器的误解)

在我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)

c++ memory memory-management allocation c++11

15
推荐指数
1
解决办法
1382
查看次数

创建库以覆盖迭代器的运算符*() - 冒险悬挂指针

我正在努力创造自己的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_ …

c++ boost iterator adapter c++11

15
推荐指数
1
解决办法
428
查看次数

Visual Studio:热键/直接步入f()语句a() - > f(b(),c(),d())的方法

在调试时,我目前处于这个(下一个)声明: -

system<System_Body>()->executeFracture(calculateFracture(data));
                       ^^1               ^^2
Run Code Online (Sandbox Code Playgroud)

如何步入executeFracture()calculateFracture()直接轻松(不更改代码)?

热键?延期?插入?

我糟糕的解决方案

  • 有了F11,我必须先迈出第一步system<System_Body>().
  • 我也可以从那里跳到源头executeFracture()并按下ctrl+F10,但这不方便.

编辑

MotKohnTheUndeadFish建议使用步骤具体,谢谢!
另一个类似的线程(我刚才发现)告诉它的热键是Shift+Alt+F11.
热键使选择弹出,很好.

编辑2(赏金原因)

现有答案(TheUndeadFish 's)要求我在弹出窗口中将鼠标移动到正确的选项.
(或按向上/向下选择)

我希望有一个更方便的方法,例如: -

  • 我点击这个词calculateFracture,所以插入符号(闪烁|)移动到它.
  • 然后,我使用键盘按某些热键,
    VS将calculateFracture() 立即进入.

c++ visual-studio-debugging visual-studio-2015

14
推荐指数
2
解决办法
676
查看次数

在各种类型的对象之间存储许多关系1:1:去耦和高性能

我有300多个班级.它们在某些方面有关系.

为简单起见,所有关系均为1:1.
这是一个示例图.

在此输入图像描述 (在实际情况中,大约有50个关系对.)

注意:对于某些情况,某些关系可能不存在.
例如,某些hen与任何内容无关food.

注2:没有链接=从不,例如每个egg都与任何相关cage.
永远不会添加/删除/查询这种关系.

题:

如何优雅地存储它们之间的关系?
我的所有4个想法(下面)似乎都有缺点.

是一个相关的问题,但是1:N只有1个关系.

我糟糕的解决方案

这些是半伪代码.

版本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,反之亦然.

有很多想法,但似乎都没有.
我将展示每个解决方案的简短片段,然后总结问题末尾的利弊.

版本2哈希映射

使用std::unordered_map.
它成为我程序的瓶颈.(在发布模式下配置)

class Egg{}; …
Run Code Online (Sandbox Code Playgroud)

c++ database one-to-one relationship c++14

13
推荐指数
1
解决办法
679
查看次数

适配器模式:支持基本数据,可以是const或非const,优雅

如何使适配器类适当地支持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)

c++ const function adapter c++14

12
推荐指数
2
解决办法
730
查看次数

3D碰撞检测:凸包与凸包,需要Position和Normal

我想知道两个3D凸包(vs )之间的碰撞位置的大概3D位置 3D法线。 AB

括号中的CPU显示了我完成的程序所需的相对CPU时间。

第1部分:抢先体验(CPU 1%)

第一步,我使用一种非常便宜的算法- 分离轴定理
例如,我将15轴用于2个多维数据集。(在实际情况下,形状会更复杂。)
如果至少有1个可以分开的轴,return "no-collide"
否则,请执行下一部分。

第2部分:顶点与体积(CPU 10%)

  • 检查-的每个顶点A是否在内部B
  • 检查-的每个顶点B是否在内部A

在此处输入图片说明

第3部分:Edge vs Edge(CPU> 20%)

有一个奇怪的情况,例如https://gamedev.stackexchange.com/questions/75437/collision-detection-3d-rectangles-using-sat。我从那里偷了图像:

在此处输入图片说明

因此,我还需要edge vs edge

  • 对于每对A和B的边缘(12 * 12 = 144对),在找到边缘最近点A对的边缘B。检查顶点是否在内部B
  • (反之亦然)对于每对B&A边,检查该顶点是否在内部A

哇,这是很多计算。
但是,还没有结束。

问题

  1. 报告的碰撞位置不太准确(左:当前,右:希望):-

    在此处输入图片说明

    为了解决这个问题,我考虑过要生成一个新的凸形= A intersect B
    有一些免费的C ++库(例如OpenMesh),但是我认为它过于占用 CPU资源。
    请注意,我不需要准确无误。

  2. 有时还会报告错误的正常状态(左:当前,右:希望):-

    在此处输入图片说明

    ^这个问题可能通过增加来解决边缘 …

c++ algorithm collision-detection convex game-physics

12
推荐指数
1
解决办法
485
查看次数

C++不鼓励收集基类 - 无论如何都要伪造它?

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*>,我有一些不太理想的方法,如下所示.

我的解决方案不好

1. Java方式

  • Make MyBinaryTree<T>MyArray<Orange*>(及它们的迭代器)继承自一个新类Collection<T>(和CollectionIterator<T>).
  • 将签名更改为 …

c++ containers templates c++11

11
推荐指数
1
解决办法
966
查看次数