3

特定の粒子の成長パターンを分析しており、その点パターンを、同じ強度 (単位面積あたりの点数が同じ) の完全な六方格子のパターンと比較したいと考えています。これを行う関数を作成しましたが、固有のエラーがあり、どこから発生したのかわかりません。基本的に、関数がコースを実行した後、正確な数の粒子を持たない完全な六角形の点パターンが生成されます。通常、約 1 ~ 4% ずれています。次のコードをコピーして R に貼り付けると、次のことがわかります。この特定の例では、誤差は 11.25% です。元の点パターンには 71 個の粒子があり、生成された完全な六角形の点パターンには 80 個の粒子があります。これは非常に奇妙に思えます。

以下は、六方格子を生成するために私が書いた関数のコードです。

library(spatstat)

data(swedishpines)

swedishpines.df <- as.data.frame(swedishpines)

MaxXValue <- max(swedishpines.df[1])
MaxYValue <- max(swedishpines.df[2])
#The above two lines dictate the window size
NumberOfParticles <- nrow(swedishpines.df[1])
#Number of entries = number of particles

#calculate delta
intensity <- NumberOfParticles / (MaxXValue*MaxYValue)
#Intensity ---> particles / unit^2
    #Area = ( sqrt(3) / 2 ) * delta^2
    #Now - in substituting intensity in for area, it is key to recognize 
    #that there are 3 particles associated with each hexagonal tile.
    #This is because each particle on the border of the tile is really 1/3 of a 
    #a particle due to it being associated with 3 different hexagonal tiles.  
    #Since intensity = 3 Particles / Area, 
delta <- sqrt(2/(intensity*(sqrt(3))))
#This is derived from the equation for the area of a regular hexagon. 

六方格子の単位格子の図

#xcoords and ycoords represent the x and y coordintes of all of the generated points.  The 'x' and 'y' are temporary holders for the x and y coordinates of a single horizontal line of points (they are appended to xcoords and ycoords at the end of each while loop).  

xcoords <- c()
ycoords <- c()

#The following large while loop calculates the coordinates of the first set of points that are vertically aligned with one another. (alternating horizontal lines of particles)  This is shown in the image below.

最初のポイント セット

y_shift <- 0
while (y_shift < MaxYValue) {

    x <- c(0)
    x_shift <- 0 + delta
    count <- 0

    while (x_shift < MaxXValue) {
        x <- append(x, x_shift)
        x_shift <- x_shift + delta
        count <- count + 1
    }

    y <- c(y_shift)

    for (i in seq(0,(count-1))) {
        y <- append(y, y_shift)
    }

    y_shift <- y_shift + sqrt(3)*delta
    xcoords <- append(xcoords,x)
    ycoords <- append(ycoords,y)

}

#The following large while loop calculates the coordinates of the second set of points that are vertically aligned with one another. This is shown in the image below. 

ポイントの 2 番目のセット

y_shift <- 0 + (delta*(sqrt(3)))/2
while (y_shift < MaxYValue) {

    x <- c(0 + (1/2)*delta)
    x_shift <- 0 + (1/2)*delta + delta
    count <- 0

    while (x_shift < MaxXValue) {
        x <- append(x, x_shift)
        x_shift <- x_shift + delta
        count <- count + 1
    }

    y <- c(y_shift)

    for (i in seq(0,(count-1))) {
        y <- append(y, y_shift)
    }

    y_shift <- y_shift + sqrt(3)*delta
    xcoords <- append(xcoords,x)
    ycoords <- append(ycoords,y)

}

hexplot <- ppp(xcoords, ycoords, window=owin(c(0,MaxXValue),c(0,MaxYValue)))

両方のセットが合体

現在、私は R に比較的慣れていないため、このエラーの原因となったコードのどこかで構文エラーが発生している可能性があります。あるいは、このプロセスの思考回路に何らかの誤りがあるのか​​もしれません。しかし、私の結果は私が試みてきたものに非常に近いので、その可能性は低いと思います (ほとんどの場合、わずか 1 ~ 4% の誤差で十分です)。

要約すると、私が助けてほしいのは、ポイント パターンを取得し、同じウィンドウ サイズの別のポイント パターンを同じ数の粒子で作成する方法ですが、完全に六角形のポイント パターンです。

ご不明な点がございましたら、お気軽にお問い合わせください。

ありがとう!

4

2 に答える 2

4

私が間違っている場合は申し訳ありませんが、例で示した制約を考えると、(一般的なケースでは) やろうとしていることは不可能だと思います。簡単に言えば、ウィンドウと同じ高さと幅のページに 71 個のポイントを六角形パターンで描く方法を思いつくことができますか? そのようなパターンは存在しないと思います。

さらに説明するには、コードの最後の行を検討してください。

hexplot <- ppp(xcoords, ycoords, window=owin(c(0,MaxXValue),c(0,MaxYValue)))

ここで、ウィンドウが元のデータと同じサイズであるため、同じ強度を得るには、まったく同じ数のポイント (71) が必要になります。ポイントの六角形の配置には、x 行があり、それぞれに y ポイントが含まれています。しかし、乗算すると 71 になる整数 x と y はありません。

そうは言っても、ウィンドウの幅を少し「伸ばす」と、行の半分にもう 1 つのポイントが含まれます。これは少し緩い制約ですが、一般的なケースで解決策があるという保証はありません。

したがって、まったく同じポイント強度を得るには、相対的なウィンドウ サイズを変更できる必要があります。空白を追加してポイントの強度を下げるには、引き伸ばす必要があります。それはまだ一般的なケースではうまくいかないかもしれません...しかし、私はそれを解決していません。単純なグリッドから始めて、コードを六角形に拡張するのが最も簡単かもしれません。


whileあなたのコードを見て、関数を使用できたときにループを使用していることに気付きましたseq。たとえば、x0 から でMaxXValue増加するすべてのポイントを生成したい場合は、次のようにsqrt(3)*deltaします。

x<-seq(0,MaxXValue,by=delta)

その大きな代わりにwhile。ここにいくつかのエラーがあるかもしれませんが、コード全体を次のように減らすことができると思います:

library(spatstat)
data(swedishpines)
swedishpines.df <- as.data.frame(swedishpines)
MaxXValue <- max(swedishpines.df[1])
MaxYValue <- max(swedishpines.df[2])
NumberOfParticles <- nrow(swedishpines.df)
intensity <- NumberOfParticles / (MaxXValue*MaxYValue)
delta <- sqrt(2/(intensity*(sqrt(3))))
x<-seq(0,MaxXValue,by=delta)
y<-seq(0,MaxYValue,by=sqrt(3)*delta)
first.coords=merge(x,y) # Find every combo of x and y
x=seq(delta/2,MaxXValue,by=delta)
y=delta*sqrt(3)/2 + (delta*sqrt(3)*seq(0,length(x)/2))
second.coords=merge(x,y)
coords=rbind(first.coords,second.coords)
ppp(coords$x, coords$y, window=owin(c(0,MaxXValue),c(0,MaxYValue)))

最後に、あなたのコメントで、六角形の面積( sqrt(3) / 2 ) * delta^2(3*sqrt(3)/2) * delta^2`


Josh O'Brien のコメントに興味があり、必要な正確なポイント数を取得するためにローテーション関数を実装することにしました。コードは次のとおりです。

# Include all above code
rotate=function(deg) {
    r=matrix(c(cos(deg),-sin(deg),sin(deg),cos(deg)),byrow=T,nrow=2)
    rotated.coords=data.frame(t(r %*% t(as.matrix(coords))))
    names(rotated.coords)=c('x','y')
    rotated.coords
}

rotate.optim=function(deg) {
    rotated.coords=rotate(deg)
    abs(NumberOfParticles-length(suppressWarnings(ppp(rotated.coords$x, rotated.coords$y, window=owin(c(0,MaxXValue),c(0,MaxYValue)))$x)))
}

o=optim(0,rotate.optim,lower=0,upper=2*pi,method='Brent')
rotated.coords=rotate(o$par)
rotated.coords.window=rotated.coords[rotated.coords$x >= 0 & rotated.coords$y >= 0 & rotated.coords$x <= MaxXValue & rotated.coords$y <= MaxYValue,]
final=ppp(rotated.coords.window$x,rotated.coords.window$y,window=owin(c(0,MaxXValue),c(0,MaxYValue)))
plot(final)

回転した 16 進プロット

于 2012-07-31T22:21:56.763 に答える
0

完全を期すために、spatstathexgridには六角形のグリッドを生成する機能がありrotate.ppp、後でパターンを回転させるために適用できる機能があることを付け加えておきます。

于 2015-01-27T22:37:20.720 に答える