0

I have a rectangle that drawn with 4 points. I need to rotate all points an arbitrary degree and find the new x,y of the points.I try to rotate these but the problem is when I'll increase the degree, rectangle Becomes smaller and when I'll decrease the degree, the first rectangle not drawn again. How can I do this by using Angular.

<div ng-app="myApp">
    <div  ng-app="myApp" ng-controller="rectController">
         <input type="number" ng-model="Rotation" min="-360" max="360" value="0"/>
         <rect-rotate/>
    </div>
 </div>

Here is the JavaScript code:

var App = angular.module('myApp', []);
var Ctrl = App.controller('rectController', function($scope) { });

Ctrl.directive('rectRotate', function() {

        function link(scope, el, attr) {
            var w = 1200, h = 780;
            var width = 300, height = 200;
            var point1=[300,200],point2=[600,200],point3=[600,400],point4=[300,400];

            var svg = d3.select(el[0]).append("svg")
                .attr("width", w)
                .attr("height", h);
            var newg = svg.append("g").data([{ x: width, y: height }]);

             var rect = newg.append("path")
                .attr("x", function(d) {
                    return d.x;
                })
                .attr("y", function(d) {
                    return d.y;
                })
                .attr("fill-opacity", .5)
                .attr("d", function(d) {

        var dCommand
                    = "M" + point1[0] + "," + point1[1] + "L" + point2[0] 
                    + "," + point2[1] + "L " + point3[0] + "," + point3[1] 
                    + "L " + point4[0] + "," + point4[1] + "Z";
                    return dCommand;
                });
         scope.$watch('Rotation', function (newValues) {
            var rotateAngle = newValues;
            rotateAngle = rotateAngle * Math.PI / 180.0;
            var centerX = (point1[0]+point3[0]) / 2;
            var centerY = (point1[1]+point3[1]) / 2;

 //1
 point1[0] = (Math.cos(rotateAngle) * (point1[0] - centerX)
          -(Math.sin(rotateAngle) * (point1[1] - centerY)) + centerX;
 point1[1] = (Math.sin(rotateAngle) * (point1[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point1[1] - centerY)) + centerY;

//2
point2[0] = (Math.cos(rotateAngle) * (point2[0] - centerX)
          -(Math.sin(rotateAngle) * (point2[1] - centerY)) + centerX;
point2[1] = (Math.sin(rotateAngle) * (point2[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point2[1] - centerY)) + centerY;

//3
point3[0] = (Math.cos(rotateAngle) * (point3[0] - centerX)
          -(Math.sin(rotateAngle) * (point3[1] - centerY)) + centerX;
point3[1] = (Math.sin(rotateAngle) * (point3[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point3[1] - centerY)) + centerY;

//4
point4[0] = (Math.cos(rotateAngle) * (point4[0] - centerX)
          -(Math.sin(rotateAngle) * (point4[1] - centerY)) + centerX;
point2[1] = (Math.sin(rotateAngle) * (point4[0] - centerX)) 
          +(Math.cos(rotateAngle) * (point4[1] - centerY)) + centerY;

 rect.attr("d", function (d) {

        var dCommand
                    = "M" + point1[0] + "," + point1[1] + "L" + point2[0] 
                    + "," + point2[1] + "L " + point3[0] + "," + point3[1] 
                    + "L " + point4[0] + "," + point4[1] + "Z";
                    return dCommand;
                    });
        }return {
            link: link
        };

    });
Gabriel
  • 1,413
  • 1
  • 18
  • 29
  • You can simply use the `transform` attribute with a `rotate()` value, no need to compute the rotation yourself. – Lars Kotthoff Jun 11 '15 at 21:10
  • I'm afraid I need to create path with d value to keep my other format. The transform attribute with rotate() value will rotate rectangle by top-left pivot and will move it. I need to rotate by center-center and keep coordination. – Gabriel Jun 11 '15 at 21:14
  • 1
    You can specify the point to rotate about -- https://developer.mozilla.org/en/docs/Web/SVG/Attribute/transform – Lars Kotthoff Jun 11 '15 at 21:39

2 Answers2

1

You should use the rotate attribute as Lars Kotthoff already mentioned.

As you're basically creating a rect I replaced your path with a svg:rect for convenience. The following code does the rotation by rotating the g element. This way you can crate any number of shapes inside and they will rotate properly.

For rotating the g element around the center I calculated the center by adding half of the width and height of the element to its x and y position.

var App = angular.module('myApp', []);
var Ctrl = App.controller('rectController', function($scope) { });

Ctrl.directive('rectRotate', function() {
  function link(scope, el, attr) {
    var w = 1200, h = 780;
    var width = 300, height = 200, positionX = 300, positionY = 200;

    var svg = d3.select(el[0]).append("svg")
        .attr("width", w)
        .attr("height", h);

    var newg = svg.append("g");

    var rect = newg.append("rect")
        .attr("x", positionX)
        .attr("y", positionY)
        .attr("fill-opacity", .5)
        .attr("width", width)
        .attr("height", height);

    scope.$watch('Rotation', function (newValues) {

      var rotateAngle = newValues || 0;
      newg.attr("transform","rotate(" + rotateAngle + " "+ (positionX + width / 2) +" "+ (positionY + height / 2) +")");
    });
  }
  return {link: link};
});
jhinzmann
  • 968
  • 6
  • 15
  • Thanks for your answer but I afraid need to use path to draw some shape with at least 4 points. some shapes are polygon and there is no tag except path to create it. Actually I rotate the rectangle but the question is rectangle become smaller in every rotation and I don't know what's wrong with my code. – Gabriel Jun 11 '15 at 22:02
  • i can totaly understand that you want to know why your code fails. So the main task is to calculate the roation of points and not to actually rotate them? because with my solution you can rotate what ever shape you want (pahts included). just append it to `newg` like i did with the `rect`and it will rotate properly. – jhinzmann Jun 11 '15 at 22:06
  • I realized that now. Thank you again. – Gabriel Jun 11 '15 at 22:14
0

There is many way to rotate points. You can use matrix to rotate points. Your points coordinates multiple the matrix. Here is links, which may help you.

http://www.euclideanspace.com/maths/geometry/affine/aroundPoint/

Rotate point in rectangle

Community
  • 1
  • 1
Hazarapet Tunanyan
  • 2,809
  • 26
  • 30
  • Thank you dear ngDeveloper I used the above link to rotate the rectangle points. The question is rectangle become smaller in every rotation and I don't know whats wrong with my code. – Gabriel Jun 11 '15 at 21:54