Updating a string inside a callback - string
The following code is a graphic rendering of the Earth globe spinning eastward. I have two push buttons, Spin and Stop. Both share the same callback function, hAnimaCallback. In particular, this latter does not work. I pretend to use the strings (names) of the push buttons to create a switch that stops the movement. However, I can not get to change the string name inside the while loop and I do not understand why my method is wrong.
function example
fh = figure('Menu','none','Toolbar','none','Units','characters');
T = 0:pi/100:2*pi;
Y = zeros(numel(T),3);
Y(:,1) = 7000*cos(T);
Y(:,2) = 7000*sin(T);
hPanAni = uipanel('parent',fh,'Units','characters','Position',...
[22.6 10.4 53 23],'title','Controls','FontSize',11,...
'FontAngle','italic','FontWeight','bold');
hIniAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.64 0.5 0.12],'String','Spin',...
'FontSize',10,'Callback',#hAnimaCallback);
hFinAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.26 0.5 0.12],'String','Stop',...
'FontSize',10,'Callback',#hAnimaCallback);
hPantSim = uipanel('Parent',fh,'Units','characters',...
'Position',[107.87 8 157.447 42],'BorderType','none','title',...
'Screen','FontSize',11,'FontAngle','italic',...
'FontWeight','bold');
hPantSimInt = uipanel('Parent',hPantSim,'Units','normalized','Position',...
[0 0 1 1],'BorderType','line','BackgroundColor','black');
ah4 = axes('Parent',hPantSimInt,'Units','normalized','Position',...
[0 0 1 1],'Color','none','Visible','off','DataAspectRatio',...
[1 1 1],'NextPlot','add');
rotate3d(ah4);
hgrot = hgtransform('Parent',ah4);
Resf = 6378;
maptext = imread('tierra.jpg');
[X, map] = rgb2ind(maptext,128);
[x,y,z] = sphere(50);
x = Resf*x;
y = Resf*y;
z = Resf*z;
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.Parent = hgrot;
props.Cdata = flipud(X); % it is necesary to do this for getting the
% appropiate image on the sphere
hsurf = surface(x,y,z,props);
colormap(map);
axis equal;
view([71 14]);
set(gcf,'Renderer','opengl')
drawnow;
line('parent',ah4,'XData',Y(:,1),'YData',Y(:,2),'ZData',...
Y(:,3),'Color','red','LineWidth',2);
line('parent',ah4,'XData',Y(end,1),'YData',Y(end,2),...
'ZData',Y(end,3),'Marker','o','MarkerSize',6,'MarkerFaceColor','b');
axis square equal vis3d;
view(3);
handles.XLim = get(ah4,'XLim');
handles.YLim = get(ah4,'YLim');
handles.ZLim = get(ah4,'ZLim');
xmin = handles.XLim(1);
ymin = handles.YLim(1);
zmin = handles.ZLim(1);
xmax = handles.XLim(2);
ymax = handles.YLim(2);
zmax = handles.ZLim(2);
set(ah4, 'XLim', [xmin xmax],'YLim', [ymin ymax],'Zlim',[zmin zmax]);
az = 0;
function hAnimaCallback(hObject,evt)
while (ishandle(fh))
state = get(hObject,'String'), % state should change between the states of
% Spin and Stop but this does not occur
if (strcmp(state,'Stop'))
break;
else
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
drawnow;
end
end
end
end
It seems like you are running into some kind of race condition because of the repeated drawnow calls in the while loop. The state changes to Stop, when you press the Stop button, but it is to quick to notice. Basically, the while loop is running as fast as MATLAB can run. Instead of drawnow using a pause(0.1) command seems to work (with a little bit code logic changes):
az = 0;
spin = false;
function hAnimaCallback(hObject,~)
state = get(hObject,'String')
if strcmp(state, 'Spin')
spin = true;
else
spin = false;
end
while (spin)
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
pause(0.1);
end
end
Related
Plot output differences between python and julia
I am trying to use julai as main language for my work. But I find that this plot is different than python (Which outputs the right plot) Here is the python code and output import numpy as np import math import matplotlib.pyplot as plt u = 9.27*10**(-21) k = 1.38*10**(-16) j2 = 7/2 nrr = 780 h = 1000 na = 6*10**(23) rho = 7.842 mgd = 157.25 a = mgd d = na*rho*u/a m_f = [] igd = 7.0 for t in range(1,401): while True: h1 = h+d*nrr*igd x2 = (7*u*h1)/(k*t) x4 = 2*j2 q2 = (x4+1)/x4 m = abs(7*(q2*math.tanh(q2*x2)**-1 - (1/x4)*math.tanh(x2/x4)**-1)) if abs(m - igd) < 10**(-12): break else: igd = m m_f.append(abs(m)) plt.plot(range(1,401), m_f) plt.savefig("Py_plot.pdf") and it gives the following right plot The right plot as expected But when I do the same calculations in julia it gives different output than python, here is my julia code using Plots u = 9.27*10^(-21) k = 1.38*10^(-16) j2 = 7/2 nrr = 780 h = 1000 na = 6*10^(23) rho = 7.842 mgd = 157.25 a = mgd d = na*rho*u/a igd = 7.0 m = 0.0 m_f = Float64[] for t in 1:400 while true h1 = h+d*nrr*igd x2 = (7*u*h1)/(k*t) x4 = 2*j2 q2 = (x4+1)/x4 m = 7*(q2*coth(rad2deg(q2*x2))-(1/x4)*coth(rad2deg(x2/x4))) if abs(abs(m)-igd) < 10^(-10) break else igd = m end end push!(m_f, abs(m)) end plot(1:400, m_f) and this is the unexpected julia output unexpected wrong output from julia I wish for help....
Code: using Plots const u = 9.27e-21 const k = 1.38e-16 const j2 = 7/2 const nrr = 780 const h = 1000 const na = 6.0e23 const rho = 7.842 const mgd = 157.25 const a = mgd const d = na*rho*u/a function plot_graph() igd = 7.0 m = 0.0 trange = 1:400 m_f = Vector{Float64}(undef, length(trange)) for t in trange while true h1 = h+d*nrr*igd x2 = (7*u*h1)/(k*t) x4 = 2*j2 q2 = (x4+1)/x4 m = abs(7*(q2*coth(q2*x2)-(1/x4)*coth(x2/x4))) if isapprox(m, igd, atol = 10^(-10)) break else igd = m end end m_f[t] = m end plot(trange, m_f) end Plot: Changes for correctness: Changed na = 6.0*10^(23) to na = 6.0e23. Since ^ has a higher precedence than *, 10^23 is evaluated first, and since the operands are Int values, the result is also an Int. However, Int (i.e. Int64) can only hold numbers up to approximately 9 * 10^18, so 10^23 overflows and gives a wrong result. julia> 10^18 1000000000000000000 julia> 10^19 #overflow starts here -8446744073709551616 julia> 10^23 #and gives a wrong value here too 200376420520689664 6.0e23 avoids this problem by directly using the scientific e-notation to create a literal Float64 value (Float64 can hold this value without overflowing). Removed the rad2deg calls when calling coth. Julia trigonometric functions by default take radians, so there's no need to make this conversion. Other changes Marked all the constants as const, and moved the rest of the code into a function. See Performance tip: Avoid non-constant global variables Changed the abs(m - igd) < 10^-10 to isapprox(m, igd, atol = 10^-10) which performs basically the same check, but is clearer and more flexible (for eg. if you wanted to change to a relative tolerance rtol later). Stored the 1:400 as a named variable trange. This is just because it's used multiple times, so it's easier to manage as a variable. Changed m_f = Float64[] to m_f = Vector{Float64}(undef, length(trange)) (and the push! at the end to an assignment). If the size of the array is known beforehand (as it is in this case), it's better for performance to pre-allocate it with undef values and then assign to it. Changed u and k also to use the scientific e-notation, for consistency and clarity (thanks to #DNF for suggesting the use of this notation in the comments).
How can I modify a M/M/1 queuing system to G/G/1?
I wrote a Monte Carlo simulation for M/M/1 queuing system since it's deterministic. Now I tried modifying the same code for a G/G/1 queueing system with interarrival times and service times having a triangular distribution. Instead of drawing samples from Poisson and exponential distribution, I am drawing samples from the triangular distribution (for G/G/1). However, I am getting results that are hard to make sense of. The analytical approximation results say that the mean waiting time in the queue is 0.9708 which is kinda off from the result (~0.75) I am getting with the simulation. clc clear tic Nc = 1008; Tsys = zeros(1,Nc); Tia = zeros(1,Nc); Ta = zeros(1,Nc); Tsrv = zeros(1,Nc); Tnsrv = zeros(1,Nc); Txsys = zeros(1,Nc); WTqmc = zeros(1,Nc); MTqmc = zeros(1,Nc); MTsys = zeros(1,Nc); Tri1_min = 2; Tri1_mid = 3; Tri1_max = 5; Tri2_min = 1.8; Tri2_mid = 2.8; Tri2_max = 4.5; pdat = makedist('Triangular','a',Tri1_min,'b',Tri1_mid,'c',Tri1_max); pdser = makedist('Triangular','a',Tri2_min,'b',Tri2_mid,'c',Tri2_max); Tia(1) = random(pdat); Ta(1) = Tia(1); Tsys(1) = Tsrv(1); Tnsrv(1) = Ta(1); Tsrv(1) = random(pdser); Txsys(1) = Ta(1) + Tsrv(1); WTqmc(1) = 0; MTqmc(1) = WTqmc(1); for i = 2:1:Nc Tia(i) = random(pdat); Ta(i) = Ta(i-1) + Tia(i); Tsys(i) = Ta(i); if Ta(i) < Txsys(i-1) Tnsrv(i) = Tnsrv(i-1) + Tsrv(i-1); else Tnsrv(i) = Ta(i); end Tsrv(i) = random(pdser); Txsys(i) = Tnsrv(i) + Tsrv(i); WTqmc(i) = Tnsrv(i)-Ta(i); Tsys(i) = Txsys(i) - Ta(i); MTqmc(i) = ((i-1)* MTqmc(i-1) + WTqmc(i))/i; % MTsys(i) = ((i-1)* MTsys(i-1) + Tsys(i))/i; end Tend = Txsys(Nc); Nts = floor(Tend); dt = 1; Time = zeros(1,Nts); Lq = zeros(1,Nts); Time(1) = 0; Lq(1) = 0; for j = 2:1:Nts Time(j) = Time(j-1)+dt; Lq(j) = 0; for i = 1:1:Nc if (Ta(i) < Time(j) && Txsys(i) > Time(j) && Tnsrv(i) > Time(j)) Lq(j) = Lq(j)+1; end end end MLqmc = mean(Lq) MTqmc1 = MTqmc(Nc) MTqmc_mean = mean(WTqmc) SDmtamc = std(WTqmc) SEmtamc = SDmtamc/sqrt(Nc) toc mean1= (2+3+5)/3; mean2=(1.8+2.8+4.5)/3; var1=(4+9+25-2*3-2*5-3*5)/18; var2=(1.8*1.8+2.8*2.8+4.5*4.5-1.8*2.8-1.8*4.5-2.8*4.5)/18; rho= (1/mean1)/(1/mean2); ca2= var1/mean1^2; cs2=var2/mean2^2; Lq=((rho^2)*(1+cs2)*(ca2+(rho^2)*cs2))/(2*(1-rho)*(1+(rho^2)*cs2)); wq=Lq/(1/mean1) %Plot Outcomes figure(1) plot(Ta,MTqmc) xlabel('Arrivals') ylabel('Mean Time in Queue') title('Queue Length vs Time')
Does xlswrite have limitations?
I'm running MATLAB R2017a. I am trying to execute a simple program that writes 3 characters to an Excel file. When I run the program with a small number of values it is fine but when I increase it to the millions, the program pauses. Does anyone know why the programming is pausing like this? X = [] filename = 'PopltnFL.xlsx'; NumTrump = 4617886; NumClinton = 4504975; NumOther = 297025; *% Values for which program runs without puasing* % NumTrump = 4; % NumClinton = 4; % NumOther = 2; % for ii = 1:NumTrump X = [X,'T']; end for jj = 1:NumClinton X = [X,'C']; end for kk = 1:NumOther X = [X,'O']; end X = X'; xlswrite(filename,X)
Variable issue in GameMaker 2
Making a game in GameMaker and I'm having a problem where the variable is not set and I'm not sure why. When pressing down on either W,A,S, or D and clicking LMB it works but crashes if I pressing down on W,A,S, or D then let go and afterwards click LMB. Code: var look var bullet if (keyboard_check(ord("A"))){ x = x - 5; sprite_index = spr_west_hiro image_xscale = 3 image_yscale = 3 look = 180 } else if (keyboard_check(ord("D"))){ x = x + 5; sprite_index = spr_east_hiro image_xscale = 3 image_yscale = 3 look = 0 } else if (keyboard_check(ord("S"))){ y = y + 5; sprite_index = spr_south_hiro image_xscale = 3 image_yscale = 3 look = 270 } else if (keyboard_check(ord("W"))){ y = y - 5; sprite_index = spr_north_hiro image_xscale = 3 image_yscale = 3 look = 90 } //------------------------------------------------------------------------------ if (keyboard_check_released(ord("A"))){ sprite_index = spr_idlewest_hiro image_xscale = 3 image_yscale = 3 look = 180 } else if (keyboard_check_released(ord("D"))){ sprite_index = spr_idleast_hiro image_xscale = 3 image_yscale = 3 look = 0 } else if (keyboard_check_released(ord("S"))){ sprite_index = spr_idlesouth_hiro image_xscale = 3 image_yscale = 3 look = 270 } else if (keyboard_check_released(ord("W"))){ sprite_index = spr_idlenorth_hiro image_xscale = 3 image_yscale = 3 look = 90 } //-------------------------------------------------------------------------------- if (mouse_check_button_pressed(mb_left)){ var bullet = instance_create_layer(x,y, "Instances", obj_bullet) bullet.direction = look } Error: ERROR!!! :: ############################################################################################ FATAL ERROR in action number 1 of Step Event0 for object obj_hiro: local variable look(100001, -2147483648) not set before reading it. at gml_Object_obj_hiro_Step_0 (line 61) - bullet.direction = look ############################################################################################ -------------------------------------------------------------------------------------------- stack frame is gml_Object_obj_hiro_Step_0 (line 61) I have reviewed the code multiple times and I am still stumped. Particularly because of the fact that it seems as though the variable doesn't save the coefficient set to it despite the fact that it should when W,A,S or D is pressed down then released.
Firstly, you would want to assign a value to your look variable, as otherwise it will remain not set to anything if no buttons had been pressed. Secondly, you may want to do so in Create event, as you probably want your character to shoot in last pressed direction, not just "somewhere"
when a spawn object moves across the screen, I want it to despawn once it gets to a certain x value?
I have random spawned objects that automatically moves across the screen. I want it so that when the objects reach a certain x position it despawns itself. local mRandom = math.random local objects = {"Vehicle11" ,"Vehicle21","Vehicle31","Vehicle41"} local objectTag = 0 local object = {} local function spawncarright() local rightcar = {408,312} objectTag = objectTag + 1 local objIdx = mRandom(#objects) local objName = objects[objIdx] object[objectTag] = display.newImage(objName..".png") -- see the difference here object[objectTag].x = 32 object[objectTag].y = rightcar[math.random(1,2)] object[objectTag].name = objectTag transition.to(object[objectTag], {time = 3500, x = 348}) end timer.performWithDelay(2000,spawncarright,0) so once reaches object[objectTag].x = 348 the object despawn
Try this: local function deSpawn() for i=1,objectTag do if(object[i]~=nil and object[i].x~=nil and object[i].x>=348)then -- If you want to remove the object, then use the following 2 lines -- object[i]:removeSelf() print("Removed object["..i.."]") --or else if you want to reposition the object, then uncomment the following -- --[[ spawncarright() --]] end end end Runtime:addEventListener("enterFrame",deSpawn) Keep coding................... :)
You should do it within the transition.to call: object[objectTag].deleteSelf = function(self) object[self.name] = nil -- Remove reference to object in table display.remove(self) self = nil end local localObj = object[objectTag] -- Do this so the object doesn't change with the objectTag does; if objectTag is incremented, then when the transition ends, it won't be pointing to the same object when we call the function transition.to(localObj, {time = 3500, x = 348, onComplete = function() localObj:deleteSelf() end})