/** * @param float $angle */ public function rotate($angle) { $points = array(); $points[0] = $this->dx; $points[1] = $this->dy; rotateAboutPoint($points, 0, 0, $angle); $this->dx = $points[0]; $this->dy = $points[1]; }
private function drawLabelRotated($imageRef, $centre, $angle, $text, $padding, $direction) { $fontObject = $this->owner->fonts->getFont($this->bwfont); list($strWidth, $strHeight) = $fontObject->calculateImageStringSize($text); $angle = $this->normaliseAngle($angle); $radianAngle = -deg2rad($angle); $extra = 3; $topleft_x = $centre->x - $strWidth / 2 - $padding - $extra; $topleft_y = $centre->y - $strHeight / 2 - $padding - $extra; $botright_x = $centre->x + $strWidth / 2 + $padding + $extra; $botright_y = $centre->y + $strHeight / 2 + $padding + $extra; // a box. the last point is the start point for the text. $points = array($topleft_x, $topleft_y, $topleft_x, $botright_y, $botright_x, $botright_y, $botright_x, $topleft_y, $centre->x - $strWidth / 2, $centre->y + $strHeight / 2 + 1); if ($radianAngle != 0) { rotateAboutPoint($points, $centre->x, $centre->y, $radianAngle); } $textY = array_pop($points); $textX = array_pop($points); if ($this->bwboxcolour->isRealColour()) { imagefilledpolygon($imageRef, $points, 4, $this->bwboxcolour->gdAllocate($imageRef)); } if ($this->bwoutlinecolour->isRealColour()) { imagepolygon($imageRef, $points, 4, $this->bwoutlinecolour->gdAllocate($imageRef)); } $fontObject->drawImageString($imageRef, $textX, $textY, $text, $this->bwfontcolour->gdallocate($imageRef), $angle); $areaName = "LINK:L" . $this->id . ':' . ($direction + 2); // the rectangle is about half the size in the HTML, and easier to optimise/detect in the browser if ($angle % 90 == 0) { // We optimise for 0, 90, 180, 270 degrees - find the rectangle from the rotated points $rectanglePoints = array(); $rectanglePoints[] = min($points[0], $points[2]); $rectanglePoints[] = min($points[1], $points[3]); $rectanglePoints[] = max($points[0], $points[2]); $rectanglePoints[] = max($points[1], $points[3]); $newArea = new HTML_ImageMap_Area_Rectangle($areaName, "", array($rectanglePoints)); wm_debug("Adding Rectangle imagemap for {$areaName}\n"); } else { $newArea = new HTML_ImageMap_Area_Polygon($areaName, "", array($points)); wm_debug("Adding Poly imagemap for {$areaName}\n"); } // Make a note that we added this area $this->imap_areas[] = $areaName; $this->imageMapAreas[] = $newArea; $this->owner->imap->addArea($newArea); }
/** * moveNode - move a node, taking into account any relative nodes, and any links that * join to it, dealing with VIAs in an attractive way. * * @param string $nodeName * @param number $newX * @param number $newY * @return array * @throws WMException */ function moveNode($nodeName, $newX, $newY) { if (!$this->isLoaded()) { throw new WMException("Map must be loaded before editing API called."); } // if the node doesn't exist, nothing will be changing if (!$this->map->nodeExists($nodeName)) { return array(0, 0, 0, 0); } $movingNode = $this->map->getNode($nodeName); $affected_nodes = array(); $affected_links = array(); // This is a complicated bit. Find out if this node is involved in any // links that have VIAs. If it is, we want to rotate those VIA points // about the *other* node in the link foreach ($this->map->links as $link) { if (count($link->vialist) > 0 && ($link->a->name == $nodeName || $link->b->name == $nodeName)) { $affected_links[] = $link->name; // get the other node from us if ($link->a->name == $nodeName) { $pivot = $link->b; } if ($link->b->name == $nodeName) { $pivot = $link->a; } // this is a weird special case, but it is possible, with link offsets // if the link starts and ends on this node, translate any VIAs if ($link->a->name == $nodeName && $link->b->name == $nodeName) { $dx = $link->a->x - $newX; $dy = $link->a->y - $newY; for ($count = 0; $count < count($link->vialist); $count++) { $link->vialist[$count][0] = $link->vialist[$count][0] - $dx; $link->vialist[$count][1] = $link->vialist[$count][1] - $dy; } } else { $pivotX = $pivot->x; $pivotY = $pivot->y; $newPoint = new WMPoint($newX, $newY); $pivotPoint = $pivot->getPosition(); $movingPoint = $movingNode->getPosition(); $oldVector = $pivotPoint->vectorToPoint($movingPoint); $newVector = $pivotPoint->vectorToPoint($newPoint); // $dx_old = $pivotX - $movingNode->x; // $dy_old = $pivotY - $movingNode->y; // $dx_new = $pivotX - $newX; // $dy_new = $pivotY - $newY; // $l_old = sqrt($dx_old*$dx_old + $dy_old*$dy_old); // $l_new = sqrt($dx_new*$dx_new + $dy_new*$dy_new); // // $angle_old = rad2deg(atan2(-$dy_old, $dx_old)); // $angle_new = rad2deg(atan2(-$dy_new, $dx_new)); $angle_old = $oldVector->getAngle(); $angle_new = $newVector->getAngle(); $l_new = $newVector->getLength(); $l_old = $oldVector->getLength(); # $log .= "$pivx,$pivy\n$dx_old $dy_old $l_old => $angle_old\n"; # $log .= "$dx_new $dy_new $l_new => $angle_new\n"; // the geometry stuff uses a different point format, helpfully $points = array(); foreach ($link->vialist as $via) { $points[] = $via[0]; $points[] = $via[1]; } $scaleFactor = $l_new / $l_old; // rotate so that link is along the axis rotateAboutPoint($points, $pivotX, $pivotY, deg2rad($angle_old)); // do the scaling in here for ($count = 0; $count < count($points) / 2; $count++) { $basex = ($points[$count * 2] - $pivotX) * $scaleFactor + $pivotX; $points[$count * 2] = $basex; } // rotate back so that link is along the new direction rotateAboutPoint($points, $pivotX, $pivotY, deg2rad(-$angle_new)); // now put the modified points back into the vialist again $viaCount = 0; $count = 0; foreach ($points as $p) { // skip a point if it positioned relative to a node. Those shouldn't be rotated (well, IMHO) if (!isset($link->vialist[$viaCount][2])) { $link->vialist[$viaCount][$count] = $p; } $count++; if ($count == 2) { $count = 0; $viaCount++; } } } } } $movingNode->x = $newX; $movingNode->y = $newY; $n_links = count($affected_links); $n_nodes = count($affected_nodes); return array($n_nodes, $n_links, $affected_nodes, $affected_links); }