创建一个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

我对自己提出了一种挑战,我想我可以站起来寻求帮助,让我的头脑清醒过来。我想使用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 = 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个文件