如何修改嵌套ArrayList中外层列表的PVector对象显示位置?
问题描述
我正在开发一个嵌套结构的ArrayList<ArrayList<PVector>>,希望外层的每个ArrayList能显示在不同位置。尝试用translate()方法区分位置但无效,所有列表仍显示在同一位置;也试过通过point(v3.x * gap, v3.y * gap, v3.z * gap)调整点位置,同样没效果。请问如何修改外层ArrayList的显示位置?
现有代码
//import import peasy.*; //import variables PeasyCam acam; //position variable for pointSphere float x; float y; float z; float gap = 500; //arraylist of arraylist ArrayList<ArrayList <PVector>> sphereList = new ArrayList<ArrayList<PVector>>(); //empty arraylist ArrayList<PVector> sphere1 = new ArrayList<PVector>(); void setup() { size(1920, 1080, P3D); //camera setting acam = new PeasyCam(this, 500, 500, 500, 2000); acam.rotateX(0); acam.rotateY(0); acam.rotateZ(0); pointSphere(270, 27, 27); } void draw() { background(0); for (int i = 0; i < sphere1.size(); i++) { PVector v1; v1 = sphere1.get(i); stroke(255); strokeWeight(random(2, 10)); point(v1.x, v1.y, v1.z); for (int j = 0; j < sphereList.size(); j++) { PVector v3; v3=sphereList.get(i).get(j); pushMatrix(); gap = gap + 500; translate(1000 + gap, 1000 + gap, 1000 + gap); point(v3.x, v3.y, v3.z); popMatrix(); } } } void pointSphere (float r, float uAmount, float wAmount) { for (float u= 0; u < 180; u += 180/uAmount) { for (float w = 0; w < 360; w += 360/wAmount) { //define PVector PVector vS1 = new PVector(r*sin(radians(u))*cos(radians(w)), r*sin(radians(u))*sin(radians(w)), r*cos(radians(u))); //storing the location of Pvector into sphere1 sphere1.add(vS1); sphereList.add(sphere1); } } }
解决方案
核心问题分析
- 列表引用重复:
pointSphere函数中始终把同一个sphere1对象添加到sphereList,导致外层所有ArrayList指向同一数据集合,显示位置必然重复。 - 循环逻辑错误:
draw方法的嵌套循环顺序颠倒,且gap在每次循环中持续累加,导致位置无意义偏移,同时存在索引越界风险。 - translate位置不合理:初始
gap值过大,累加后偏移过度,无法区分不同外层列表。
修改步骤
重构
pointSphere函数,创建独立内层列表
每次循环新建ArrayList<PVector>,确保每个外层元素对应独立的点集合:void pointSphere (float r, float uAmount, float wAmount) { for (float u= 0; u < 180; u += 180/uAmount) { // 每次循环新建独立的内层列表 ArrayList<PVector> sphere = new ArrayList<PVector>(); for (float w = 0; w < 360; w += 360/wAmount) { PVector vS1 = new PVector(r*sin(radians(u))*cos(radians(w)), r*sin(radians(u))*sin(radians(w)), r*cos(radians(u))); sphere.add(vS1); } sphereList.add(sphere); } }注:原代码中的
sphere1可直接删除,无需单独维护。调整
draw方法循环逻辑,正确应用translate
先遍历外层列表,为每个列表分配独立偏移位置,避免重复累加gap:float gap = 600; // 调整为合适的间距值 void draw() { background(0); stroke(255); strokeWeight(random(2, 10)); // 遍历外层列表,每个列表对应一个偏移位置 for (int i = 0; i < sphereList.size(); i++) { ArrayList<PVector> currentSphere = sphereList.get(i); // 按x轴递增分配位置,可按需改为y/z轴或三维网格排列 float offsetX = i * gap; float offsetY = 0; float offsetZ = 0; pushMatrix(); translate(offsetX, offsetY, offsetZ); // 绘制当前列表的所有点 for (PVector v : currentSphere) { point(v.x, v.y, v.z); } popMatrix(); } }清理冗余变量
删除原代码中未使用的x、y、z变量,简化代码结构。
效果说明
修改后,每个外层ArrayList会按x轴方向以gap为间隔排列显示,你可以根据需求调整offsetX、offsetY、offsetZ的计算逻辑,实现三维网格等多种排列方式。
内容的提问来源于stack exchange,提问作者Karen Lin
相关产品推荐
相关产品推荐

