使用Javascript(ES6),306个 293 283字节
c=(v,w,x)=>(w[0]-v[0])*(w[1]-x[1])-(w[1]-v[1])*(w[0]-x[0])>0?1:0
i=(v,w,x,y)=>(c(v,w,x)+c(w,x,y)+c(x,y,v)+c(y,v,w))%4==0&&r.push([v,w,x,y])
j=(v,w,x,y)=>{i(v,w,x,y);i(v,w,y,x);i(v,x,w,y)}
k=(v,w,x,y,z)=>{j(v,w,x,y);j(v,w,x,z);j(v,w,y,z);j(v,x,y,z);j(w,x,y,z)}
f=(v)=>(r=[],k(...v),r)
说明:
该函数c
计算多边形的3个相邻点之间的矢量叉积,如果为正,则返回1,否则返回0(注意:叉积不能为零,因为这些点不能共线)。
j=(v,w,x,y)=>{i(v,w,x,y);i(v,w,y,x);i(v,x,w,y)}
k=(v,w,x,y,z)=>{j(v,w,x,y);j(v,w,x,z);j(v,w,y,z);j(v,x,y,z);j(w,x,y,z)}
该函数k
并j
生成输入数组的所有循环置换(忽略逆序)。
i=(v,w,x,y)=>(c(v,w,x)+c(w,x,y)+c(x,y,v)+c(y,v,w))%4==0&&r.push([v,w,x,y])
然后,对每个循环置换调用函数“ i”,以计算c
相邻坐标的4个三元组中的每一个的函数之和。如果叉积都具有相同的符号,则它们将全部为0或1,并且总计为0(模4),并且多边形为凹面并被推入输出数组。如果任何一个三元组的符号不同,则总和将为非零(模4),并且多边形为凸形。
f=(v)=>(r=[],k(...v),r)
该函数f
用于初始化输出数组,然后在返回输出之前调用上述函数。
测试:
c=(v,w,x)=>(w[0]-v[0])*(w[1]-x[1])-(w[1]-v[1])*(w[0]-x[0])>0?1:0
i=(v,w,x,y)=>(c(v,w,x)+c(w,x,y)+c(x,y,v)+c(y,v,w))%4==0&&r.push([v,w,x,y])
j=(v,w,x,y)=>{i(v,w,x,y);i(v,w,y,x);i(v,x,w,y)}
k=(v,w,x,y,z)=>{j(v,w,x,y);j(v,w,x,z);j(v,w,y,z);j(v,x,y,z);j(w,x,y,z)}
f=(v)=>(r=[],k(...v),r)
tests = [
[[6,8],[1,10],[6,6],[5,9],[8,10]],
[[3,8],[7,5],[6,9],[7,8],[5,1]],
[[4,8],[1,9],[9,9],[10,2],[1,6]]
];
tests.forEach(
(test,i)=>{
console.log( "Test " + (i+1) );
f(test).forEach(
(x)=>console.log( " " + x.map((e)=>"("+e[0]+","+e[1]+")").join(','))
);
}
);
编辑:
也可以使用原始版本并将前两行更改为:
t=(a,b,c)=>Math.sign((b[0]-a[0])*(b[1]-c[1])-(b[1]-a[1])*(b[0]-c[0]))
p=(a,b,c,d)=>[t(a,b,c),t(b,c,d),t(c,d,a),t(d,a,b)].filter(x=>x).reduce((p,c,i,a)=>p&c==a[0],1)
q=(a,m,n,o)=>[a[0],a[m],a[n],a[o]]
f=(a)=>{r=[];for(i=0;i<5;i++){b=a.slice();b.splice(i,1);r.push(q(b,1,2,3));r.push(q(b,1,3,2));r.push(q(b,2,1,3))}return r.filter((a)=>p(...a))}
但是,由于问题中明确排除了这种情况,因此不需要多余的字符。