我的问题是这个..我正在研究一些聚类算法..首先我正在试验2d形状..
鉴于特定区域说500sq单位..我需要为特定区域生成随机形状
说一个500平方米的矩形,正方形,三角形......等等。关于我应该如何解决这个问题的任何建议..我正在使用R语言..
答案 0 :(得分:6)
对常规多边形执行此操作非常简单。
具有半径为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)
}
答案 1 :(得分:1)
500平方公尺面积的随机平方很容易 - 它是一个方格(500)米的正方形。你关心轮换吗?然后用runif(x,0,2 * pi)旋转它。你关心它的位置吗?添加从runif或其他任何内容计算的(x,y)偏移量。
矩形?鉴于任何一对边的长度,您只能自由选择其他两边的长度。你如何选择第一对边的长度?好吧,您可能希望在应用程序的某些“明智”限制之间使用runif()。你可以使用rnorm(),但这可能会给你负长度,所以可能是rnorm-squared。然后,一旦你有那边,另一边长度是500 / L.旋转,翻译,加入盐和胡椒调味。
对于三角形,面积公式为半基础 - 高度。因此,生成一个基本长度 - 再次,runif,rnorm等等 - 然后选择另一个给出所需高度的点。旋转等
总的来说,一个形状有多个“自由度”,约束要修复的区域将至少限制其中一个自由[1],所以如果你开始用随机数建立一个形状,你会来到了你必须加入计算值的那一点。
[1]恰好一个?我不确定 - 这些在统计意义上不是自由度......
答案 2 :(得分:0)
我建议编码相邻小方块的随机游走,这样小方块的聚合可以是已知区域的任意形状。
答案 3 :(得分:-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};
}