目前,我正在尝试连接在设定距离内的球体。我尝试使用line(x1, y1,z1,x2,y2,z2)函数,但这会产生一些随机的线条。然后我尝试使用贝塞尔,但我仍然得到奇怪的结果。
这是到目前为止的代码:
import peasy.*;
ArrayList<Position> positions;
int count=0;
int distanceToDrawLines = 20;
PeasyCam camera;
void setup() {
size(1280, 720, P3D);
stroke(255);
positions = new ArrayList<Position>();
smooth(8);
lights();
}
void draw() {
float randomX, randomY, randomZ;
//camera(mouseX, height/2, (height/2) / tan(PI/6), width/2, height/2, 0, 0, 1, 0);
//camera = new PeasyCam(this, 0, 0, 0, 0);
randomX = random(0, width);
randomY = random(0, height);
randomZ = random(0, 40);
Position newPosition = new Position(new PVector(randomX, randomY, randomZ), 20);
positions.add(newPosition);
fill(255, 0, 0, 75);
stroke(0);
newPosition.Draw();
for (int i=0; i<positions.size(); i++) {
Position position = positions.get(i);
noFill();
beginShape();
vertex(position.vector.x,position.vector.y,position.vector.z);
if (position!=newPosition) {
float d = dist(position.vector.x, position.vector.y, position.vector.z, newPosition.vector.x, newPosition.vector.y, newPosition.vector.z);
if (d<=distanceToDrawLines && d!=0) {
println(d, positions.size(), position.vector, newPosition.vector);
bezierVertex(position.vector.x, position.vector.y, position.vector.z, newPosition.vector.x, newPosition.vector.y, newPosition.vector.z);
}
}
endShape();
}
}
和位置
类:
public class Position {
public PVector vector;
private boolean drawn;
public float radius;
public Position(PVector vector, float radius) {
this.vector = vector;
this.radius = radius;
}
public void DrawSphere() {
if (!drawn) {
fill(255, 0, 0, 75);
noStroke();
translate(vector.x, vector.y, vector.z);
sphere(radius);
fill(0);
stroke(0);
drawn = true;
}
}
public void DrawEllipse() {
if (!drawn) {
fill(random(0,255), random(0,255), random(0,255), 75);
noStroke();
ellipse(vector.x, vector.y, radius, radius);
point(vector.x, vector.y);
fill(0);
drawn = true;
}
}
}
任何帮助将不胜感激。
谢谢!
你还没有发布位置类,所以我假设它大致如下:
class Position{
PVector vector;
float radius;
Position(PVector pos,float rad){
vector = pos;
radius = rad;
}
void Draw(){
pushMatrix();
translate(vector.x,vector.y,vector.z);
sphere(radius);
popMatrix();
}
}
有几件事似乎没有反映出你的意图:
settings()
中初始化一次,而不是在draw()
count
变量的意图?在一定距离内接近的球体
听起来有点不清楚。看起来距离没有设置,因为您在最近的位置实例中比较的距离之一位于随机位置。(除非您确实想将距离与最近的球体/位置实例进行比较)
除此之外,我只有一些简化此设置的提示:
>
使用PVector的dist()做同样的事情
dist(位置. vector.x、位置.vector.y、位置.vector.z、newPosition.vector.x、newPosition.vector.y、newPosition.vector.z);但保持语法更简洁:位置.vector.dist(newPosition.vector);
您可以根据您的代码在修订和注释版本中尝试这些建议(使用向上/向下键更改距离阈值):
in-processing
import peasy.*;
ArrayList<Position> positions;
int count=0;
//increase the distance threshold value: with a wider range of random values there will be less chances of spheres being so close to each other
int distanceToDrawLines = 200;
PeasyCam camera;
//keep a reference to the most recent Position instance
Position newPosition = null;
void setup() {
size(1280, 720, P3D);
stroke(255);
positions = new ArrayList<Position>();
smooth(8);
lights();
//use simplified spheres (will look blockier, but will render faster)
sphereDetail(5);
//setup PeasyCam once in setup
camera = new PeasyCam(this, 100);
camera.setMinimumDistance(50);
camera.setMaximumDistance(500);
}
void draw() {
background(127);
//generate a limited amount of spheres
if(count < 100){
float randomX, randomY, randomZ;
randomX = random(-width, width);
randomY = random(-height, height);
randomZ = random(-40, 40);
newPosition = new Position(new PVector(randomX, randomY, randomZ), 20);
positions.add(newPosition);
count++;
}
for (int i=0; i<positions.size(); i++) {
Position position = positions.get(i);
noFill();
if (position != newPosition) {
float d = position.vector.dist(newPosition.vector);
if (d<=distanceToDrawLines && d!=0) {
println(d, positions.size(), position.vector, newPosition.vector);
line(position.vector.x, position.vector.y, position.vector.z, newPosition.vector.x, newPosition.vector.y, newPosition.vector.z);
}
}else{
//hightlight newest Position instance in transparent red
fill(255, 0, 0, 75);
}
//render every Position instance (after the noFill() / fill() have been set
position.Draw();
}
}
//test - play with UP/DOWN arrows to tinker with distance
void keyPressed(){
if(keyCode == UP) distanceToDrawLines += 10;
if(keyCode == DOWN) distanceToDrawLines -= 10;
distanceToDrawLines = constrain(distanceToDrawLines,20,2000);
println("distanceToDrawLines: " + distanceToDrawLines);
}
class Position{
PVector vector;
float radius;
Position(PVector pos,float rad){
vector = pos;
radius = rad;
}
void Draw(){
pushMatrix();
translate(vector.x,vector.y,vector.z);
sphere(radius);
popMatrix();
}
}
这里的更新是一个示例,突出了注释中提到的一些优化概念。理想情况下,一些代码会移动到着色器,但值得使用jVisual alvm
来跟踪当前执行的调用大部分时间并在那里开始优化。
import peasy.*;
ArrayList<Position> positions;
Position newPosition;
int count=0;
int distanceToDrawLines = 500;
PeasyCam cam;
PShape nodes;
int fcount, lastm;
float frate;
int fint = 3;
void setup() {
size(1280, 720, P3D);
positions = new ArrayList<Position>();
smooth(8);
lights();
//use simplified spheres (will look blockier, but will render faster)
sphereDetail(0);//5
frameRate(60);
cam = new PeasyCam(this, 100);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
nodes = createShape(GROUP);
while (count < 300) {
float randomX, randomY, randomZ, randomRadius;
randomX = random(-width*2, width*2);
randomY = random(-height*2, height*2);
randomZ = random(-1000*2, 1000*2);
randomRadius = random(10, 40);
newPosition = new Position(new PVector(randomX, randomY, randomZ), randomRadius);
positions.add(newPosition);
count++;
}
println("positions initialized");
//calculate distances once, rather than multiple times per seconds
//similarly instantiate geometries, which will simply be rendered in draw()
float distanceToDrawLinesSq = distanceToDrawLines * distanceToDrawLines;
int numPositions = positions.size();
for (int i=0; i<numPositions-1; i++) {
for (int j=i+1; j<positions.size(); j++) {
Position iPosition = positions.get(i);
//iPosition.DrawSphere();
nodes.addChild(getSphere(iPosition));
Position jPosition = positions.get(j);
//jPosition.DrawSphere();
nodes.addChild(getSphere(jPosition));
//cam.lookAt(iPosition.vector.x, iPosition.vector.y, iPosition.vector.z, 5);
// float d = iPosition.vector.dist(jPosition.vector);
// if (d <= distanceToDrawLines) {
//using distance squared (more useful in draw() than setup though
float dSq = PVector.sub(iPosition.vector,jPosition.vector).magSq();
if (dSq <= distanceToDrawLinesSq) {
PShape line = createShape(LINE,iPosition.vector.x, iPosition.vector.y, iPosition.vector.z, jPosition.vector.x, jPosition.vector.y, jPosition.vector.z);
line.setStroke(color(255));
line.setFill(false);
nodes.addChild(line);
//stroke(255);
//line(iPosition.vector.x, iPosition.vector.y, iPosition.vector.z, jPosition.vector.x, jPosition.vector.y, jPosition.vector.z);
}
}
}
println("geometries initialized");
}
PShape getSphere(Position p){
PShape sphere = createShape(SPHERE, 1.0);
sphere.setStroke(false);
sphere.setFill(p.fillColor);
sphere.translate(p.vector.x,p.vector.y,p.vector.z);
sphere.scale(p.radius);
return sphere;
}
void draw() {
background(0);
hint(DISABLE_DEPTH_TEST);
pushMatrix();
translate(width/2, height/2, -500);
rotateY(frameCount * 0.01);
rotateX(frameCount * 0.01);
shape(nodes);
popMatrix();
hint(ENABLE_DEPTH_TEST);
fcount += 1;
int m = millis();
if (m - lastm > 1000 * fint) {
frate = float(fcount) / fint;
fcount = 0;
lastm = m;
println("fps: " + frate);
}
//saveFrame("/output3/sequence####.tga");
//saveFrame in separate thread
TImage frame = new TImage(width,height,RGB,sketchPath("frame_"+nf(frameCount,3)+".tga"));
frame.set(0,0,get());
frame.saveThreaded();
}
class TImage extends PImage implements Runnable{//separate thread for saving images
String filename;
TImage(int w,int h,int format,String filename){
this.filename = filename;
init(w,h,format);
}
public void saveThreaded(){
new Thread(this).start();
}
public void run(){
this.save(filename);
}
}
public class Position {
private float speed;
public PVector vector;
public float radius;
public int fillColor = color(200, 0, 0, 75);
public Position(PVector vector, float radius) {
this.vector = vector;
this.radius = radius;
this.speed = 0.05;
}
public void DrawSphere() {
noStroke();
vector.x+=random(-speed, speed);
vector.y+=random(-speed, speed);
vector.z+=random(-speed, speed);
fill(fillColor);
pushMatrix();
translate(vector.x, vector.y, vector.z);
sphere(radius);
popMatrix();
}
public void DrawEllipse() {
pushMatrix();
translate(vector.x, vector.y, vector.z);
ellipse(vector.x, vector.y, radius, radius);
popMatrix();
}
}