私の質問はこれです..私はいくつかのクラスタリングアルゴリズムに取り組んでいます..この最初の私は2D形状を実験しています..
特定の領域を指定すると、500sqユニットと言います..特定の領域のランダムな形状を生成する必要があります
500平方単位の長方形、正方形、三角形などを言います。この問題をどのように処理するかについての提案はあります。私はR言語を使用しています。
正多角形に対してこれを行うのはかなり簡単です。
半径Rの外接円を持つn辺の正多角形の面積は次のとおりです。
A = 1/2 nR^2 * sin((2pi)/n)
したがって、nとAがわかれば、Rを簡単に見つけることができます。
R = sqrt((2*A)/(n*sin((2pi)/n))
したがって、中心を選択し、距離Rに移動して、2pi/n
角度の増分でnポイントを生成できます。
Rの場合:
regular.poly <- function(nSides, area)
{
# Find the radius of the circumscribed circle
radius <- sqrt((2*area)/(nSides*sin((2*pi)/nSides)))
# I assume the center is at (0;0) and the first point lies at (0; radius)
points <- list(x=NULL, y=NULL)
angles <- (2*pi)/nSides * 1:nSides
points$x <- cos(angles) * radius
points$y <- sin(angles) * radius
return (points);
}
# Some examples
par(mfrow=c(3,3))
for (i in 3:11)
{
p <- regular.poly(i, 100)
plot(0, 0, "n", xlim=c(-10, 10), ylim=c(-10, 10), xlab="", ylab="", main=paste("n=", i))
polygon(p)
}
一般的な凸多角形に外挿することができます。
凸多角形の面積は次のようになります。
A = 1/2 * [(x1*y2 + x2*y3 + ... + xn*y1) - (y1*x2 + y2*x3 + ... + yn*x1)]
上記のようにポリゴンを生成しますが、角度と半径は正多角形のものとは異なります。
次に、ポイントをスケーリングして、目的の領域を取得します。
convex.poly <- function(nSides, area)
{
# Find the radius of the circumscribed circle, and the angle of each point if this was a regular polygon
radius <- sqrt((2*area)/(nSides*sin((2*pi)/nSides)))
angle <- (2*pi)/nSides
# Randomize the radii/angles
radii <- rnorm(nSides, radius, radius/10)
angles <- rnorm(nSides, angle, angle/10) * 1:nSides
angles <- sort(angles)
points <- list(x=NULL, y=NULL)
points$x <- cos(angles) * radii
points$y <- sin(angles) * radii
# Find the area of the polygon
m <- matrix(unlist(points), ncol=2)
m <- rbind(m, m[1,])
current.area <- 0.5 * (sum(m[1:nSides,1]*m[2:(nSides+1),2]) - sum(m[1:nSides,2]*m[2:(nSides+1),1]))
points$x <- points$x * sqrt(area/current.area)
points$y <- points$y * sqrt(area/current.area)
return (points)
}
面積500m^2のランダムな正方形は簡単です-その辺の正方形はsqrt(500)mです。回転は気になりますか?次に、runif(x、0,2 * pi)で回転させます。あなたはその場所を気にしますか?runifなどから計算された(x、y)オフセットを追加します。
矩形?辺のいずれか1組の長さを考えると、他の2つの辺の長さを選択する自由しかありません。辺の最初のペアの長さをどのように選択しますか?さて、あなたはあなたのアプリケーションのためにいくつかの「賢明な」制限の間にrunif()を使用したいかもしれません。rnorm()を使用することもできますが、負の長さになる可能性があるため、rnorm-squaredである可能性があります。次に、その側を取得すると、反対側の長さは500/Lになります。回転させ、翻訳し、塩こしょうを加えて味を整えます。
三角形の場合、面積の式は底辺の半分の高さです。したがって、ベースの長さ(runif、rnormなど)を生成してから、必要な高さを指定して別のポイントを選択します。回転など
要約すると、形状にはいくつかの「自由度」があり、固定する領域を制限すると、それらの自由度の少なくとも1つが制限されます[1]。したがって、乱数を使用して形状を作成し始めると、ポイントに到達します。ここで、計算値を入力する必要があります。
[1]ちょうど1つ?よくわかりません-これらは統計的な意味での自由度ではありません...
小さな正方形の集合が既知の面積を持つ任意の形状になるように、隣接する小さな正方形のランダムウォークをコーディングすることをお勧めします。
一般的なメソッドを作成するのは非常に困難です。ただし、3面、4面、5面のオブジェクトの例をコーディングできます。ランダムな三角形の例を次に示します (C# の場合)。
class Triangle
{
double Angle1;
double Angle2;
//double angle3; 180 - angle1 - angle2;
double Base;
}
Triangle randomTriangle(double area){
//A = (base*hieght)/2.0;
double angle1 = *random number < 180*;
double angle2 = *random number < (180 - angle1)*;
*use trig to get height in terms of angles and base*
double base = (area*2.0)/height;
return new Triangle(){Angle1 = angle1, Angle2 = angle2, Base = base};
}