2011-02-01 121 views
2

我的問題是這個..我正在研究一些聚類算法..對於這第一個我正在試驗2D形狀..如何生成指定區域的隨機形狀(R語言)。

給定一個特定區域說500sq單位..我需要生成一個特定的隨機形狀區域

說一個矩形,廣場,500個平方米單位三角。等等。我應該如何去這個問題的任何建議..我用R輸入語言..

+0

這在很大程度上取決於你如何想你的發行版的樣子。當你談論形狀時,隨機可能意味着很多不同的事情。 – tkerwin 2011-02-01 06:06:33

回答

6

這是相當簡單的,爲正多邊形做到這一點。

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) 
    } 
-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}; 
} 
+0

這將是很難轉移 - 因爲它是在... – nico 2011-02-01 07:52:56

+1

困難?幾乎不!其中只有三條線很重要。 – Spacedman 2011-02-01 08:26:01

1

區域500米^ 2的隨機正方形容易 - 其側SQRT(500)米的正方形。你關心旋轉嗎?然後通過runif(x,0,2 * pi)旋轉它。你關心它的位置嗎?添加一個(x,y)從runif或其他值計算的偏移量。

矩形?考慮到任何一對邊的長度,你只能自由選擇另外兩邊的長度。你如何選擇第一對邊的長度?那麼,你可能想在你的應用程序的某些「明智」限制之間使用runif()。你可以使用rnorm(),但這可能會給你負的長度,所以也許是rnorm平方。然後,一旦你有了那邊,另一邊的長度是500/L。旋轉,翻譯,並添加鹽和胡椒口味。

對於三角形,面積公式是半鹼基倍高。因此,生成一個基準長度 - 再次,runif,rnorm等等 - 然後選擇另一個要求的高度。旋轉等。

總而言之,一個形狀具有許多「自由度」,並且約束要固定的區域將限制這些自由中的至少一個[1],因此如果您開始用隨機構建一個形狀數字你會來到一個點,你必須把一個計算值。

[1]正好一個?我不知道 - 這些都不是度在統計意義上的自由......