我的问题是这个..我正在研究一些聚类算法..对于这第一个我正在试验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