我的問題是這個..我正在研究一些聚類算法..對於這第一個我正在試驗2D形狀..如何生成指定區域的隨機形狀(R語言)。
給定一個特定區域說500sq單位..我需要生成一個特定的隨機形狀區域
說一個矩形,廣場,500個平方米單位三角。等等。我應該如何去這個問題的任何建議..我用R輸入語言..
我的問題是這個..我正在研究一些聚類算法..對於這第一個我正在試驗2D形狀..如何生成指定區域的隨機形狀(R語言)。
給定一個特定區域說500sq單位..我需要生成一個特定的隨機形狀區域
說一個矩形,廣場,500個平方米單位三角。等等。我應該如何去這個問題的任何建議..我用R輸入語言..
這是相當簡單的,爲正多邊形做到這一點。
n邊規則多邊形的面積,半徑爲R的外接圓是
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)
}
這將是非常艱難的做一個通用的方法。 但是,您可以編寫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};
}
區域500米^ 2的隨機正方形容易 - 其側SQRT(500)米的正方形。你關心旋轉嗎?然後通過runif(x,0,2 * pi)旋轉它。你關心它的位置嗎?添加一個(x,y)從runif或其他值計算的偏移量。
矩形?考慮到任何一對邊的長度,你只能自由選擇另外兩邊的長度。你如何選擇第一對邊的長度?那麼,你可能想在你的應用程序的某些「明智」限制之間使用runif()。你可以使用rnorm(),但這可能會給你負的長度,所以也許是rnorm平方。然後,一旦你有了那邊,另一邊的長度是500/L。旋轉,翻譯,並添加鹽和胡椒口味。
對於三角形,面積公式是半鹼基倍高。因此,生成一個基準長度 - 再次,runif,rnorm等等 - 然後選擇另一個要求的高度。旋轉等。
總而言之,一個形狀具有許多「自由度」,並且約束要固定的區域將限制這些自由中的至少一個[1],因此如果您開始用隨機構建一個形狀數字你會來到一個點,你必須把一個計算值。
[1]正好一個?我不知道 - 這些都不是度在統計意義上的自由......
我會建議編碼隨機遊走相鄰的小方塊,這樣聚合的小方塊可以是已知區域的任意形狀。
這在很大程度上取決於你如何想你的發行版的樣子。當你談論形狀時,隨機可能意味着很多不同的事情。 – tkerwin 2011-02-01 06:06:33