创建一个Java点数组,该数组向定义的端点随机移动
我对自己提出了一种挑战,我想我可以站起来寻求帮助,让我的头脑清醒过来。我想使用java图形绘制一些看起来像闪电击中给定点的东西 现在我只有这个,它在随机的方向上发射廉价的“闪电”,我不在乎它在哪里结束创建一个Java点数组,该数组向定义的端点随机移动,java,arrays,random,point,Java,Arrays,Random,Point,我对自己提出了一种挑战,我想我可以站起来寻求帮助,让我的头脑清醒过来。我想使用java图形绘制一些看起来像闪电击中给定点的东西 现在我只有这个,它在随机的方向上发射廉价的“闪电”,我不在乎它在哪里结束 lightning[0] = new Point(370,130); //This is a given start point. // Start in a random direction, each line segment has a length of 25 double theta
lightning[0] = new Point(370,130); //This is a given start point.
// Start in a random direction, each line segment has a length of 25
double theta = rand.nextDouble()*2*Math.PI;
int X = (int)(25*Math.cos(theta));
int Y = (int)(25*Math.sin(theta));
//Populate the array with more points
for (int i = 1 ; i < lightning.length ; i++)
{
lightning[i] = new Point(X + lightning[i-1].x, Y + lightning[i-1].y);
boolean plusminus = rand.nextBoolean();
if (plusminus) theta = theta + rand.nextDouble()*(Math.PI/2);
else theta = theta - rand.nextDouble()*(Math.PI/2);
X = (int)(25*Math.cos(theta));
Y = (int)(25*Math.sin(theta));
}
// Draw lines connecting each point
canvas.setColor(Color.WHITE);
for (int i = 1 ; i < lightning.length ; i++)
{
int Xbegin = lightning[i-1].x;
int Xend = lightning[i].x;
int Ybegin = lightning[i-1].y;
int Yend = lightning[i].y;
canvas.drawLine(Xbegin, Ybegin, Xend, Yend);
//if (Xend != Xbegin) theta = Math.atan((Yend - Ybegin)/(Xend - Xbegin));
// Restrict the angle to 90 degrees in either direction
boolean plusminus = rand.nextBoolean();
if (plusminus) theta = theta + rand.nextDouble()*(Math.PI/2);
else theta = theta - rand.nextDouble()*(Math.PI/2);
// 50/50 chance of creating a half-length off-shoot branch on the end
if (rand.nextBoolean())
{
int Xoff = (int)(Xend+(12*Math.cos(theta)));
int Yoff = (int)(Yend+(12*Math.sin(theta)));
canvas.drawLine(Xend, Yend, Xoff, Yoff);
}
}
lightning[0]=新点(370130)//这是一个给定的起点。
//从随机方向开始,每条线段的长度为25
double theta=rand.nextDouble()*2*Math.PI;
int X=(int)(25*Math.cos(θ));
int Y=(int)(25*Math.sin(θ));
//用更多点填充阵列
对于(int i=1;i
我正试图想出一些类似的方法来创建这种效果,但要预先定义阵列中的最后一个点,以便闪电可以“击中”特定点。换句话说,我想以一种随机的方式填充一个点数组,但仍然会收敛到最后一个点上
有人愿意加入吗?没有任何图形经验,我有一个建议:很难选择一个特定的点,然后尝试以“随机”的方式达到它。相反,我建议创建一条从起点到终点的直线,然后随机弯曲部分。您可以进行多次传递,将越来越小的段弯曲到一定的限制,以获得所需的外观。同样,我是在不了解图形API的情况下说这句话的。我认为这是一种相当简单、准确、优雅的方法。它采用分而治之的策略。仅从两个值开始:
- 起点
- 终点
方差
(可以相对于长度进行计算)。理想情况下,偏移量应该与连接起点和终点的矢量垂直,但如果将偏移量设置为水平,则成本较低,只要螺栓基本上垂直移动,就像真实的闪电一样。对(开始、偏移、中间)和(偏移、中间、结束)重复上述步骤,但这次对差异使用较小的数字。这是一种递归方法,可在达到阈值方差或阈值线段长度时终止。随着递归的展开,您可以绘制所有的连接器段。其思想是,最大的差异发生在螺栓的中心(当开始到结束的距离最长时),每次递归调用时,点之间的距离都会缩小,差异也会缩小。这样,螺栓的全局方差将远大于任何局部方差(如真实的闪电螺栓)
以下是使用此算法从相同的预定义点生成的3个不同螺栓的图像。这些点正好是(250100)和(500800)。如果希望螺栓在任何方向上移动(而不仅仅是“基本垂直”),则需要增加点移动代码的复杂性,根据螺栓的移动角度移动X和Y
下面是一些用于这种方法的Java代码。我使用了一个ArrayList
,因为分而治之的方法事先不知道最终会有多少元素
// play with these values to fine-tune the appearance of your bolt
private static final double VAR_FACTOR = 0.40;
private static final double VAR_DECREASE = 0.55;
private static final int MIN_LENGTH = 50;
public static ArrayList<Point> buildBolt(Point start, Point end) {
ArrayList<Point> bolt = new ArrayList<Point>();
double dx = start.getX() - end.getX();
double dy = start.getY() - end.getY();
double length = Math.sqrt(dx*dx + dy*dy);
double variance = length * VAR_FACTOR;
bolt.add(start);
buildBolt(start, end, bolt, variance);
return bolt;
}
private static void buildBolt(Point start, Point end,
List<Point> bolt, double variance) {
double dx = start.getX() - end.getX();
double dy = start.getY() - end.getY();
double length = Math.sqrt(dx*dx + dy*dy);
if (length > MIN_LENGTH) {
int varX = (int) ((Math.random() * variance * 2) - variance);
int midX = (start.x + end.x)/2 + varX;
int midY = (start.y + end.y)/2;
Point mid = new Point(midX, midY);
buildBolt(start, mid, bolt, variance * VAR_DECREASE);
buildBolt(mid, end, bolt, variance * VAR_DECREASE);
} else {
bolt.add(end);
}
return;
}
//使用这些值可以微调螺栓的外观
私人静态最终双VAR_系数=0.40;
私人静态最终双VAR_减少=0.55;
专用静态最终整数最小长度=50;
公共静态ArrayList构建螺栓(点起点、点终点){
ArrayList螺栓=新的ArrayList();
double dx=start.getX()-end.getX();
double dy=start.getY()-end.getY();
双倍长度=数学sqrt(dx*dx+dy*dy);
双方差=长度*VAR_因子;
螺栓。添加(开始);
建筑螺栓(起点、终点、螺栓、偏差);
回位螺栓;
}
专用静态空心建筑螺栓(点起点、点终点、,
列表螺栓(双变量){
double dx=start.getX()-end.getX();
double dy=start.getY()-end.getY();
双倍长度=数学sqrt(dx*dx+dy*dy);
如果(长度>最小长度){
int varX=(int)((Math.random()*方差*2)-方差);
intmidx=(start.x+end.x)/2+varX;
int midY=(start.y+end.y)/2;
中点=新点(中点,中点);
建筑螺栓(开始、中间、螺栓、差异*VAR_减少);
建筑螺栓(中间、端部、螺栓、差异*VAR_减少);
}否则{
螺栓。添加(结束);
}
返回;
}
…实际上,我还是有点好奇你是如何使用arraylist绘制闪电的。我的直觉是把它转换成一个数组,它可以工作,但是。。。你做了什么?你可以像遍历数组一样遍历ArrayList。这就是ArrayList的全部要点。:-)这是我以前制作的3个文件