处理3,815个833 835 876 879字节
@ZacharyT通过删除不必要的括号节省了两个字节
void settings(){size(600,600);}int i,w,x,n;float l,d,t,a,f,g,m,R,U;float[][]N,T;float[]S,p;void s(float[][]t){N=new float[t.length+1][2];N[0][0]=N[0][1]=i=0;for(float[]q:t)N[++i]=q;translate(w=300,w);noFill();pushMatrix();f(N,0,-w,w,1,0);popMatrix();f(N,0,-w,w,0,0);}float p(float a,float b){for(a+=PI*4;a>b;)a-=PI*2;return a;}void f(float[][]P,float x,float y,float L,int c,int I){l=2*PI;d=i=0;S=null;for(;i<P.length;i++){float[]p=P[i];g=atan2(y,x);m=atan2(p[1],p[0]);if(p(f=(c*2-1)*(g-m),0)<l&(t=dist(0,0,p[0],p[1]))<=L&I!=i){l=p(f,0);S=new float[]{g,m};d=t;n=i;}}if(S==null)ellipse(0,0,2*(L-d),2*(L-d));else{arc(0,0,L*2,L*2,p(S[c],S[1-c]),S[1-c]);R=cos(a=S[1]);U=sin(a);translate(d*R,d*U);T=new float[P.length][2];for(int i=0;i<T.length;T[i][1]=P[i][1]-d*U,i++)T[i][0]=P[i][0]-d*R;f(T,(L-d)*R,(L-d)*U,L-d,c,n);}}
像这样运行该程序:
void setup() {
s(new float[][]{{0,100},{100,100},{-200,100},{-100,-50}});
}
(该函数s
接受float[][]
)。这实际上是测试用例3,但要乘以100以适合窗口。
需要注意的几件事:
- 该程序不会画极点
- 图像显示为上下颠倒,因为在Processing的坐标系中,y轴的正方向向下
- 因为处理使用浮点数,所以计算不是很准确,因此您可能会在图像中看到这一点。我问过OP这些浮点错误是否重要。
- 窗口的大小是600像素乘600像素
- 很小的输入坐标会使程序出错,因为堆栈
pushMatrix()
及其上的popMatrix()
操作只能容纳32个矩阵。
- 狗从(0,-300)开始,链从300像素长开始
- 为了方便起见,以下图片已缩小
上述测试用例的样本输出。
如果要查看预设的输出,请在translate(w,w);
in函数之后添加此行s
。
background(-1);scale(1,-1);fill(255,0,0);ellipse(0,0,25,25);fill(0);for(float[]q:N)ellipse(q[0],q[1],25,25);
这给了我们这个结果:
脱节f()
和解释
(还包含调试代码)
void f(float[][]points, float x, float y, float len, int c, int pindex) {
print(asd+++")");
float closest = 2*PI;
float d=0,t;
float[]stuff = null;
int index = 0;
for(int i=0;i<points.length;i++) {
if(pindex != i) {
float[]p = points[i];
float originAngle = atan2(y, x);
float tempAngle = atan2(p[1], p[0]);
//println(x,y,p[0],p[1]);
float diff = c<1?tempAngle-originAngle:originAngle-tempAngle;
println("@\t"+i+"; x=\t"+x+"; y=\t"+y+"; tx=\t"+p[0]+"; ty=\t",p[1], diff, originAngle, tempAngle);
if(p(diff) < closest && (t=dist(0,0,p[0],p[1])) < len) {
println("+1");
closest = p(diff);
stuff = new float[]{originAngle, tempAngle};
d=t;
index = i;
}
}
}
if(stuff == null) {
ellipse(0,0,2*(len-d),2*(len-d));
println("mayday");
} else {
println("d angles",d,p(stuff[c],stuff[1-c],c), stuff[1-c]);
//println(points[0]);
arc(0, 0, len*2, len*2, p(stuff[c],stuff[1-c],c), stuff[1-c]);
float angle = stuff[1];
translate(d*cos(angle), d*sin(angle));
println("Translated", d*cos(angle), d*sin(angle));
println("angle",angle);
float[][]temp=new float[points.length][2];
for(int i=0;i<temp.length;i++){
temp[i][0]=points[i][0]-d*cos(angle);
temp[i][1]=points[i][1]-d*sin(angle);
println(temp[i]);
}
println(d*sin(angle));
pushMatrix();
println();
f(temp, (len-d)*cos(angle), (len-d)*sin(angle), (len-d), c, index);
popMatrix();
//f(temp, (len-d)*cos(angle), (len-d)*sin(angle), (len-d), 0, index);
}
}
简而言之,该程序将发送两个“搜索器”,一个是逆时针方向,另一个是顺时针方向。如果链条足够长,这些搜寻器中的每一个都会找到最接近的极点并向其画一条弧,否则,它会画一个圆。一旦画出弧线,它就会向该极点发送另一个搜寻器,然后继续进行该过程。f()
包含每个寻求者的过程。我越打高尔夫球,就会有更详细的解释。
{0,-.5}
什么?