Javascript 计算任意生成线的半边/面

Javascript 计算任意生成线的半边/面,javascript,html,canvas,Javascript,Html,Canvas,我在Doob先生那里找到了这个,它生成了一个线网。我已经计算出一条线的起点和终点。现在我想从这些形状中挤出面,但是我只有线和顶点。我试图通读一些半边理论,但我认为我不太理解它 这是一个跟随一条线直到它变成矩形的问题,检查它是否与一条线相交或细分?我需要一个方向正确的碰撞 // Based on Jared Tarbell's Substrate algorithm concept. // http://www.complexification.net/gallery/machines/subst

我在Doob先生那里找到了这个,它生成了一个线网。我已经计算出一条线的起点和终点。现在我想从这些形状中挤出面,但是我只有线和顶点。我试图通读一些半边理论,但我认为我不太理解它

这是一个跟随一条线直到它变成矩形的问题,检查它是否与一条线相交或细分?我需要一个方向正确的碰撞

// Based on Jared Tarbell's Substrate algorithm concept.
// http://www.complexification.net/gallery/machines/substrate/index.php

var Boid = function ( x, y, angle ) {

    this.x = x;
    this.y = y;

    this.angle = Math.pow( Math.random(), 20 ) + angle;
    this.dx = Math.cos( this.angle );
    this.dy = Math.sin( this.angle );

    this.life = Math.random() * 100 + 100;
    this.dead = false;

    this.update = function () {

        context.strokeStyle = '#000000';
        context.beginPath();
        context.moveTo( this.x, this.y );

        this.x += this.dx * 2;
        this.y += this.dy * 2;
        this.life -= 2;

        context.lineTo( this.x, this.y );
        context.stroke();

        var index = ( Math.floor( this.x ) + width * Math.floor( this.y ) ) * 4;

        if ( this.life <= 0 ) this.kill();
        if ( data[ index + 3 ] > 0 ) this.kill();

        if ( this.x < 0 || this.x > width ) this.kill();                        
        if ( this.y < 0 || this.y > height ) this.kill();

    }

    this.kill = function () {

        boids.splice( boids.indexOf( this ), 1 );
        this.dead = true;

    }

}

var width = window.innerWidth;
var height = window.innerHeight;

var canvas = document.getElementById( 'world' );
canvas.width = width;
canvas.height = height;

var context = canvas.getContext( '2d' );
var image, data;

var boids = [];
boids.push( new Boid( width / 2, height / 2, Math.random() * 360 * Math.PI / 180 ) );

setInterval( function () {

    image = context.getImageData( 0, 0, width, height );
    data = image.data;

    for ( var i = 0; i < boids.length; i ++ ) {

        var boid = boids[ i ];
        boid.update();

        if ( !boid.dead && Math.random() > 0.5 && boids.length < 500 ) {

            boids.push( new Boid( boid.x, boid.y, ( Math.random() > 0.5 ? 90 : - 90 ) * Math.PI / 180 + boid.angle ) );

        }

    }

}, 1000 / 60 );
//基于Jared Tarbell的底层算法概念。
// http://www.complexification.net/gallery/machines/substrate/index.php
var Boid=函数(x,y,角度){
这个.x=x;
这个。y=y;
this.angle=Math.pow(Math.random(),20)+angle;
this.dx=Math.cos(this.angle);
this.dy=Math.sin(this.angle);
this.life=Math.random()*100+100;
这个死=假;
this.update=函数(){
context.strokeStyle='#000000';
context.beginPath();
context.moveTo(this.x,this.y);
this.x+=this.dx*2;
this.y+=this.dy*2;
这个生命-=2;
context.lineTo(this.x,this.y);
stroke();
var指数=(数学地板(this.x)+宽度*数学地板(this.y))*4;
如果(this.life)this.kill();
如果(this.x<0 | | this.x>宽度)this.kill();
如果(this.y<0 | | this.y>高度)this.kill();
}
this.kill=函数(){
boids.拼接(boids.indexOf(this),1);
这是真的;
}
}
变量宽度=window.innerWidth;
var height=window.innerHeight;
var canvas=document.getElementById('world');
画布宽度=宽度;
canvas.height=高度;
var context=canvas.getContext('2d');
var图像、数据;
var boids=[];
push(新的Boid(宽度/2,高度/2,Math.random()*360*Math.PI/180));
setInterval(函数(){
image=context.getImageData(0,0,宽度,高度);
data=image.data;
对于(变量i=0;i0.5&&boids.length<500){
Boid.push(新的Boid(Boid.x,Boid.y,(Math.random()>0.5?90:-90)*Math.PI/180+Boid.angle));
}
}
}, 1000 / 60 );

这看起来比我想象的要复杂。我不确定这是否是您要求的答案,但可能会帮助您决定下一步:

如果您必须使用此算法:我认为您需要跟踪构成边的每一对点:第一个点位于
Boid
函数的开头,第二个点在
Boid
被终止时;这两个点(或x1、x2、y1和y2值)都保存在一个新的
edge
对象中,该对象将添加到
edges
数组中(每个
edge
都将是死亡的灵魂
Boid

在应用之前,有两个问题:您有一组边,但需要知道哪些其他边连接到给定边的起点或终点。另一个问题是,两个Boid之间的“冲突”只会影响当前正在更新的Boid,该Boid在冲突期间被终止。为了使用半边理论,您必须“通知”另一个Boid/边有关此碰撞并在该点拆分:碰撞点是三条边的顶点,一条发生碰撞,另一条发生碰撞的边被拆分

还要注意的是,形状(面)不一定是由四条边组成的,我打开了你提供的链接,那里有很多带有树和五条边的形状


如果可以使用不同的算法生成网格,则可以更好地表示边和顶点,这将帮助您找到构成每个形状的“角点”

你的问题看起来很有趣:)但是我需要更多的信息,这样我可以帮助你(或者知道我是否可以)。“挤出面”和“这些形状”是什么意思;“这些形状”是您正在绘制的多边形区域吗?“挤出面”是指绘制“三维建筑的二维表示”?(模拟在blender或3DStudio中可以执行的操作)确定。因此,脚本动态地绘制相互相交的线。我想做的是确定画布上线条所反映的形成形状的4个点。到目前为止,点是独立的,没有任何“连接”的方式。我对three.js没有太多经验,但我相信你需要顶点来创建边。关于这个算法:如果你要使用这个算法,你应该添加一个终止条件;您可以将间隔的初始化更改为
var myIntervalId=setInterval(theFunctionHere)
,并在for循环之后添加
if(boids.length==0){clearInterval(myIntervalId)}
。谢谢。是的,当一个boid与另一个boid碰撞时,我需要弄清楚。当它碰撞时,我知道x,y,所以接下来的问题是找出它与哪个boid碰撞。我必须遍历每一个boid来检查x,y是否位于一个特定的boid上。这对性能真的不好吗?除了穿过每一条线,每一次碰撞,还有更好的方法吗?是的,该脚本生成的BOID数量对性能非常不利,除非您可以减小画布的大小或BOID的数量:我的屏幕是1920x1080,并且随着BOID数量的增加,绘图速度会减慢。我想不出更好的解决方案,但一定有更好的解决方案。如果要测试已绘制的每条直线(边数组),可以向该边添加一个字段,该字段保存直线的坡度(渐变)和一个函数,该函数计算该坡度(一次并保存),然后使用直线方程确定给定点(碰撞点)是否位于直线上。最好能找到另一种算法,它能为您提供更好的表示形式