YSD Blog

Boilerplate of Hux Blog

基于位置的模拟

流程 和bullet每次Tick差不多 5~7根据外力预测质点想要到的位置 8期望的位置可能产生碰撞 9~11约束处理,包括内部约束和碰撞约束,最终得到正确的位置 12~15根据正确的位置重新结算速度 推导 看了一个大神的推导,终于懂了。大神写的比较简略,这里捋一下。打公式真尼玛累 先证明一下这个 假设 则 接下来

bullet柔体模拟入门1

从网格创建柔体 btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices, const int* triangles, int ntriangles, bool randomizeConstraints){ int maxidx=0...

bullet入门-精细阶段

其实就是对每个overlap pair,执行一个nearcallback 在这个函数里,通过pair的两个形状的类型查找一个算法btCollisionAlgorithm 比如两个球体,就得到btSphereSphereCollisionAlgorithm(继承btCollisionAlgorithm) 查找是通过一个二维数组,里面都是各个算法的CreateFunc,在btDefaultCol...

bullet入门-粗略阶段

btDbvtBroadphase bullet刚体的碰撞检测用的就是这个 更新aabb 更新aabb后就和树测试,collideTV,碰撞就放入overlapping pair 计算overlapping pairs 因为更新aabb的过程是顺序的,所以要删除某些实际上没有发生的碰撞。如果是更新全部aabb在测试,就没这个问题,但是比较慢?? btAxisSweep3Internal ...

bullet入门-DBvt树的碰撞检测

collide*系列的函数,比如collideTV就是Tree和Volume的 collideTV 深度优先遍历Tree,如果某个node和Volume相交,且是叶子节点,则调用回调函数 collideTT,测试两个树,和TV不同的是: TT每次往栈压入的是一对节点,取出也是一对节点,sStkNN,用这个保存一对节点指针 如果取出的两个节点相交: 如果取出...

bullet入门-DBvt树的raycast

一些基础的东西 ICollide接口 声明了一些回调函数,检测到两个节点碰撞后调用。bullet里还有一些默认的实现。 比如btDbvtTreeCollider::Process就将两个节点放到btDbvtBroadphase的碰撞对缓存btOverlappingPairCache中 btDbvtProxy 继承btBroadphaseProxy,定义了一个object可以和哪些grou...

bullet入门-DBvt树的基本操作

插入 求曼哈顿距离,插入时选节点用到了 DBVT_INLINE btScalar Proximity(const btDbvtAabbMm& a, const btDbvtAabbMm& b){ const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx); return(btFabs(d.x())+btFabs(d.y...

bullet入门

Hello World 创建btDefaultCollisionConfiguration,主要是内存管理 创建btCollisionDispatcher,为凸凸、凸凹的碰撞检测提供算法,并提供调用回调函数,用于传递碰撞信息? 创建btBroadphaseInterface,里面应该包含一些粗略阶段的算法算法。Hello World中使用了btDbvtBroadphase。 ...

游戏循环

几种常见的游戏循环 固定的游戏速度 while (true) { double start = getCurrentTime(); processInput(); update(); render(); sleep(start + MS_PER_FRAME - getCurrentTime()); } 如果游戏实际推进所需的时间小于设定的时间,则等待;&l...

c++自动注册工厂模式

/// factory.h /// template class Factory { public: template struct Creator { Creator(const std::string& id) { // 内部类可以通过外部类的实...

透视矫正

投影面上纹理坐标u、v与顶点点坐标x、y 不是 线性关系 实际上,s/z、t/z和x’、y’也是线性关系:对1/z关于x’、y’插值得到1/z’,然后对s/z、t/z关于x’、y’进行插值得到s’/z’、t’/z’,然后用s’/z’和t’/z’分别除以1/z’,就得到了插值s’和t’。(带’的是投影空间种的坐标,不带的是相机空间的坐标) 除了纹理坐标,顶点的其他属性也是同样的道理

裁剪

Sutherland-Hodgman 算法 Sutherland-Hodgman算法逐平面对多边形进行剪裁。 对于每个剪裁面来说,输入多边形顶点序列,v1-v2-v3-…-v1, 对每条边剪裁,输出新的顶点序列 q1-q2-q2-…. 当使用一个平面对一条线段剪裁时,可能有4种情况: v1,v2都在平面内侧,输出v1 v1在平面内侧,v2在平面外侧,输出v1和交点 v1,v...

c++ operator++

当对operator ++函数进行重载时,需要自增操作符的前缀和后缀形式有不同的参数。 但是不论是自增或自减的前缀还是后缀都只有一个参数。 为了解决这个语言问题, C++规定后缀形式有一个int类型参数,当函数被调用时,编译器传递一个0做为int参数的值给该函数. UPInt& operator++() { *this += 1; return *this; }...

数位dp

Example 1: Amount of Degrees 求给定区间[X, Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂的和。其中 2 <= B <= 10。 如指定[15, 20],K=2,B=2,有三个数满足: 17=2^4+2^0 18=2^4+2^1 20=2^4+2^2 因此输出 3 ...

刷题常用

随机数 #include <stdlib.h> // 要取得[a,b)的随机整 (rand() % (b-a)) + a; // 要取得[a,b]的随机整 (rand() % (b-a+1)) + a; // 要取得(a,b]的随机整 (rand() % (b-a)) + a + 1; string int 互转 #in...

Burst Ballons

Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will ge...

Find Duplicate

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate n...

水塘抽样

有N个元素的链表,事先不知道有多长,写一个函数可以高效地从其中取出k个随机数。 水塘抽样:水塘抽样是一系列的随机算法, 其目的在于从包含n个项目的集合S中选取k个样本,其中n为一很大或未知的数量, 尤其适用于不能把所有n个项目都存放到主内存的情况。 從S中抽取首k項放入「水塘」中 對於每一個S[j]項(j ≥ k): ...

Increasing Triplet Subsequence

Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array. 遍历数组,维护一个最小值,和倒数第二小值. 遍历原数组的时候,如果当前数字小于等于最小值,更新最小值; 如果严格大于最小值,且...

Factorial Trailing Zeroes

Given an integer n, return the number of trailing zeroes in n!. 返回n的阶乘后面有几个0。 只有 2 * 5 才能得到 0,这道题实际上是看n!里有几个 2 * 5 ,比如 5! = 2 * 2 * 2 * 3 * 5 ,有一对 2 * 5 ,由于2远比5多,只要看5的个数。 ...

Decode String

Given an encoded string, return it’s decoded string. The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times...

Best Time to Buy and Sell Stock with Cooldown

Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transa...

Generate Parentheses

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n = 3, a solution set is: [ "((()))", "(()(...

Different Ways to Add Parentheses

Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +...

32位与64位下各类型长度对比

I表示:int类型 L表示:long类型 P表示:pointer指针类型 32表示:32位系统 64表示64位系统 如:LP64表示,在64位系统下的long类型和pointer类型长度为64位。

Sum of Two Integers

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and - 用异或算不带进位的和,用与算进位 class Solution { public: int getSum(int a, int b) { if (b == 0) ret...

Combination Sum

Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited...

Kth Smallest Element in a Sorted Matrix

Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix. 我用最大堆做的,堆的大小为k,堆顶保存当前最大的数字,即矩阵中第k小的数字 建堆的时候,每push一个数字到堆的...

Count Numbers with Unique Digits

Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10^n. Example: Given n = 2, return 91. (The answer should be the total n...

Bulb Switcher

There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it’s off or turn...

迭代器与traits技法


Counting Bits

Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1’s in their binary representation and return them ...

二叉搜索树的删除

结点Z没有孩子结点,那么直接删除Z就行了。 结点Z有一个孩子结点,那么删除Z,将Z的父结点与此孩子结点(子树)关联就可以了。 (图中的a和b) 结点Z有两个孩子结点,删除Z该怎样将Z的父结点与这两个孩子结点关联呢? 这种情况下不能直接删除Z,而是要用Z的后继(比Z的键值稍大的结点)来替代Z。 实现方法就是将后继从二叉树中删除,将后继...

或与加

给定 x, k ,求满足 x + y = x | y 的第k小的正整数 y x在二进制取1的位上,y只能取0 exp. x = 10010010011 y = 00000000000   k = 0 y = 00000000100   k = 1 y = 00000001000   k = 2 ...

POSIX 线程分离、结合

在任何一个时间点上,线程是可结合的( joinable ),或者是分离的( detached)。 一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的。 相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。 如果线程处于 joinable 状态,则只能只能被创建他的线程等待终止。 在Linux平台默认情...

POSIX 线程(2)

条件变量 允许线程以无竞争的方式等待条件的发生。 当一个线程获得互斥锁后,发现自己需要等待某个条件变为真, 如果是这样,该线程就可以等待在某个条件上 互斥量是用于上锁,条件变量用于等待 int pthread_cond_wait( pthread_cond_t *restrict cond, pthread_mutex_t *restrict mu...

POSIX 线程(1)

标示 pthread_t 具体内容根据实现的不同而不同,有可能是一个Structure,因此不能将其看作为整数 #include <pthread.h> int pthread_equal(pthread_t tid1, pthread_t tid2); // 相等返回非0 pthread_t pthread_self(void); 创建 restrict只...

死锁

必要条件(同时具备) 互斥条件。即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有 不可抢占条件。进程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者手中夺取资源,而只能由该资源的占有者进程自行释放 占有且申请条件。进程至少已经占有一个资源,但又申请新的资源;由于该资源已被另外进程占有,此时该进程阻塞;但是,它在等待新资源之时,仍继续占用...

数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 首先我们考虑这个问题的一个简单版本: 一个数组里除了一个数字之外,其他的数字都出现了两次。 请写程序找出这个只出现一次的数字。 这个题目的突破口在哪里?题目为什么要强调有一个数字出现一次,其他的出现两次? 我们想到了异或运算的性质:任何一个数字异或它自己都等于0 。 也就是说,...

各种海量数据处理面试题

海量日志数据,提取出某日访问百度次数最多的那个IP。 IP地址是32位的二进制数,所以共有N=2^32=4G个不同的IP地址, 创建一个unsigned count[N]的数组, 即可统计出每个IP的访问次数,而sizeof(count) == 4G*4byte=16G, 远远超过了32位计算机所支持的内存大小, 因此不能直接创建这个数组. 下面采用划分法解决这个问题. ...

构建乘积数组

给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1], 其中B中的元素B[i]=A[0]A[1]…A[i-1]A[i+1]…A[n-1]。不能使用除法;不能使用额外的空间 对于每个B的元素B[i],使用两次循环计算,第一次计算A[i]左面全部数的乘积,第二次计算右面的乘积 vector<int> multiply(const vector<...

模板实参推断

类型转换 编译器通常不对实参进行类型转换,而是生成新的模板实例 将实参传递给带模板类型的函数形参时,能够自动应用的类型转换: 顶层const被忽略 可以将非const对象的引用或指针传递给const的引用或指针形参 如果函数参数不是引用,则可将数组或函数转成指针 注意: 算数转换/子类向父类转换...

内存对齐

数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方, 以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小 (只要该成员有子成员,比如说是数组,结构体等)的整数倍开始.(比如int在32位机为4字节,则要从4的整数倍地址开始存储。 结构体作为成员:如果一个结构里有某些结构体成员,则...

c++对象内存布局

影响对象大小的因素 成员变量 虚函数表指针_vftptr 虚基类表指针_vbptr 内存对齐 _vftptr、_vbptr的初始化、set、reset由对象的构造函数, 赋值运算符自动完成; 对象生命周期结束后,由对象的析构函数来销毁。 // sizeof(CGrandChildren) = 36

new & delete

new表达式 & delete表达式 new表达式执行三步操作 调用标准库函数operator new分配一块大的,原始的,未命名的内存 运行相应的构造函数,传入初值 对象被分配了空间并构造完成,返回指向该对象的指针 delete表达式执行了两步操作 执行析构函数 调用标准库函...

I/O复用

I/O模型 阻塞式I/O 进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误才返回。 最常见的错误是系统调用被信号中断。 我们说进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。recvfrom成功返回后,应用进程开始处理数据。 非阻塞式I/O 前三次调用recvfrom时没有数据可返回,因此内核转而立即返回一个EWOULDB...

描述符就绪条件

套接字准备好读 该套接字接受缓冲区的数据字节数>=低水位标记的当前值(默认1)。这时读套接字将不阻塞并返回大于0的值 该连接的读半部关闭(也就是接受了FIN的TCP连接)。这时读套接字将不阻塞并返回0 是一个监听套接字且已完成的连接数不为0。对这样的套接字accept通常不会阻塞 其上有一个套接字错误待处理。这时读套接字将不阻塞并返回-1,同时设置errno。 ...

Linux内存管理

虚拟内存地址与物理内存地址 每个进程仿佛自己独享一片2N字节的内存,其中N是机器位数 页:一个内存页是一段固定大小的连续内存地址的总称, 具体到Linux中,典型的内存页大小为4096Byte(4K)。 进程级内存管理 内存排布 Code:这是整个用户空间的最低地址部分,存放的是指令(也就是程序所编译成的可执行机器码) Data:这里存放的是初始化过的全局...

Uncopyable base class

将copy构造函数声明为private并不绝对安全,因为成员函数和友元函数还是可以调用;如果不实现它们,对其调用将获得一个链接错误。 一个阻止copying动作设计的base class class Uncopyable { protected: Uncopyable() { } ~Uncopyable() { } private: Uncopyable(const...

Casting Away Constness

常量性转除 避免代码重复的安全做法:令non-const成员调用const成员 class TextBlock { public: ... const char& operator[] (std::size_t position) const { ... ... return text[positio...

钢条切割

给一个长度为n的钢条,可将其切割成整数长度的几段(共2的n-1次方种切法,对于每个位置可选择切割或不切割); 长度i的钢条具有Pi的价格,如何切割(也可能不切割)能使得受益最大? 设长度j的钢条最大收益r[j],第一刀切割长度s[j]; 对于子问题:切割长度j(j<=n)的钢条,假设第一刀切在i,i<=j, 则此时的收益: r[j] = max(Pi + r[j-i])...

Container With Most Water

给出一个非零数组,代表一系列高度; 取出两个高度,计算两个高度和低组成的容器最多能装多少水。 Note:两个高度中较低的那个最终决定水槽的容量! 设i,j分别为水槽的左右两个高度,i,j中较小的向中间移动, 直到找到新的i或j比之前较大的还要大,此时底比之前要小, 最小高度比之前高,容量可能比之前大。 def computeArea(self, l, r, x): re...

TCP协议通信流程

listen()调用后,对于给定的监听套接口,内核要维护两个队列: 已由客户发出SYN并到达服务器,服务器正在等待完成相应的TCP三次握手过程,若三路握手完成,该项就移至已完成连接队列 已完成连接的队列 accept()从已完成连接队列返回第一个连接,如果已完成连接队列为空,则阻塞 connect()发出SYN_SENT,并...

RAII

Resource Acquisition Is Initialization. 资源的有效期与持有(管理)资源的对象的生命期严格绑定: 使用一个对象,在其构造时获取对应的资源; 在对象生命期内控制对资源的访问,使之始终保持有效; 最后在对象析构的时候,释放构造时获取的资源。 资源不具有自动释放的功能,而C++中的类具有自动调用析构函数的功能。 把资源用类进行封装起来,对...