// Rotates the selection by a specified angle.

  angle = parseFloat(getArgument());
  if (isNaN(angle)) exit("Angle is invalid: "+getArgument());
  Dialog.create("Rotate Selection");
  decimalPlaces = 0;
  if (floor(angle)!=angle) decimalPlaces = 2;
  Dialog.addNumber("     Angle:", angle, decimalPlaces, 3, "degrees");
  Dialog.addMessage("Enter negative angle to \nrotate counter-clockwise");
  Dialog.show();
  angle = Dialog.getNumber();
  if (selectionType==9) {
     rotateCompositeSelection(angle);
     return toString(angle);
  }
  theta = -angle*PI/180;
  getBoundingRect(xbase, ybase, width, height);
  xcenter=xbase+width/2; ycenter=ybase+height/2;
  getSelectionCoordinates(x, y);
  line = selectionType==5&&x.length==2;
  if (line) {
      getLine(x1, y1, x2, y2, width);
      x[0]=x1; y[0]=y1; x[1]=x2; y[1]=y2;
  }
  for (i=0; i<x.length; i++) {
      dx=x[i]-xcenter; dy=ycenter-y[i];
      r = sqrt(dx*dx+dy*dy);
      a = atan2(dy, dx);
      x[i] = xcenter + r*cos(a+theta);
      y[i] = ycenter - r*sin(a+theta);
  }
  if (line)
      makeLine(x[0], y[0], x[1], y[1]);
  else
      makeSelection(selectionType, x, y);
  return toString(angle);

  function rotateCompositeSelection(angle) {
     setBatchMode(true);
     id = getImageID;
     getSelectionBounds(x1, y1, w1, h1);
     run("Create Mask");
     makeRectangle(x1, y1, w1, h1);
     run("Crop");
     run("Arbitrarily...", "enlarge angle="+angle);
     setThreshold(255, 255);
     run("Convert to Mask");
     setThreshold(255, 255);
     run("Create Selection");
     getSelectionBounds(x2, y2, w2, h2);
     selectImage(id);
     run("Restore Selection");
     setSelectionLocation(x1-(w2-w1)/2, y1-(h2-h1)/2);
  }
