Matlab r2015a guide - cannot convert double to a handle - matlab-guide

In the past , I used Matlab 2013 and this code runs correctly and no errors , but now I use matlab r2015a and when I run the code, I get the following error: Cannot convert double value -10 to a handle. I checked the Matworks website but the explanation is not very clear. Do you have any suggestion on how to fix this? Thank you so much !
function minhhoaxy(action,in1)
global DATA;
if nargin < 1,
action='start';
end;
if strcmp(action,'start'),
clf reset;
figure(gcf);
set(gcf,'Units','normalized','NumberTitle','off', ...
'Name','Minh hoa GUI','backingstore','on');
min_x=-10;
max_x=10;
x=0;
uicontrol('Style','text','Units','normalized',...
'Position',[.03 .03 .1 .05],...
'BackgroundColor',[0 0.5 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'ForegroundColor','white','String','Vò trí x:',...
'HorizontalAlignment','center');
uicontrol('Style','text','Units','normalized',...
'Position',[.15 .03 .05 .05],...
'BackgroundColor',[0 0 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'HorizontalAlignment','center',...
'ForegroundColor','white','String',num2str(min_x));
x1=uicontrol('Style','slider','Units','normalized',...
'Position',[.2 .03 .25 .05],...
'SliderStep',[5.0000e-004 5.0000e-003],...
'Value',x,'Max',max_x,'Min',min_x,...
'Callback','minhhoaxy(''setx'',1);minhhoaxy(''redraw'');');
uicontrol('Style','text','Units','normalized',...
'Position',[.45 .03 .05 .05],...
'BackgroundColor',[0 0 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'HorizontalAlignment','center',...
'ForegroundColor','white','String',num2str(max_x));
x2=uicontrol('Style','edit','Units','normalized',...
'Position',[.55 .03 .09 .05],...
'FontSize',10','Fontname','VNI-Times',...
'String',num2str(x),...
'Callback','minhhoaxy(''setx'',2);minhhoaxy(''redraw'')');
uicontrol('Style','text','Units','normalized',...
'Position',[.64 .03 .05 .05],...
'BackgroundColor',[0 0 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'ForegroundColor','white','String','cm',...
'HorizontalAlignment','center');
uicontrol('Style','Pushbutton','Units','normalized',...
'Position',[.87 .03 .1 .05],...
'FontSize',12,'Fontname','VNI-Times',...
'Callback','minhhoaxy(''done'')','String','Thoaùt');
min_y=-10;
max_y=10;
y=0;
uicontrol('Style','text','Units','normalized',...
'Position',[.03 .1 .1 .05],...
'BackgroundColor',[0 0.5 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'ForegroundColor','white','String','Vò trí y:',...
'HorizontalAlignment','center');
uicontrol('Style','text','Units','normalized',...
'Position',[.15 .1 .05 .05],...
'BackgroundColor',[0 0 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'HorizontalAlignment','center',...
'ForegroundColor','white','String',num2str(min_y));
uicontrol('Style','text','Units','normalized',...
'Position',[.45 .1 .05 .05],...
'BackgroundColor',[0 0 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'HorizontalAlignment','center',...
'ForegroundColor','white','String',num2str(max_y));
uicontrol('Style','text','Units','normalized',...
'Position',[.64 .1 .05 .05],...
'BackgroundColor',[0 0 .5],...
'FontSize',12,'Fontname','VNI-Times',...
'ForegroundColor','white','String','cm',...
'HorizontalAlignment','center');
y1=uicontrol('Style','slider','Units','normalized',...
'Position',[.2 .1 .25 .05],...
'SliderStep',[5.0000e-004 5.0000e-003],...
'Value',y,'Max',max_y,'Min',min_y,...
'Callback','minhhoaxy(''sety'',1);minhhoaxy(''redraw'');');
y2=uicontrol('Style','edit','Units','normalized',...
'Position',[.55 .1 .09 .05],...
'FontSize',10','Fontname','VNI-Times',...
'String',num2str(y),...
'Callback','minhhoaxy(''sety'',2);minhhoaxy(''redraw'')');
dt=plot(x,y,'r.','EraseMode','xor','Markersize',50);
axis([-10 10 -10 10]);
grid;
DATA=[x;min_x;max_x;x1;x2;dt;y;min_y;max_y;y1;y2];
elseif strcmp(action,'redraw'),
x=DATA(1);
dt=DATA(6);
set(DATA(5),'string',num2str(x));
set(DATA(4),'value',x);
y=DATA(7);
set(DATA(11),'string',num2str(y));
set(DATA(10),'value',y);
set(dt,'XData',x);
set(dt,'YDATA',y);
drawnow;
elseif strcmp(action,'setx'),
if (in1==1),
DATA(1)=get(DATA(4),'value');
else
min_x=DATA(2);
max_x=DATA(3);
x=str2double(get(DATA(5),'string'));
if (x>max_x),
x=max_x;
end;
if (x<min_x),
x=min_x;
end;
DATA(1)=x;
end
elseif strcmp(action,'sety'),
if (in1==1),
DATA(7)=get(DATA(10),'value');
else
min_y=DATA(8);
max_y=DATA(9);
y=str2double(get(DATA(11),'string'));
if (y>max_y),
y=max_y;
end;
if (y<min_y),
y=min_y;
end;
DATA(7)=y;
end
elseif strcmp(action,'done'),
clf reset;
clear global DATA
close;
end

The issue is due to the fact that graphics handles used to be doubles but are now objects. Because of this, you cannot create an array that contains both numbers and graphics handles (but you used to be able to do this). If you do, MATLAB will try to convert between types and fail. Your issue is at the following line
DATA = [x; min_x; max_x; x1; x2; dt; y; min_y; max_y; y1; y2];
The dt in the middle there is a graphics handle to a plot object and is causing the error that you are seeing.
dt = plot(x,y,'r.','EraseMode','xor','Markersize',50);
To avoid this you will need to use a different data structure than a numeric array.
A much better way to handle your data and graphics handle is to use a struct or a more understandable datatype. Something like the following.
DATA.x = x;
DATA.y = y;
DATA.dt = dt;
...
Otherwise you will need to use a cell array as that can contain both objects and numbers:
DATA = {x; min_x; max_x; x1; x2; dt; y; min_y; max_y; y1; y2};

I had the same error message in MATLAB 2016b, i.e. Cannot convert double value 1138.95 to a handle; for use of a double array with fourier slice theorem, in image reconstruction code. It was solved by simply typing clear all in the command line.

Related

Opengl matrix without glm [duplicate]

This question already has an answer here:
How do I compose a rotation matrix with human readable angles from scratch?
(1 answer)
Closed 11 months ago.
Does anybody know what the order of a 4x4 GLfloat array matrix for transforming a 2D rectangle is? I don't want to use glm or cglm to make my life easy. I'm trying to use the least amount of libraries as possible.
Is the order something like this:
{ px, sx, rx, 0, py, sy, ry, 0, pz, sz, rz, 0, 0, 0, 0, 1 } ?
If not what is it?
Thanks!
4x4 matrix is for 3D.
Xx Yx Zx Tx
Xy Yy Zy Ty
Xz Yz Zz Tz
0 0 0 1
(Xx, Xy, Xz) - left (or right) vector
(Yx, Yy, Yz) - up vector
(Zx, Zy, Zz) - forward vector
(Tx, Ty, Tz) - translation (position) vector
indices:
m00 m01 m02 m03
m10 m11 m12 m13
m20 m21 m22 m23
m30 m31 m32 m33
Order: m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33
If you need only 2D transformations you can use a 3x3 matrix.
Xx Yx Tx
Xy Yy Ty
0 0 1
Order: m00, m10, m20, m01, m11, m21, m02, m12, m22
Or you want this?
Xx Yx 0 Tx
Xy Yy 0 Ty
0 0 1 0
0 0 0 1

Parallel Computing with Julia #parallel and SharedArray

I have been trying to implement some parallel programming in Julia using #parallel and SharedArrays.
Xi = Array{Float64}([0.0, 450.0, 450.0, 0.0, 0.0, 450.0, 450.0, 0.0])
Yi = Array{Float64}([0.0, 0.0, 600.0, 600.0, 0.0, 0.0, 600.0, 600.0])
Zi = Array{Float64}([0.0, 0.0, 0.0, 0.0, 400.0, 400.0, 400.0, 400.0])
Xj = Array{Float64}([0.0, 450.0, 450.0, 0.0, 0.0, 450.0, 450.0, 0.0])
Yj = Array{Float64}([0.0, 0.0, 600.0, 600.0, 0.0, 0.0, 600.0, 600.0])
Zj = Array{Float64}([0.0, 0.0, 0.0, 0.0, 400.0, 400.0, 400.0, 400.0])
L = Array{Float64}([400.0, 400.0, 400.0, 400.0, 450.0, 600.0, 450.0, 600.0])
Rot = Array{Float64}([90.0, 90.0, 90.0, 90.0, 0.0, 0.0, 0.0, 0.0])
Obviously these vectors will be huge, but for simplicity I just put this limited size.
This is the operation without parallel computing:
function jt_transcoord(Xi, Yi, Zi, Xj, Yj, Zj, Rot, L)
r = Vector(length(Xi))
for i in 1:length(Xi)
rxX = (Xj[i] - Xi[i]) / L[i]
rxY = (Yj[i] - Yi[i]) / L[i]
rxZ = (Zj[i] - Zi[i]) / L[i]
if rxX == 0 && rxY == 0
r[i] = [0 0 rxZ; cosd(Rot[i]) -rxZ*sind(Rot[i]) 0; sind(Rot[i]) rxZ*cosd(Rot[i]) 0]
else
R=sqrt(rxX^2+rxY^2)
r21=(-rxX*rxZ*cosd(Rot[i])+rxY*sind(Rot[i]))/R
r22=(-rxY*rxZ*cosd(Rot[i])-rxX*sind(Rot[i]))/R
r23=R*cosd(Rot[i])
r31=(rxX*rxZ*sind(Rot[i])+rxY*cosd(Rot[i]))/R
r32=(rxY*rxZ*sind(Rot[i])-rxX*cosd(Rot[i]))/R
r33=-R*sind(Rot[i])
r[i] = [rxX rxY rxZ;r21 r22 r23;r31 r32 r33]
end
end
return r
end
The returned value is basically an array that contains a matrix in each vector row. That looks something like this:
r =
[[0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0],
[0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0],
[0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0],
[0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0],
[1.0 0.0 0.0; 0.0 -0.0 1.0; 0.0 -1.0 -0.0],
[0.0 1.0 0.0; 0.0 -0.0 1.0; 1.0 0.0 -0.0],
[-1.0 0.0 0.0; 0.0 0.0 1.0; 0.0 1.0 -0.0],
[0.0 -1.0 0.0; -0.0 0.0 1.0; -1.0 -0.0 -0.0]]
This is my function using #parallel. First of all I need to convert the vectors to SharedArrays:
Xi = convert(SharedArray, Xi)
Yi = convert(SharedArray, Yi)
Zi = convert(SharedArray, Zi)
Xj = convert(SharedArray, Xj)
Yj = convert(SharedArray, Yj)
Zj = convert(SharedArray, Zj)
L = convert(SharedArray, L)
Rot = convert(SharedArray, Rot)
This the same code but using #parallel
function jt_transcoord_parallel(Xi, Yi, Zi, Xj, Yj, Zj, Rot, L)
r = SharedArray{Float64}(zeros((length(Xi),1)))
#parallel for i in 1:length(Xi)
rxX = (Xj[i] - Xi[i]) / L[i]
rxY = (Yj[i] - Yi[i]) / L[i]
rxZ = (Zj[i] - Zi[i]) / L[i]
if rxX == 0 && rxY == 0
r[i] = [0 0 rxZ; cosd(Rot[i]) -rxZ*sind(Rot[i]) 0; sind(Rot[i]) rxZ*cosd(Rot[i]) 0]
else
R=sqrt(rxX^2+rxY^2)
r21=(-rxX*rxZ*cosd(Rot[i])+rxY*sind(Rot[i]))/R
r22=(-rxY*rxZ*cosd(Rot[i])-rxX*sind(Rot[i]))/R
r23=R*cosd(Rot[i])
r31=(rxX*rxZ*sind(Rot[i])+rxY*cosd(Rot[i]))/R
r32=(rxY*rxZ*sind(Rot[i])-rxX*cosd(Rot[i]))/R
r33=-R*sind(Rot[i])
r[i] = [rxX rxY rxZ;r21 r22 r23;r31 r32 r33]
end
end
return r
end
I just got a vector of zeros. My question is: Is there a way to implement this function using #parallel in Julia and get the same results that I got in my original function?
The functions jt_transcoord and jt_transcoord_parallel have major coding flaws.
In jt_transcoord, you are assigning an array to a vector element position. For example, you write r = Vector(length(Xi)) and then assign r[i] = [rxX rxY rxZ;r21 r22 r23;r31 r32 r33]. But r[i] should be a number, and you instead assign it a 3x3 matrix. I suspect that Julia is quietly changing types for you.
SharedArray objects will not admit this lax type conversion behavior. The components of a SharedArray must be of a single primitive type such as Float64, and Vector{Matrix} is not a primitive type. Open a Julia v0.6 REPL and copy/paste the following code:
r = SharedArray{Float64}(length(Xi))
for i in 1:length(Xi)
rxX = (Xj[i] - Xi[i]) / L[i]
rxY = (Yj[i] - Yi[i]) / L[i]
rxZ = (Zj[i] - Zi[i]) / L[i]
if rxX == 0 && rxY == 0
r[i] = [0 0 rxZ; cosd(Rot[i]) -rxZ*sind(Rot[i]) 0; sind(Rot[i]) rxZ*cosd(Rot[i]) 0]
else
R = sqrt(rxX^2+rxY^2)
r21 = (-rxX*rxZ*cosd(Rot[i])+rxY*sind(Rot[i]))/R
r22 = (-rxY*rxZ*cosd(Rot[i])-rxX*sind(Rot[i]))/R
r23 = R*cosd(Rot[i])
r31 = (rxX*rxZ*sind(Rot[i])+rxY*cosd(Rot[i]))/R
r32 = (rxY*rxZ*sind(Rot[i])-rxX*cosd(Rot[i]))/R
r33 = -R*sind(Rot[i])
r[i] = [rxX rxY rxZ;r21 r22 r23;r31 r32 r33]
end
end
On my end, I get:
ERROR: MethodError: Cannot `convert` an object of type Array{Float64,2} to an object of type Float64
This may have arisen from a call to the constructor Float64(...),
since type constructors fall back to convert methods.
Stacktrace:
[1] setindex!(::SharedArray{Float64,2}, ::Array{Float64,2}, ::Int64) at ./sharedarray.jl:483
[2] macro expansion at ./REPL[26]:6 [inlined]
[3] anonymous at ./<missing>:?
Essentially, Julia is telling you that it cannot assign a matrix to a SharedArray vector.
What are your options?
If you insist on having a Vector{Matrix} return type, then use r = Vector{Matrix{Float64}}(length(Xi)) in jt_transcoord. But you cannot use SharedArrays for this since Vector{Matrix} is not an admissible primitive type.
Alternatively, if you are willing to operate with tensors (i.e. 3-way arrays) then you can use pseudocode A below. But SharedArray computing will only help you if you carefully account for which process owns which portion of the tensor. Otherwise, the processes will need to communicate with each other, and your parallelized function could execute very slowly.
If you are willing to lay your 3x3 matrices in a 3n x 3 columnwise fashion, then you can use pseudocode B below.
Pseudocode A
function jt_transcoord_tensor(Xi, Yi, Zi, Xj, Yj, Zj, Rot, L)
# initialize array
r = Array{Float64}(3,3,length(Xi))
# r = SharedArray{Float64,3}((3,3,length(Xi))) # for SharedArrays
for i in 1:length(Xi)
# #parallel for i in 1:length(Xi) # for SharedArrays
# other code...
r[:,:,i] = [0 0 rxZ; cosd(Rot[i]) -rxZ*sind(Rot[i]) 0; sind(Rot[i]) rxZ*cosd(Rot[i]) 0]
# other code...
r[:,:,i] = [rxX rxY rxZ;r21 r22 r23;r31 r32 r33]
end
end
return r
end
Pseudocode B
function jt_transcoord_parallel(Xi, Yi, Zi, Xj, Yj, Zj, Rot, L)
n = length(Xi)
r = SharedArray{Float64}((3*n,3))
#parallel for i in 1:length(Xi)
# other code...
r[(3*(i-1)+1):3*(i),:] = [0 0 rxZ; cosd(Rot[i]) -rxZ*sind(Rot[i]) 0; sind(Rot[i]) rxZ*cosd(Rot[i]) 0]
# other code...
r[(3*(i-1)+1):3*(i),:] = [rxX rxY rxZ;r21 r22 r23;r31 r32 r33]
end
end
return r
end

Random direction en 2D lua

I want to create a random direction for my sprite, in Lua 2D.
So, i've tried that :
Sprite.x = Sprite.x + vx
Sprite.y = Sprite.y + vy
Sprite.vx = math.random(-1,1)
Sprite.vy = math.random(-1,1)
So, i managed to create a random direction, but my problem is the speed of the sprite, is directly linked to the number of direction. For example if i want the speed to be 1, it can only have 4 direction. I made a sprite with a lot more, by setting the random speed between -3 and 3, but then it's faster than what i want.
What should i do?
I've seen a few posts talking about random direction, but the description wasn't about lua and i couldn't really understand it..
Thanks!
If I am understanding the problem correctly, you want to choose random directions for the velocity, but you don't want the speed to change. To do this you can choose random velocity components for the x- and y-directions, and then normalize this to a unit vector by dividing each component by the magnitude of the vector.
Also, math.random(-1, 1) will only give value of -1, 0, or 1. If you want more variety in the directions, use math.random() to get floating point values in the range [0, 1). You can randomly choose to make the components negative to get a full spectrum of directions.
Here is a little function that returns a pair of vx and vy velocity components:
function rand_v_dir ()
vx = math.random()
vy = math.random()
norm = math.sqrt(vx * vx + vy * vy)
vx = vx / norm
vy = vy / norm
if math.random(0, 1) == 0 then
vx = -vx
end
if math.random(0, 1) == 0 then
vy = -vy
end
return vx, vy
end
Here are ten random velocity vectors generated by the above function:
> for i = 1, 10 do
vx, vy = rand_v_dir()
print("Velocity: ", vx, vy)
print("Speed: ", math.sqrt(vx * vx + vy * vy))
end
Velocity: -0.70784982398251 0.70636295676368
Speed: 1.0
Velocity: -0.28169296961382 -0.95950459658625
Speed: 1.0
Velocity: 0.71839382297246 -0.69563662577168
Speed: 1.0
Velocity: 0.29007205509751 0.9570048081653
Speed: 1.0
Velocity: -0.40540707321421 0.91413626171807
Speed: 1.0
Velocity: -0.7236198731718 0.69019872439091
Speed: 1.0
Velocity: 0.31888322750977 0.94779401096069
Speed: 1.0
Velocity: -0.64427423170525 0.76479455696325
Speed: 1.0
Velocity: -0.66481241135881 0.74701034644996
Speed: 1.0
Velocity: -0.65843036923729 0.75264164704463
Speed: 1.0
We can do better than this, though. This approach gives directions that are biased towards the corners, as pointed out by #JoelCornett and #nobody in the comments. One improvement would be to select a random angle between 0 and 2π, and to take the velocity vector to be a unit vector. Then the cosine of the angle will be the velocity component in the x-direction, and the sine of the angle will be the component in the y-direction (measuring the angle with respect to the positive x-axis).
This approach also has the benefit of being simpler to code:
function rand_polar_dir ()
dir = 2 * math.pi * (math.random())
vx = math.cos(dir)
vy = math.sin(dir)
return vx, vy
end
Here are ten random velocity vectors generated with the second approach:
> for i = 1, 10 do
vx, vy = rand_polar_dir()
print("Velocity: ", vx, vy)
print("Speed: ", math.sqrt(vx * vx + vy * vy))
end
Velocity: 0.093304068605003 -0.99563766038743
Speed: 1.0
Velocity: -0.31453683190827 -0.9492452693446
Speed: 1.0
Velocity: 0.72403297094833 0.68976536371416
Speed: 1.0
Velocity: -0.39261186353618 -0.91970425931962
Speed: 1.0
Velocity: -0.74523744965918 0.66679917788303
Speed: 1.0
Velocity: 0.15192428057379 -0.98839213522374
Speed: 1.0
Velocity: 0.93666276755405 -0.35023257969239
Speed: 1.0
Velocity: 0.86478573695856 -0.50214104507902
Speed: 1.0
Velocity: 0.64665884247741 -0.7627793530542
Speed: 1.0
Velocity: 0.2877390096936 0.95770886092828
Speed: 1.0
For both of the above approaches, the magnitude of the velocity vector is 1. If you want to double the speed, just multiply the random vector by 2.

Reading a yaw navigation angle and set it to 0

I am working with a drone, and I can read the yaw navigation angle from its sensors. However, I would like to establish this angle as the "0" angle when I start my process. The range of this angle is between -180 degrees to 180 degrees.
initial_yaw = read_yaw_angle()
current_yaw = read_yaw_angle() - initial_yaw
but if initial_yaw is 180 degrees, and the measured angle is, let's say, -50 degrees. Now I have that the current_yaw is -230 which is out of the range -180 to 180 degrees. How can I solve this issue? (is it modulo operator what I need to use?)
current_yaw = read_yaw_angle() - initial_yaw;
if (current_yaw < -180) {
current_yaw += 360;
} else if (currrent_yaw > 180) {
current_yaw -= 360;
}

Rotating a matrix in a non standard 2d plane

I have some problems figuring out how to rotate a matrix in a 2d plane since my coordinate system is not a standard mathematical one, my plane has an inverted y-axis, meaning higher y value is lower on the screen. I also want to rotate the matrix clockwise instead of the standard anticlockwise.
So if I try to illustrate how I want it to work:
O = origin
X = points to rotate
Then 0 degrees looks like this:
XXX
O
I want 90 degrees to look like this:
X
OX
X
180 degrees should look like this:
O
XXX
270 degrees should look like this:
X
XO
X
Any ideas on how to calculate the new x and y for a point after rotating in this plane?
The clockwise rather than anti-clockwise just means flipping the sign on the angle.
To get the full result, we just transform into 'standard coords', do the rotation, and transform back:
The coordinate transform and its inverse is:
(x') = ( 1 0 ) (x)
(y') ( 0 -1 ) (y)
A rotation anti-clockwise is:
(x') = ( cos(angle) -sin(angle) ) (x)
(y') ( sin(angle) cos(angle) ) (y)
So a rotation clockwise is:
(x') = ( cos(angle) sin(angle) ) (x)
(y') ( -sin(angle) cos(angle) ) (y)
Altogether this gives:
(x') = ( 1 0 )( cos(angle) sin(angle) ) ( 1 0 )(x)
(y') ( 0 -1 )( -sin(angle) cos(angle) ) ( 0 -1 )(y)
Multiply the matrices to get:
(x') = ( cos(angle) sin(angle) ) (x)
(y') ( -sin(angle) cos(angle) ) (y)
Now, as you may by now have realized, this is actually the same matrix as rotating 'standard coords' in the anti-clockwise direction.
Or in code:
// Angle in radians
double x2 = cos(angle) * x1 - sin(angle) * y1;
double y2 = sin(angle) * x1 + cos(angle) * y1;
For example, if angle is 180 degrees, cos(angle) is -1, and sin is 0, giving:
double x2 = -x1;
double y2 = -y1;

Resources