[cos(th) | -sin(th)] [sin(th) | cos(th)],
for any angle "th". More generally, with 1 <= i < j <= k, if we replace elements (i, i), (i, j), (j, i), (j, j) with the elements of this 2x2 matrix, we get a k x k orthogonal matrix. Moreover, if my memory is correct, I believe there is a theorem that says that any orthogonal matrix can be decomposed into a product of 2-dimensional rotations like this.
Therefore, if you can decompose the rotation you want into a sequence of 2-dimensional rotations, then you have the rotation you want.
hope this helps. spencer graves
Richard A. O'Keefe wrote:
Barry Rowlingson <[EMAIL PROTECTED]> provided functions PolygonArea and PolygonCenterOfMass.
As an exercise in R programming, I thought "why don't I vectorise these and then see if it makes a practical difference".
Here are my versions of his functions. Somehow I ended up with a sign error when I entered his centroid code, so I had better exhibit the code that I actually tested.
polygon.area <- function (polygon) { N <- dim(polygon)[1] area <- 0 for (i in 1:N) { j <- i %% N + 1 area <- area + polygon[i,1]*polygon[j,2] - polygon[i,2]*polygon[j,1] } abs(area/2) }
polygon.centroid <- function(polygon) {
N <- dim(polygon)[1]
cx <- cy <- 0
for (i in 1:N) {
j <- i %% N + 1
factor <- polygon[j,1]*polygon[i,2] - polygon[i,1]*polygon[j,2]
cx <- cx + (polygon[i,1]+polygon[j,1])*factor
cy <- cy + (polygon[i,2]+polygon[j,2])*factor
}
factor <- 1/(6*polygon.area(polygon))
c(cx*factor, cy*factor)
}
Here are vectorised versions. I found myself wishing for a function to
rotate a vector. Is there one? I know about ?lag, but
help.search("rotate") didn't find anything to the point.
vectorised.area <- function(polygon) {
ix <- c(2:dim(polygon)[1], 1)
xs <- polygon[,1] ys <- polygon[,2]
abs(sum(xs*ys[ix]) - sum(xs[ix]*ys))/2
}
vectorised.centroid <- function(polygon) {
ix <- c(2:dim(polygon)[1], 1)
xs <- polygon[,1]; xr <- xs[ix]
ys <- polygon[,2]; yr <- ys[ix]
factor <- xr*ys - xs*yr
cx <- sum((xs+xr)*factor)
cy <- sum((ys+yr)*factor)
scale <- 3*abs(sum(xs*yr) - sum(xr*ys))
c(cx/scale, cy/scale)
}
Test case 1: unit square.
p <- rbind(c(0,0), c(0,1), c(1,1), c(1,0)) polygon.area(p)
[1] 1
vectorised.area(p)
[1] 1
polygon.centroid(p)
[1] 0.5 0.5
vectorised.centroid(p)
[1] 0.5 0.5
system.time(for (i in 1:1000) polygon.area(p))
[1] 0.56 0.02 0.58 0.00 0.00
system.time(for (i in 1:1000) vectorised.area(p))
[1] 0.22 0.03 0.25 0.00 0.00
system.time(for (i in 1:1000) polygon.centroid(p))
[1] 1.56 0.06 1.66 0.00 0.00
system.time(for (i in 1:1000) vectorised.centroid(p))
[1] 0.35 0.04 0.39 0.00 0.00
Even for a polygon this small, vectorising pays off.
Test case 2: random 20-gon.
p <- cbind(runif(20), runif(20)) polygon.area(p)
[1] 0.2263327
vectorised.area(p)
[1] 0.2263327
polygon.centroid(p)
[1] 0.6820708 0.5196700
vectorised.centroid(p)
[1] 0.6820708 0.5196700
system.time(for (i in 1:1000) polygon.area(p))
[1] 2.49 0.03 2.61 0.00 0.00
system.time(for (i in 1:1000) vectorised.area(p))
[1] 0.29 0.05 0.34 0.00 0.00
system.time(for (i in 1:1000) polygon.centroid(p))
[1] 7.29 0.07 7.70 0.00 0.00
system.time(for (i in 1:1000) vectorised.centroid(p))
[1] 0.45 0.05 0.51 0.00 0.00
I was expecting the 20-gon version to be faster; what I did not expect was that vectorising would pay off even for a quadrilateral. In fact,
p <- rbind(c(0,0), c(0,1), c(1,0)) system.time(for (i in 1:1000) polygon.centroid(p))
[1] 1.25 0.04 1.31 0.00 0.00
system.time(for (i in 1:1000) vectorised.centroid(p))
[1] 0.33 0.07 0.40 0.00 0.00
it even pays off for a triangle.
______________________________________________ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help
______________________________________________ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help