2011-02-01 77 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]正好一个?我不知道 - 这些都不是度在统计意义上的自由......