[R] placing labels in polygon center ?

Spencer Graves spencer.graves at pdf.com
Thu Aug 14 06:25:06 CEST 2003


	  I didn't study your code, but regarding a function to rotate a 
vector:  Multiplication by an orthogonal matrix does that.  You may know 
that an orthogonal matrix is a matrix whose transpose is its inverse. 
Thus, A is orthogonal if and only if (A %*% t(A)) = identity.  One of 
the simplest orthogonal matrices is as follows:

[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 <B.Rowlingson at lancaster.ac.uk> 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.
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-help




More information about the R-help mailing list