2012-08-26 251 views
0

首先,我畫了很多圈,他們稍微移動,因爲我在一個圓圈的中心添加了噪音。這些圓圈是「不可見的」,因爲它們具有與背景相同的顏色。第二,我畫了一些組合ellipse(mouseX,mouseY,random(1,3),random(1,3)),rect,line等的圖案。由於顏色,圖案也是「不可見的」。如何計算Processing中兩個因變量之間的距離?

第三,這就是問題所在,我想讓圓圈顯示出來(改變顏色),如果它們與圖案的距離小於一定值。

我怎樣才能計算這些圈子的中心和圖案的邊界之間的距離?他們都是因變量

然後我發現想一個辦法:讓它的問題比較陣列中的每個元素與數組中的所有其他元素https://forum.processing.org/topic/constantly-resizing-ellipse-based-on-distance, 但我仍然不知道如何修改形狀之類的函數ellipse(x,y,radius1,radius2)成一個數組。

也許是因爲Processing中的shape函數打包得很好,所以它們不容易被破壞和使用。我找到了一種計算點對點距離的方法: processing.org/discourse/beta/num_1276644884.html

但是我不明白,請給我任何提示。謝謝。

+0

距離如何定義?圓/橢圓的中心之間的距離或邊界之間的距離? – Ridcully

+0

圓圈的中心和圖案的邊框之間。 – kikkpunk

+0

你可以發佈圖案的圖片嗎?我認爲這只是橢圓形,但再次讀你的問題,你還提到矩形和線條。 – Ridcully

回答

1

你的問題主要是關於幾何和數學比約編程,但這裏有雲:顯然,他們中心的距離,減去其半徑之和:

  • 兩個圓的邊界之間的最小距離。圓和線段的邊界之間

  • 最小距離:參見thisthisthis和谷歌搜索的條款minimum distance between point and line segment的任何其他結果。再次,你將不得不減去半徑。

  • 圓形邊框與矩形/多邊形等之間的最小距離:每個單獨的段的最小距離。

  • 圓圈邊界與直線之間的最小距離:請參閱this

  • 圓形和橢圓邊界之間的最小距離:搜索「點和橢圓之間的最小距離」。有很多結果,比其他一些更直接。不要忘記減去圓的半徑。

如果一切都失敗了(例如對於任意形狀),您可能必須逐點並計算距離 - 效率不高,但通常是有效的。

一個重要的問題是:你對幾何重疊感興趣嗎(即由公式定義)還是在像素重疊?根據繪製算法,兩個形狀的屏幕上的表示可能會重疊,而在數學上形狀本身不會,反之亦然。

+0

另請參閱實現['Shape'](http://docs.oracle.com/javase/7/docs/api/java/awt/Shape.html)接口的類可用的方法。 – trashgod

+0

@thkala,thx但我不明白你提供的例子。我只知道處理語法的whick繪製形狀,如:線(x1,y1,x2,y2),橢圓(x,y,radius1,radius2)。所有的例子都在這裏http://processing.org/learning/basics/,我需要計算這些形狀上的點之間的距離。也許是因爲形狀函數打包的很好,不容易打破和使用它。我找到了一種計算點對點距離的方法http://processing.org/discourse/beta/num_1276644884.html – kikkpunk

0

在這一點上,您可能應該更多地關注編程基礎知識,而不是解決問題背後的數學問題。事實上,我們現在讓數學問題變得非常簡單,所以代碼不會太複雜:讓我們假裝你的模式是正方形的,而你只關心從圓心到「中心」的距離,圖案'/平方。例如橢圓()函數只會做一件事 - 將在屏幕上繪製一個橢圓,但您需要一些東西來跟蹤您使用的橢圓的屬性(如位置和大小)。

一個保持性能的跟蹤方法是將它們存儲在一個數組:

int numEllipses = 100; 
float[] ellipseXValues = new float[numEllipses]; 
float[] ellipseYValues = new float[numEllipses]; 
float[] ellipseSizeValues = new float[numEllipses]; 
//etc. 

對於每個屬性,你會使用一個數組,因爲你有多個橢圓形「對象」。類似於模式。如果你不熟悉數組,那麼以這種方式做事是一個很好的練習。你會注意到你的代碼將會非常快速地運行,但是當你學習時代碼看起來不那麼重要:它更多的是理解和跟蹤你所做的事情(而不是「比可以咀嚼的東西更多的東西」)。

另一種方法是使用類。類很酷,因爲它們允許你封裝與你想法相關的屬性和功能。例如,您可以創建自己的Ellipse類或Pattern類,該類將保存要使用的屬性(如位置,顏色等),但也可以具有函數(如Ellipse將呈現其自身的函數(如draw()函數)屏幕一種方式,但另一種模式)等等。 下面是一個例子:

class Circle{ 
    float x,y,vx,vy,size;//store position(x,y), velocity(vx,vy) and size 
    color clr;   //store color 
    Circle(float ax,float ay,float as,color ac){ 
    x = ax; 
    y = ay; 
    size = as; 
    clr = ac; 
    vx = random(-.1,.1);//random velocity 
    vy = random(-.1,.1); 
    } 
    void update(int w,int h){ 
    x += vx;//update position based on velocity 
    y += vy; 
    if(x < 0 || x > w) vx *= -1;//check bounds and flip velocity if there's a collision 
    if(y < 0 || y > h) vy *= -1; 
    } 
    void draw(){ 
    pushStyle();//start isolating drawing commands 
    noStroke(); 
    fill(clr); 
    ellipse(x,y,size,size); 
    popStyle();//stop isolating drawing commands 
    } 

} 

類就像是一個模板/藍圖 - 它可以是任何你想要的。例如,您可以有一個Vehicle類,該類有一個屬性numberOfWheels,它確定從該類創建的實例/對象的外觀如何:2個自行車,4個汽車等。同樣,您可以有一個Pattern類,它可能有與其相關的各種屬性/變量:條紋/點,數量,顏色列表等

下面是如何使用Circle類一個基本的例子:

Circle c; 
void setup(){ 
    size(400,400); 
    smooth(); 
    c = new Circle(200,200,20,color(192));//create a new object from the template/class using the *new* keyword 
} 
void draw(){ 
    background(255); 

    c.x = mouseX;//access and modify properties of the object 
    c.y = mouseY; 
    c.size = map(mouseX,0,width,20,200); 
    c.clr = color(map(mouseY,0,height,0,240)); 

    c.draw();//call a function/method of the object 
} 

通知之間的區別定義/類和對象(用新的實例化)。 如果你不熟悉課程已經檢查出Daniel Shiffman的優秀Objects tutorial。在處理中,您可以瀏覽示例>基本信息>對象>對象

(不那麼重要了。我使用的是map()功能可輕鬆連接鼠標位置一樣大小和顏色圓的性質)現在

,你可以創建自己的類型/類,你還可以創建這些對象的數組。 有一個基本的例子附帶處理:例子>基本>陣列> ArrayObjects

下面是我們如何使用Circle類(和一個非常類似的廣場)一起上課,在兩個不同的陣列和檢查的距離:

int maxCircles = 20; 
int maxSquares = 3; 
float minDist = 50; 
Circle[] circles = new Circle[maxCircles];//create an array Circle objects/instances 
Square[] squares = new Square[maxSquares]; 

void setup(){ 
    size(400,400); 
    smooth(); 
    colorMode(HSB,360,100,100); 
    for(int i = 0; i < maxCircles; i++) circles[i] = new Circle(random(width),random(height),random(4,10),color(0,0,100)); 
    for(int i = 0; i < maxSquares; i++) squares[i] = new Square(random(width),random(height),random(4,10),color(240)); 
} 
void draw(){ 
    background(0,0,95); 
    for(int i = 0; i < maxCircles; i++){ 
    circles[i].update(width,height); 

    for(int j = 0; j < maxSquares; j++){ 
     squares[j].update(width,height); 
     //use the dist() function to compute distances 
     float distance = dist(circles[i].x,circles[i].y,squares[j].x,squares[j].y); 
     if(distance < minDist){//based on that, if within a threshold, map colours/etc. 
     circles[i].clr = color( 0,map(distance,0,minDist,100,0),100); 
     } 

     squares[j].draw(); 
    } 
    circles[i].draw(); 
    } 
} 
class Circle{ 
    float x,y,vx,vy,size;//store position(x,y), velocity(vx,vy) and size 
    color clr;   //store color 
    Circle(float ax,float ay,float as,color ac){ 
    x = ax; 
    y = ay; 
    size = as; 
    clr = ac; 
    vx = random(-.1,.1);//random velocity 
    vy = random(-.1,.1); 
    } 
    void update(int w,int h){ 
    x += vx;//update position based on velocity 
    y += vy; 
    if(x < 0 || x > w) vx *= -1;//check bounds and flip velocity if there's a collision 
    if(y < 0 || y > h) vy *= -1; 
    } 
    void draw(){ 
    pushStyle();//start isolating drawing commands 
    noStroke(); 
    fill(clr); 
    ellipse(x,y,size,size); 
    popStyle();//stop isolating drawing commands 
    } 

} 
class Square{ 
    float x,y,vx,vy,size; 
    color clr; 
    Square(float ax,float ay,float as,color ac){ 
    x = ax; 
    y = ay; 
    size = as; 
    clr = ac; 
    vx = random(-.02,.02);//random velocity 
    vy = random(-.02,.02); 
    } 
    void update(int w,int h){ 
    x += vx; 
    y += vy; 
    if(x < 0 || x > w) vx *= -1; 
    if(y < 0 || y > h) vy *= -1; 
    } 
    void draw(){ 
    pushStyle(); 
    noStroke(); 
    fill(clr); 
    rect(x-size/2,y-size/2,size,size); 
    popStyle(); 
    } 

} 

正如您在註釋代碼中所看到的,在複雜的概念被簡化/封裝後,它只是循環訪問數組和檢查距離(使用dist())。

這裏有一個快速預覽,其中小方塊「假裝」是圖紋和影響圈的顏色自己周圍:

Circles and Squares

您還可以run the code online或波紋管:

var maxCircles = 20; 
 
var maxSquares = 3; 
 
var minDist = 150; 
 
var circles = new Array(maxCircles); 
 
var squares = new Array(maxSquares); 
 

 
function setup(){ 
 
    createCanvas(400,400); 
 
    smooth(); 
 
    colorMode(HSB,360,100,100); 
 
    for(var i = 0; i < maxCircles; i++) circles[i] = new Circle(random(width),random(height),random(4,10),color(0,0,100)); 
 
    for(i = 0; i < maxSquares; i++)  squares[i] = new Square(random(width),random(height),random(4,10),color(240)); 
 
} 
 
function draw(){ 
 
    background(0,0,95); 
 
    for(var i = 0; i < maxCircles; i++){ 
 
    circles[i].update(width,height); 
 
    for(var j = 0; j < maxSquares; j++){ 
 
     squares[j].update(width,height); 
 
     var distance = dist(circles[i].x,circles[i].y,squares[j].x,squares[j].y); 
 
     if(distance < minDist){ 
 
     circles[i].clr = color( 0,map(distance,0,minDist,100,0),100); 
 
     }squares[j].draw(); 
 
    } 
 
    circles[i].draw(); 
 
    } 
 
} 
 
function Circle(ax,ay,as,ac){ 
 
    this.x = ax; 
 
    this.y = ay; 
 
    this.size = as; 
 
    this.clr = ac; 
 
    this.vx = random(-.1,.1);//random velocity 
 
    this.vy = random(-.1,.1); 
 
    
 
    this.update = function(w,h){ 
 
    this.x += this.vx; 
 
    this.y += this.vy; 
 
    if(this.x < 0 || this.x > this.w) this.vx *= -1; 
 
    if(this.y < 0 || this.y > this.h) this.vy *= -1; 
 
    } 
 
    this.draw = function(){ 
 
    push(); 
 
    noStroke(); 
 
    fill(this.clr); 
 
    ellipse(this.x,this.y,this.size,this.size); 
 
    pop(); 
 
    } 
 
    
 
} 
 
function Square(ax,ay,as,ac){ 
 
    this.x = ax; 
 
    this.y = ay; 
 
    this.size = as; 
 
    this.clr = ac; 
 
    this.vx = random(-.02,.02);//random velocity 
 
    this.vy = random(-.02,.02); 
 
    
 
    this.update = function(w,h){ 
 
    this.x += this.vx; 
 
    this.y += this.vy; 
 
    if(this.x < 0 || this.x > this.w) this.vx *= -1; 
 
    if(this.y < 0 || this.y > this.h) this.vy *= -1; 
 
    } 
 
    this.draw = function(){ 
 
    push(); 
 
    noStroke(); 
 
    fill(this.clr); 
 
    rect(this.x-this.size/2,this.y-this.size/2,this.size,this.size); 
 
    pop(); 
 
    } 
 
    
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>

希望這個解釋這是處理這個問題的一個基本方法。你發現自己熟悉的語法和一些編程的概念之後應該是一個更容易潛入稍微更多的東西:

  • 你可能會發現陣列一定程度限制,因爲他們是固定的大小和可探索ArrayList
  • 您可能會發現基本距離函數對於複雜圖案來說不夠精確,並且可以找到其他計算距離的方法。

古德勒克

+0

Thx George,但是您能否更詳細地解釋此代碼:circles [i]。clr = color(0,map(distance,0,minDist,100,0),100);我認爲值的當前範圍的上限必須大於下限?順便說一句,遠距離的色彩褪色似乎不太好,我想適應它,但卡在上面的代碼。 – kikkpunk

+0

@ i'notaprogrammer這並不複雜,但是如果它分成兩行,可能會更容易理解:'float saturation = map(distance,0,minDist,100,0); 圈[i] .clr =顏色(0,飽和度,100);'。正如文獻中所描述的那樣,這張圖需要5個參數,例如:'價值,從Min,fromMax,toMin,toMax'。我已經使用了最後兩個值,因爲在我的演示中,我希望在最小距離上具有完全飽和度(100),當距離較大時不需要飽和度(0),基本上使用「更飽滿」的顏色來減小距離。隨意使用你認爲合適的地圖顏色。 –

1

有加工類,做了很多工作,這對你叫PVector。您可以使用繼承並創建一個新的類,即PVector。

或者你可以把你的座標變成一個PVector,用於計算。

println(new PVector(x1, y1).dist(new PVector(x2, y2))); 

注意:PVector也可用於3D向量和座標。

相關問題