views:

234

answers:

2

I have a class called forest and a property called fixedPositions that stores 100 points (x,y) and they are stored 250x2 (rows x columns) in MatLab. When I select 'fixedPositions', I can click scatter and it will plot the points.

Now, I want to rotate the plotted points and I have a rotation matrix that will allow me to do that.

The below code should work:

theta = obj.heading * pi/180; apparent = [cos(theta) -sin(theta) ; sin(theta) cos(theta)] * obj.fixedPositions;

But it wont. I get this error.

??? Error using ==> mtimes Inner matrix dimensions must agree.

Error in ==> landmarks>landmarks.get.apparentPositions at 22 apparent = [cos(theta) -sin(theta) ; sin(theta) cos(theta)] * obj.fixedPositions;

When I alter forest.fixedPositions to store the variables 2x250 instead of 250x2, the above code will work, but it wont plot. I'm going to be plotting fixedPositions constantly in a simulation, so I'd prefer to leave it as it, and make the rotation work instead.

Any ideas?

Also, fixed positions, is the position of the xy points as if you were looking straight ahead. i.e. heading = 0. heading is set to 45, meaning I want to rotate points clockwise 45 degrees.

Here is my code:

classdef landmarks
  properties
    fixedPositions   %# positions in a fixed coordinate system. [x, y]
    heading = 45;     %# direction in which the robot is facing
  end
  properties (Dependent)
    apparentPositions
  end
  methods
    function obj = landmarks(numberOfTrees)
        %# randomly generates numberOfTrees amount of x,y coordinates and set 
        %the array or matrix (not sure which) to fixedPositions
        obj.fixedPositions = 100 * rand([numberOfTrees,2]) .* sign(rand([numberOfTrees,2]) - 0.5);
    end
    function apparent = get.apparentPositions(obj)
        %# rotate obj.positions using obj.facing to generate the output
        theta = obj.heading * pi/180;
        apparent = [cos(theta)  -sin(theta) ; sin(theta)  cos(theta)] * obj.fixedPositions;
    end
  end
end

P.S. If you change one line to this: obj.fixedPositions = 100 * rand([2,numberOfTrees]) .* sign(rand([2,numberOfTrees]) - 0.5);

Everything will work fine... it just wont plot.

ans = obj.fixedPositions; ans'; will flip it to what I need to plot, but there has to be a way to avoid this?

+3  A: 

I think you want to transpose the matrix before and after multiplying by the rotation. If the matrix is real numbers, you can do:

apparent = ([cos(theta)  -sin(theta) ; sin(theta)  cos(theta)] * (obj.fixedPositions)')';
Sanjay Manohar
Money! Thanks. Off hand, is the best way to animate something like this just to erase the scatter plot and redraw it?
pinnacler
+3  A: 

One solution is to compute the transpose of your above rotation matrix and move it to the other side of the matrix multiplication:

rotMat = [cos(theta) sin(theta); -sin(theta) cos(theta)];  %# Rotation matrix
apparent = (obj.fixedPositions)*rotMat;  %# The result will be a 250-by-2 array

When plotting your points, you should take advantage of handle graphics to create the smoothest animation. Instead of erasing the old plot and replotting it, you can use the handle to the plot object and the SET command to update its properties, which should render much faster. Here's an example using the SCATTER function:

h = scatter(apparent(:,1),apparent(:,2));  %# Make a scatter plot and return a
                                           %#   handle to the scattergroup object
%# Recompute new values for apparent
set(h,'XData',apparent(:,1),'YData',apparent(:,2));  %# Update the scattergroup
                                                     %#   object using set
drawnow;  %# Force an update of the figure window
gnovice