0

まず、たくさんの円を描いていますが、円の中心にノイズを追加しているため、円がわずかに動いています。これらの円は、背景と同じ色であるため、「見えません」。

ellipse(mouseX,mouseY,random(1,3),random(1,3))次に、rect、 、 などを組み合わせていくつかのパターンを描きますline。パターンも色のために「見えません」。

第三に、これが問題です。パターンからの距離が一定量未満の場合、円を表示 (色を変更) したいと考えています。

それらの円の中心とパターンの境界線の間の距離を計算するにはどうすればよいですか? どちらも従属変数です

そして、私は考える1つの方法を見つけました:配列内の各要素を配列内の他のすべての要素と比較する問題にすること https://forum.processing.org/topic/constantly-resizing-ellipse-based-on- distanceですが、形状関数をellipse(x,y,radius1,radius2)配列に変更する方法がまだわかりません。

おそらく、Processing の形状関数は非常にうまくパッケージ化されているため、簡単に壊して使用することはできません。ポイントからラインまでの距離を計算する方法を見つけました: processing.org/discourse/beta/num_1276644884.html

しかし、私はそれを理解していません.私にヒントを教えてください.ありがとう.

4

3 に答える 3

1

あなたの質問は、プログラミングよりも主に幾何学と数学に関するものですが、次のようになります。

  • 2 つの円の境界間の最小距離: 明らかに、それらの中心の距離から半径の合計を引いたものです。

  • 円の境界線と線分の間の最小距離: thisthisthis、および用語を使用した Google 検索のその他の結果を参照してくださいminimum distance between point and line segment。もう一度、半径を減算する必要があります。

  • 円と長方形/多角形などの境界間の最小距離: 各セグメントのすべての距離の最小値。

  • 円の境界と線との間の最小距離: こちらを参照してください。

  • 円と楕円の境界間の最小距離: 「点と楕円の間の最小距離」を検索します。多くの結果があり、いくつかは他よりも簡単です。円の半径を引くことを忘れないでください。

他のすべてが失敗した場合 (たとえば、任意の形状の場合)、ポイントごとに移動して距離を計算する必要がある場合があります。あまり効率的ではありませんが、通常は効果的です。

重要な質問: ジオメトリック オーバーラップ (式で定義されたもの) またはピクセルオーバーラップに関心がありますか? 描画アルゴリズムによっては、2 つの形状の画面上の表現が重なり合う場合がありますが、数学的には形状自体は重なりません。

于 2012-08-26T09:08:05.467 に答える
1

PVectorと呼ばれるこの作業の多くを行う処理クラスがあります。継承を使用して、 PVectorを拡張する新しいクラスを作成できます。

または、座標を取得して、計算のためにその場で PVector に変更することもできます。

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

注: PVector は、3D ベクトルと座標に対しても機能します。

于 2012-09-01T18:50:36.533 に答える
0

この時点で、問題を解決するための数学よりも、プログラミングの基礎を習得することの方が心配になるはずです。実際、ここでは数学の問題を非常に単純にして、コードが複雑になりすぎないようにしましょう。パターンが正方形で、円の中心から中心までの距離だけに関心があるとしましょう。パターン」/正方形。

たとえば、ellipse() 関数は 1 つのことしか行いません。画面上に楕円を描画しますが、使用する楕円のプロパティ (位置やサイズなど) を追跡するために何かが必要になります。

プロパティを追跡する 1 つの方法は、それらを配列に格納することです。

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

複数の楕円「オブジェクト」があるため、プロパティごとに配列を使用します。パターンについても同様です。配列にまだ慣れていない場合は、この方法で作業することをお勧めします。コードが非常に速く長くなることに気付くでしょうが、学ぶときはコードがどのように見えるかはそれほど重要ではありません。

これを行う別の方法は、クラスを使用することです。クラスが優れているのは、思いついたアイデアに関連するプロパティと機能をカプセル化できるからです。たとえば、独自のEllipseクラス、またはPattern使用するプロパティ (位置、色など) を保持するクラスを作成できますが、関数 (楕円が画面 1 にレンダリングされる 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するプロパティを持つクラスを持つことができます: 2 人用のバイク、4 人用の車など。同様に、クラスを持つことができ、さまざまなプロパティを持つことができます。 /それに関連する変数: ストライプ/ドットの数、色のリストなどnumberOfWheelsPattern

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
}

定義/クラスとオブジェクト ( newでインスタンス化) の違いに注意してください。クラスにまだ慣れていない場合は、Daniel Shiffmanの優れたオブジェクト チュートリアルを参照してください。Processing では、 Examples > Basics > Objects > Objectsを調べることができます。

(あまり重要ではありません: map()関数を使用して、マウスの位置をサイズや色などの円のプロパティに簡単にリンクしています。)

独自のタイプ/クラスを作成できるようになったので、そのようなオブジェクトの配列を作成することもできます。Processing に同梱されている基本的な例があります: Examples > Basics > Arrays > ArrayObjects

Circle クラス (および非常によく似た Square) クラスを 2 つの別個の配列で一緒に使用し、距離をチェックする方法は次のとおりです。

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()を使用)。

これは簡単なプレビューです。小さな四角形がパターンのように「ふり」、周囲の円の色に影響を与えます。

丸と四角

コードをオンラインまたは以下で実行することもできます。

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>

うまくいけば、これは問題に対処するための基本的な方法の 1 つを説明します。構文といくつかのプログラミングの概念に慣れてきたら、もう少し多くのことに飛び込むのがはるかに簡単になるはずです。

  • 配列は固定サイズであり、 ArrayListを調べることができるため、配列が多少制限される場合があります。
  • 基本的な距離関数は複雑なパターンに対して十分に正確ではないことがわかり、距離を計算する他の方法を見つけることができます。

幸運を

于 2012-08-27T08:44:29.323 に答える