Processing 如何在L-系统树上找到分支的起始/结束顶点?(p5.js)

Processing 如何在L-系统树上找到分支的起始/结束顶点?(p5.js),processing,p5.js,fractals,procedural-generation,l-systems,Processing,P5.js,Fractals,Procedural Generation,L Systems,我试图在一个简单的L-系统树上得到分支端点的x,y坐标。其思想是创建一个p5.Vector(x,y)并将其推送到一个数组中 现在,我可以通过将原点设置为(0,-len)来绘制椭圆来标记所需的点,但我有一个问题。当我尝试将(0,-len)作为新的p5.Vector(x,y)推送到一个数组中时,每个点的x坐标都是0,尽管y坐标正确 我知道这与将坐标转换回(宽度/2,高度)有关,但我无法计算出正确的计算。我甚至试过tan(angle)*(y1-y2),但并不完全正确。蒂亚 var axiom = 'F

我试图在一个简单的L-系统树上得到分支端点的x,y坐标。其思想是创建一个
p5.Vector(x,y)
并将其推送到一个数组中

现在,我可以通过将原点设置为(0,-len)来绘制椭圆来标记所需的点,但我有一个问题。当我尝试将(0,-len)作为新的p5.Vector(x,y)推送到一个数组中时,每个点的x坐标都是0,尽管y坐标正确

我知道这与将坐标转换回(宽度/2,高度)有关,但我无法计算出正确的计算。我甚至试过
tan(angle)*(y1-y2)
,但并不完全正确。蒂亚

var axiom = 'F';
var sentence = axiom;
var len = 300;

var count = 0;
var flowerArr = [];

var rules = [];
rules[0] = {
    a: 'F',
    b: 'G[+F][-F]GF'
};

rules[1] = {
    a: 'G',
    b: 'GG'
};


function setup() {
    createCanvas(window.innerWidth, window.innerHeight);
    stroke(10);
    smooth();
    turtle();
}


function turtle() {
    background(255);
    strokeWeight(1);
    angle = radians(Math.random() * (25 - 15) + 15);
    resetMatrix();
    translate(width / 2, height);

    for (var i = 0; i < sentence.length; i++) {
        var current = sentence.charAt(i);
        var randomSeed = 2;
        if (current == 'F' || current == 'G') {
            ellipse(0, -len, 5);
            line(0, 0, 0, -len);
            translate(0, -len);
        } else if (current == '+') {
            let positiveRotation = angle * Math.random() * randomSeed;
            rotate(positiveRotation);
        } else if (current == '-') {
            let negativeRotation = -angle * Math.random() * randomSeed;
            rotate(negativeRotation);
        } else if (current == '[') {
            push();
        } else if (current == ']') {
            pop();
            count++;
        }
    }
    if (i >= sentence.length) {
        finished = true;
        console.log("done", count);
    }
}

function generateStems(iterations) {
    for (i = iterations - 1; i > 0 ; i--) {
        branch();
    }
}

function branch() {
    len *= Math.random() * (.52 - .45) + .45;
    var nextSentence = '';
    for (var i = 0; i < sentence.length; i++) {
        var current = sentence.charAt(i);
        var found = false;
        for (var j = 0; j < rules.length; j++) {
            if (current == rules[j].a) {
                found = true;
                nextSentence += rules[j].b;
                break;
            }
        }
        if (!found) {
            nextSentence += current;
        }
    }
    sentence = nextSentence;
    turtle();
}

function draw() {
    generateStems(4);
    noLoop();
}
var公理='F';
var语句=公理;
var len=300;
var计数=0;
var-arr=[];
var规则=[];
规则[0]={
a:‘F’,
b:'G[+F][F]GF'
};
规则[1]={
a:‘G’,
b:‘GG’
};
函数设置(){
createCanvas(window.innerWidth,window.innerHeight);
中风(10);
光滑的();
海龟();
}
函数{
背景(255);
冲程重量(1);
角度=弧度(数学随机()*(25-15)+15);
重置矩阵();
平移(宽度/2,高度);
for(变量i=0;i<句子长度;i++){
var电流=句子特征(i);
var-randomSeed=2;
如果(当前=='F'| |当前=='G'){
椭圆(0,-len,5);
线(0,0,0,-len);
平移(0,-len);
}else if(当前=='+'){
让positiveRotation=angle*Math.random()*randomSeed;
旋转(正旋转);
}否则如果(当前=='-'){
设negativeRotation=-angle*Math.random()*randomSeed;
旋转(负腐蚀);
}else if(当前=='['){
推();
}else if(当前==']'){
pop();
计数++;
}
}
如果(i>=句子长度){
完成=正确;
console.log(“完成”,计数);
}
}
函数generateStems(迭代){
对于(i=iterations-1;i>0;i--){
分支();
}
}
职能科(){
len*=Math.random()*(.52-.45)+.45;
var nextSentence='';
for(变量i=0;i<句子长度;i++){
var电流=句子特征(i);
var=false;
对于(var j=0;j

据我所知,目前p5.js对/操作和坐标空间转换的支持还不太成熟

理论上,您可以手动跟踪每一个变换(平移/旋转),并手动计算以获得变换的位置,然而,在实践中,这可能容易出错且繁琐

在处理过程中,您可以依靠该方法将一个点从一个坐标系转换到另一个坐标系,但目前在p5.js中不能。 这样的功能可以进一步简化

下面是一个基本示例(请注意
P3D
的用法):

目前,出于实际原因,如果必须计算转换后的位置,我建议将代码移植到Processing

更新根据您的评论,更容易使用L-系统为花朵引入新规则

假设
*
表示一朵花,您可以修改规则将其包含在最后一条指令中:
b:'G[+F][F]GF'
变为
b:'G[+F][F]GF*'

然后,当你遍历当前句子时,只需处理该符号:

var公理='F';
var语句=公理;
var len=300;
var计数=0;
var-arr=[];
var规则=[];
规则[0]={
a:‘F’,
b:'G[+F][F]GF*'
};
规则[1]={
a:‘G’,
b:‘GG’
};
函数设置(){
createCanvas(630630);
中风(10);
noFill();
光滑的();
海龟();
}
函数{
背景(255);
冲程重量(1);
角度=弧度(数学随机()*(25-15)+15);
重置矩阵();
平移(宽度/2,高度);
for(变量i=0;i<句子长度;i++){
var电流=句子特征(i);
var-randomSeed=2;
如果(当前=='F'| |当前=='G'){
椭圆(0,-len,5);
线(0,0,0,-len);
平移(0,-len);
//花规
}else if(当前=='*'){
花(6,len*0.618033);
}else if(当前=='+'){
让positiveRotation=angle*Math.random()*randomSeed;
旋转(正旋转);
}否则如果(当前=='-'){
设negativeRotation=-angle*Math.random()*randomSeed;
旋转(负腐蚀);
}else if(当前=='['){
推();
}else if(当前==']'){
pop();
计数++;
}
}
如果(i>=句子长度){
完成=正确;
//console.log(“完成”,计数);
}
}
功能花(侧边、边长){
beginShape();
设角度增量=两个_PI/边;
for(设i=0;i 0;i--){
分支();
}
}
职能科(){
len*=Math.random()*(.52-.45)+.45;
var nextSentence='';
for(变量i=0;i<句子长度;i++){
var电流=句子特征(i);
var=false;
对于(var j=0;jPVector v1 = new PVector();
float len = 100;

void setup(){
  size(300,300,P3D);
  noFill();
  strokeWeight(3);
}

void draw(){
  background(255);
  // isolate coordinate system
  pushMatrix();
  // apply a set of transformations
  translate(width / 2, height);
  translate(0,-len);
  rotate(radians(45));
  // draw a blue rectangle from the corner to illustrate this transformed position
  stroke(0,0,192);
  rect(0,0,30,30);
  // further transform
  translate(90,0);
  // draw a rect rectangle
  stroke(192,0,0);
  rect(0,0,30,30);
  // use screenX/screenY to calculate the transformed coordinates
  v1.set(screenX(0,0,0),screenY(0,0,0)); 
  popMatrix();

  // simply draw a (green) circle on top at the same transformed coordinates, without being in that local coordinate system 
  stroke(0,192,0);
  ellipse(v1.x, v1.y, 30, 30);
}