在三维中常常需要重算正交的基向量组,
由于叉乘操作是有序的. 一般来说 : UxV不等于VxU,
所有往往记不住到底是哪个左向量乘哪个右向量求出
第三个向量,由于吃了一些亏所以做了总结.
i,j,k三个基向量, 如果你使用的图形引擎Z往屏幕外面,
右手边X和上方向Y规定为正方向的一组正交向量,如果
你使用的模型的基向量组和它相同,那么放心用.
ix
j=k, kx
i=j, jx
k=i 但是你可能不总是那么幸运.也许你打算使用Z往屏幕里面,
右手边X和上方向Y规定为正方向的一组正交向量,这时你就
需要改变叉乘方式了
jx
i=k, ix
k=j, kx
j=i
也就是统统反过来使用就可以了.
但是如果你想使用Z往屏幕里面,右手边X和下方向Y规定
为正方向的一组正交向量时这时你又需要怎么弄呢?
其实还是:
ix
j=k, kx
i=j, jx
k=i 如果你想使用Z往屏幕里面,左手边X和下方向Y规定
为正方向的一组正交向量时这时你又需要怎么弄呢?
这时又是:
jx
i=k, ix
k=j, kx
j=i
也是统统反过来使用.
这时怎么得到得结论?
其实就是通过计算得到的
以下都假设x右为正方向,y上为正方向,z往屏幕外为正方向设备的环境
测试.
var vec3 = glMatrix.vec3;
console.log("-------------------->z轴往屏幕里为正的坐标系");
var u = vec3.fromValues(1,0,0)
var v = vec3.fromValues(0,1,0)
var w = vec3.fromValues(0,0,-1)
console.log(vec3.cross(vec3.create(), w,v));
console.log(vec3.cross(vec3.create(), u,w));
console.log(vec3.cross(vec3.create(), v,u));
console.log("-------------------->y轴向下为正的坐标系");
var u = vec3.fromValues(1,0,0)
var v = vec3.fromValues(0,-1,0)
var w = vec3.fromValues(0,0,1)
console.log(vec3.cross(vec3.create(), w,v));
console.log(vec3.cross(vec3.create(), u,w));
console.log(vec3.cross(vec3.create(), v,u));
console.log("-------------------->x轴向左为正的坐标系");
var u = vec3.fromValues(-1,0,0)
var v = vec3.fromValues(0,1,0)
var w = vec3.fromValues(0,0,1)
console.log(vec3.cross(vec3.create(), w,v));
console.log(vec3.cross(vec3.create(), u,w));
console.log(vec3.cross(vec3.create(), v,u));
console.log("-------------------->全部反为正坐标系");
var u = vec3.fromValues(-1,0,0)
var v = vec3.fromValues(0,-1,0)
var w = vec3.fromValues(0,0,-1)
console.log(vec3.cross(vec3.create(), w,v));
console.log(vec3.cross(vec3.create(), u,w));
console.log(vec3.cross(vec3.create(), v,u));
以上都能得到正确的向量组
console.log("-------------------->z轴往屏幕外为正坐标系");
var u = vec3.fromValues(1,0,0)
var v = vec3.fromValues(0,1,0)
var w = vec3.fromValues(0,0,1)
console.log(vec3.cross(vec3.create(), v,w));
console.log(vec3.cross(vec3.create(), w,u));
console.log(vec3.cross(vec3.create(), u,v));
console.log("-------------------->任意两个是为负数的坐标系");
var u = vec3.fromValues(-1,0,0)
var v = vec3.fromValues(0,1,0)
var w = vec3.fromValues(0,0,-1)
console.log(vec3.cross(vec3.create(), v,w));
console.log(vec3.cross(vec3.create(), w,u));
console.log(vec3.cross(vec3.create(), u,v));
以上也都能得到正确的向量组.
结论就是如果偶数相反就正常使用,如果是奇数相反就
用反过来用.
// 排列:正数n的全排列
// n 正数n
// return 数值
function A(n) {
if (n <= 0) return n;
var sum = 1;
for (var i = n; i > 0; --i) {
sum *= i;
}
return sum;
}
// 组合:从n个中选择m个来组合
// n 正数n
// m 正数m
// return 数值
function C(n, m) {
return A(n) / (A(m) * A(n - m));
}
// 数组组合: 从array中选择n个元素来组合
// array 数组
// n 正数n
// return 多少种组合
function ArrayComb(array, n) {
var result = [], t = [], e;
function Recursion(index, array, n, t, result) {
if (t.length === n) { result.push(t.slice()); return };
for (var i = index; i < array.length; ++i) {
e = array[i];
t.push(e);
Recursion(i + 1, array, n, t, result);
t.pop();
}
}
Recursion(0, array, n, t, result);
return result;
}
c/c++
//>this is a Quine program implement by c language.
//>reference http://www.madore.org/~david/computers/quine.html
#include <stdio.h>
int main(void){
char n='\n'; char g='\\'; char q='"'; char s=';';
char*s1="//>this is a Quine program implement by c language.%c//>reference http://www.madore.org/~david/computers/quine.html%c#include <stdio.h>%cint main(void){%c char n='%cn'; char g='%c%c'; char q='%c'; char s=';';%c char*s1=%c%s%c;%c printf(s1,n,n,n,n,g,g,g,q,n,q,s1,q,n,s,n,s,n)%c%c return 0%c%c}";
printf(s1,n,n,n,n,g,g,g,q,n,q,s1,q,n,s,n,s,n);
return 0;
}
javascript
var c1='"'; var c2='\n'; var c3='\\'; var c4=';';
var s1="var c1='%c1'; var c2='%c3n'; var c3='%c3%c3'; var c4=';';%c2var s1=%c1%s1%c1%c4%c2console.log((((((((((s1.replace('%c1', c1)).replace('%c1', c1)).replace('%c1', c1)).replace('%c2', c2)).replace('%c2', c2)).replace('%c3', c3)).replace('%c3', c3)).replace('%c3', c3)).replace('%c4', c4)).replace('%s1', s1))";
console.log((((((((((s1.replace('%c1', c1)).replace('%c1', c1)).replace('%c1', c1)).replace('%c2', c2)).replace('%c2', c2)).replace('%c3', c3)).replace('%c3', c3)).replace('%c3', c3)).replace('%c4', c4)).replace('%s1', s1))
// test less and equal zero
// x小于,等于0返回0,x大于0返回1
// if x <= 0 return 0 and x > 0 return 1.
float LQZ(x){
return max(0, sign(x));
// return ceil(clamp(0.,1.,x));
}
// if x <= 0 return a and x > 0 return b
// x小于,等于0返回a,x大于0返回b
float v = mix(a, b, LQZ(x));
// if x is odd number (0~1,2~3,4~5,6~7) return a else return b
// 奇数段(0~1,2~3,4~5,...)返回a,偶数段(1~2,3~4)返回b
float v = mix(a, b, LQZ(mod(x,2.0) - 1.0));