Corona SDK rotation - rotation

I'm working on a project that involves a clock, and a set_alarm mechanism that works by dragging a rotating pointer (clock is classic like analog with pointers, not digital) that is attached to the center of the clock, so by rotating pointer (that sets alarm) you can set the alarm. Here is the source:
local function rotateObj2(event)
local t = event.target
local phase = event.phase
if (phase == "began") then
display.getCurrentStage():setFocus( t )
t.isFocus = true
-- Store initial position of finger
t.x1 = event.x
t.y1 = event.y
elseif t.isFocus then
if (phase == "moved") then
animateAlarm = true
t.x2 = event.x
t.y2 = event.y
angle1 = 180/math.pi * math.atan2(t.y1 - t.y , t.x1 - t.x)
angle2 = 180/math.pi * math.atan2(t.y2 - t.y , t.x2 - t.x)
print("angle1 = "..angle1)
rotationAmt = angle1 - angle2
--rotate it
t.rotation = t.rotation - rotationAmt
print ("t.rotation = "..t.rotation)
t.x1 = t.x2
t.y1 = t.y2
alarm.rotation = t.rotation
setAlarm.rotation = t.rotation
print ("setAlarm.rotation = "..t.rotation)
if(alarm.rotation >=0)then
local hourValue = math.floor(t.rotation/30)
local minuteValue = math.floor(t.rotation*2)
local hour = hourValue
local minute = minuteValue
if(minuteValue>=720 and minuteValue<780)then
minute = minuteValue-720
elseif(minuteValue>=660 and minuteValue<720)then
minute = minuteValue-660
elseif(minuteValue>=600 and minuteValue<660)then
minute = minuteValue-600
elseif(minuteValue>=540 and minuteValue<600)then
minute = minuteValue-540
elseif(minuteValue>=480 and minuteValue<540)then
minute = minuteValue-480
elseif(minuteValue>=420 and minuteValue<480)then
minute = minuteValue-420
elseif(minuteValue>=360 and minuteValue<420)then
minute = minuteValue-360
elseif(minuteValue>=300 and minuteValue<360)then
minute = minuteValue-300
elseif(minuteValue>=240 and minuteValue<300)then
minute = minuteValue-240
elseif(minuteValue>=180 and minuteValue<240)then
minute = minuteValue-180
elseif(minuteValue>=120 and minuteValue<180)then
minute = minuteValue-120
elseif(minuteValue>=60 and minuteValue<120)then
minute = minuteValue-60
end
if (hour < 10) then hour = "0" .. hour end
if (minute < 10) then minute = "0" .. minute end
hourField.text = hour
minuteField.text = minute
end
elseif (phase == "ended") then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
print ("ENDEDsetAlarm.rotation = "..setAlarm.rotation)
end
end
-- Stop further propagation of touch event
return true
end
The problem is that when I try to define alarm clock value (like 03.45) it's ok. I transform the rotation of the pointer as you can see. But, if the rotation goes below -90 or over 270 i dont get results. That's because i did not define what to do with that (-rotation)
PROBLEM:
after some time, the rotation shifts. So i dont have rotation = 0 to 270 and -90 to 0, but -90 to -360+(-90) = -450;
sometimes it becomes from 60 to 360+60=420
WTF IS THAT?! =(
help please, i can't get around that, Because these "shifts" seem to happen randomly(or I just cant get why they happen)

You can try this: where dx and dy are equal to the change in x and the change in y
angle = ((math.atan2(dx,dy)*180 / math.pi) - 180) * -1
This will give you a positive value between 0 and 360 no matter which direction you turn or how many rotations you make.

Related

How can I make my MATLAB simulation code run more efficiently?

I am creating a simulation to model a robot moving through river currents. The more code I add, the slower the simulation gets. Sometimes, it runs so slow that the buttons don't work. Does anyone know how I might speed it up?
It is possible that it might be my computer. A few times, the simulation ran flawlessly.
Code:
function CleanRiverSolutionsSimulation
%Initialize Figure
f = figure('Visible','off','Position',[250,250,1000,500],'Name','Clean River Solutions Simulation');
%Initialize variables (when changing these, don't forget to change them in
%the stop button function)
robot_position = [0 0 0];
last_robot_position = [-1 0 0];
time_data = [0];
depth_data = robot_position(3);
simulation_mode = 'paused'; %options: 'paused' 'running' 'stopped'
river_depth = 10;
water_flow_rate = 1;
%Initializes Plots
main_plot = axes('Units','pixels','Position',[50,225,500,250]);
data_plot1 = axes('Units','pixels','Position',[625,350,200,100]);
%Initializes Sliders
water_flow_slider = uicontrol('style','slider','position',[50 175 200 20],'min',0,'max',2.5,'callback',#callback_waterflow,'value',water_flow_rate);
water_flow_text = uicontrol('Style','text','String','River Water Flow','Position',[30 140 200 30]);
water_flow_text.String = sprintf('River Water Flow: %f m/s',get(water_flow_slider,'value'));
river_depth_slider = uicontrol('style','slider','position',[50 125 200 20],'min',0,'max',10,'callback',#callback_riverdepth,'value',river_depth);
river_depth_text = uicontrol('Style','text','String','River Depth','Position',[30 90 200 30]);
river_depth_text.String = sprintf('River Depth: %f m',get(river_depth_slider,'value'));
%Initializes Push Buttons
run_button = uicontrol('Style','pushbutton','String','Run','Position',[300 175 50 20],'callback',#callback_runbutton);
pause_button = uicontrol('Style','pushbutton','String','Pause','Position',[360 175 50 20],'callback',#callback_pausebutton);
stop_button = uicontrol('Style','pushbutton','String','Stop','Position',[420 175 50 20],'callback',#callback_stopbutton);
status_text = uicontrol('Style','text','String','Status','Position',[300 140 150 30]);
status_text.String = sprintf('Status: %s','Paused');
%After setup, makes figure visible
f.Visible = 'on';
%Environment Settings
riv_length = 20;
riv_width = 20;
%River flow settings
flow_dots = 4;
%Initialize Main Plot (when changing these, don't forget to change them in
%the stop button function)
plot3(main_plot,robot_position(1),robot_position(2),robot_position(3),'Marker', 'o','Color','r')
main_plot.XLim = [-riv_length/2 riv_length/2];
main_plot.YLim = [-riv_width/2 riv_width/2];
main_plot.ZLim = [-1*river_depth 1];
main_plot.XGrid = 'on';
main_plot.YGrid = 'on';
main_plot.ZGrid = 'on';
%Initialize time sequence (when changing these, don't forget to change them in
%the stop button function)
time = clock;
pausedStartTime = time(6)+60*time(5)+3600*time(4);
startTime = pausedStartTime;
pausedTime = 0;
totalPausedTime = 0;
%MAIN SIMULATION LOOP
while ishandle(f)
switch simulation_mode
case 'running'
%TODO-add forces and have the positions depend on the forces
%creates a time t to use in simulated equations
time = clock;
t = ((time(6)+60*time(5)+3600*time(4))-startTime-totalPausedTime);
%X
last_robot_position(1) = robot_position(1);
robot_position(1) = 0;
%Y
last_robot_position(2) = robot_position(2);
robot_position(2) = 0;
%Z
last_robot_position(3) = robot_position(3);
robot_position(3) = -4+2*sin(2*t); %just did a sin wave to show movement
%UPDATE MAIN PLOT
%update robot position
plot3(main_plot,robot_position(1),robot_position(2),robot_position(3),'Marker','o','Color','r')
%update robot velocity vector?
forward_vector = [robot_position(1)-last_robot_position(1),...
robot_position(2)-last_robot_position(2),...
robot_position(3)-last_robot_position(3)];
forward_unit_vector = forward_vector./norm(forward_vector);
hold(main_plot,'on')
plot3(main_plot,[robot_position(1) (robot_position(1)+forward_unit_vector(1))],...
[robot_position(2) (robot_position(2)+forward_unit_vector(2))],...
[robot_position(3) (robot_position(3)+forward_unit_vector(3))]);
%update river flow dots
for dot = 1:flow_dots
plot3(main_plot,-riv_length/2+(dot-1)*(riv_length/flow_dots)+mod((t/water_flow_rate),(riv_length/flow_dots)),10,0,'Marker','o','Color','b')
end
%update plot settings
main_plot.XLim = [-riv_length/2 riv_length/2];
main_plot.YLim = [-riv_width/2 riv_width/2];
main_plot.ZLim = [-1*river_depth 1];
main_plot.XGrid = 'on';
main_plot.YGrid = 'on';
main_plot.ZGrid = 'on';
hold(main_plot,'off')
%Update Data Plot 1 (depth)
time = clock;
time_data = [time_data ((time(6)+60*time(5)+3600*time(4))-startTime-totalPausedTime)];
depth_data = [depth_data robot_position(3)];
plot(data_plot1,time_data,depth_data)
title('Robot Depth')
data_plot1.XLim = [max(0,(((time(6)+60*time(5)+3600*time(4))-startTime-totalPausedTime)-15)),...
max(0,(((time(6)+60*time(5)+3600*time(4))-startTime-totalPausedTime)-15)+20)];
data_plot1.YLim = [-1*river_depth 1];
pause(0.1); %anything lower and the simulation won't pause
case 'paused'
pause(0.01); %need this or the sim won't start
case 'stopped'
%so far, this line is never run
end
end
%executes callback for water flow slider
function callback_waterflow(source,eventdata)
water_flow_text.String = sprintf('River Water Flow: %f m/s',get(water_flow_slider,'value'));
water_flow_rate = get(water_flow_slider,'value');
end
%executes callback for river depth slider
function callback_riverdepth(source,eventdata)
river_depth_text.String = sprintf('River Depth: %f m',get(river_depth_slider,'value'));
river_depth = get(river_depth_slider,'value');
end
%executes callback for run button
function callback_runbutton(source,eventdata)
switch simulation_mode
case 'stopped'
%Reinitialize time sequence
time = clock;
startTime = time(6)+60*time(5)+3600*time(4);
pausedTime = 0;
totalpausedTime = 0;
case 'paused'
time = clock;
currentTime = time(6)+60*time(5)+3600*time(4);
pausedTime = currentTime-pausedStartTime;
totalPausedTime = totalPausedTime + pausedTime;
pausedTime = 0;
end
simulation_mode = 'running';
status_text.String = sprintf('Status: %s','Running');
end
%executes callback for run button
function callback_pausebutton(source,eventdata)
switch simulation_mode
case 'running'
status_text.String = sprintf('Status: %s','Paused');
time = clock;
pausedStartTime = time(6)+60*time(5)+3600*time(4);
end
simulation_mode = 'paused';
end
%executes callback for run button
function callback_stopbutton(source,eventdata)
simulation_mode = 'stopped';
status_text.String = sprintf('Status: %s','Stopping');
%Reset all simulation data
robot_position = [0 0 0];
time_data = [0];
depth_data = robot_position(3);
%Reinitialize time sequence
time = clock;
pausedStartTime = time(6)+60*time(5)+3600*time(4);
startTime = pausedStartTime;
pausedTime = 0;
totalPausedTime = 0;
%Reinitialize Plots
plot3(main_plot,robot_position(1),robot_position(2),robot_position(3),'Marker','o','Color','r')
main_plot.XLim = [-riv_length/2 riv_length/2];
main_plot.YLim = [-riv_width/2 riv_width/2];
main_plot.ZLim = [-river_depth 1];
plot(data_plot1,time_data,depth_data)
status_text.String = sprintf('Status: %s','Data is reset.');
simulation_mode = 'paused';
end
end
matlab provides you tools to do this - it is called a profiler. try this
profiler on;
your_script_name;
profiler viewer;
from the output, you can tell which lines or functions cost most of your run time. I use it every time I need to speed up my matlab code.

Sign reverse does not work

For some reason when I try to reverse the sign of my current velocity in MATLAB, it just won't do it.
For example, I start off with velocity_x = 3 and velocity_y = 3 (I am drawing circle collisions).
Now inside of checking conditions I need to reverse the sign and I do the following:
% This doesn't work:
velocity_x = -velocity_x;
velocity_y = -velocity_y;
These expressions don't seem to work. Even though in the variable list it still shows as -3, the ball is just twitching and not going in the opposite direction. But when I simply put numbers there, it works fine!
% This works perfectly fine:
velocity_x = -3;
velocity_y = -3;
Here's the whole loop:
velocity_x = 3;
velocity_y = 3;
% While is not commanded to exit the loop
while exit_loop == false
[b1_x_c, b1_y_c] = getCenter(b1);
xMove(b1, velocity_x);
yMove(b1, velocity_y);
if ((b1_x_c + radius + 1) >= WINDOW_WIDTH) || ((b1_y_c + radius + 1) >= WINDOW_HEIGHT)
velocity_x = -1 * velocity_x;
velocity_y = -1 * velocity_y;
elseif ((b1_x_c - radius - 1) <= 0) || ((b1_y_c - radius - 1) <= 0)
velocity_x = (-1) * velocity_x;
velocity_y = (-1) * velocity_y;
end
redraw;
end % of the while loop
When you come in region where if or elseif condition fulfills, sign could change every cycle turn - velocity value 3 -3 3 -3 and so on...
You have to use some flag to indicate that the sign has already been changed and don't change it until that region will be leaved (a kind of hysteresis)

Optimizing for loop in Matlab

I'm writing a "Peak finder" in Matlab. I've never used Matlab or anything similar before this project, so I'm new to "vectorizing" my code. Essentially, the program needs to take a video of molecules and plot circles on the molecules present in each frame of the video. If a molecule is crowded then it gets a red circle, but if it is not crowded it gets a green circle.
My problem is that some of these videos have 2000 frames and my program takes up to ~25 seconds to process a single frame, which is not practical.
Using tic and toc I've found the trouble maker: A for-loop which calls a function that contains a for-loop.
function getPeaks( orgnl_img, processed_img, cut_off, radius )
% find large peaks peaks by thresholding, i.e. you accept a peak only
% if its more than 'threshold' higher than its neighbors
threshold = 2*std2(orgnl_img);
peaks = (orgnl_img - processed_img) > threshold;
% m and n are dimensions of the frame, named peaks
[m, n] = size(peaks);
cc_centroids = regionprops(peaks, 'centroid');
% Pre-allocate arrays
x_centroid = zeros(1, length(cc_centroids));
y_centroid = zeros(1, length(cc_centroids));
for i = 1:length(cc_centroids)
% Extract the x and y components from cc_centroids struct
x_centroid(i) = cc_centroids(i).Centroid(1);
y_centroid(i) = cc_centroids(i).Centroid(2);
row = int64(x_centroid(i));
col = int64(y_centroid(i));
% Assure that script doesnt attempt to exceed frame
if col-2 > 0 && row-2 > 0 && col+2 < m && row+2 < n
region_of_interest = orgnl_img(col-2:col+2,row-2:row+2);
local_intensity = max(region_of_interest(:));
% Do not plot circle when intensity is 'cut off' or lower
if local_intensity > cut_off
dist_bool = findDistance(cc_centroids, x_centroid(i), y_centroid(i), radius);
if dist_bool == 1
color = 'g';
else
color = 'r';
end
plotCircle(color, x_centroid(i), y_centroid(i), radius)
end
end
end
end
And here is the findDistance function which contains another for-loop and determines if the circles overlap:
function dist_bool = findDistance( all_centroids, x_crrnt, y_crrnt, radius )
x_nearby = zeros(1, length(all_centroids));
y_nearby = zeros(1, length(all_centroids));
for i = 1:length(all_centroids)
if all_centroids(i).Centroid(1) < (x_crrnt+2*radius) &&...
all_centroids(i).Centroid(1) > (x_crrnt-2*radius) &&...
all_centroids(i).Centroid(2) < (y_crrnt+2*radius) &&...
all_centroids(i).Centroid(2) > (y_crrnt-2*radius)
x_nearby(i) = all_centroids(i).Centroid(1);
y_nearby(i) = all_centroids(i).Centroid(2);
pts_of_interest = [x_nearby(i),y_nearby(i);x_crrnt,y_crrnt];
dist = pdist(pts_of_interest);
if dist == 0 || dist > 2*radius
dist_bool = 1;
else
dist_bool = 0;
break
end
end
end
end
I think that there must be much improvement to be done here. I would appreciate any advice.
Thanks! :)
UPDATE: Here are the profiler results. The first section of code is the "getPeaks" function
http://i.stack.imgur.com/VaLdH.png
The hold comes from the plot circle function:
function plotCircle( color, x_centroid, y_centroid, radius )
hold on;
th = 0:pi/50:2*pi;
xunit = radius * cos(th) + x_centroid;
yunit = radius * sin(th) + y_centroid;
plot(xunit, yunit, color);
hold off;
end

Jython (JES) - Function for rotating a picture [duplicate]

I need to write a function spin(pic,x) where it will take a picture and rotate it 90 degrees counter clockwise X amount of times. I have just the 90 degree clockwise rotation in a function:
def rotate(pic):
width = getWidth(pic)
height = getHeight(pic)
new = makeEmptyPicture(height,width)
tarX = 0
for x in range(0,width):
tarY = 0
for y in range(0,height):
p = getPixel(pic,x,y)
color = getColor(p)
setColor(getPixel(new,tarY,width-tarX-1),color)
tarY = tarY + 1
tarX = tarX +1
show(new)
return new
.. but I have no idea how I would go about writing a function on rotating it X amount of times. Anyone know how I can do this?
You could call rotate() X amount of times:
def spin(pic, x):
new_pic = duplicatePicture(pic)
for i in range(x):
new_pic = rotate(new_pic)
return new_pic
a_file = pickAFile()
a_pic = makePicture(a_file)
show(spin(a_pic, 3))
But this is clearly not the most optimized way because you'll compute X images instead of the one you are interested in. I suggest you try a basic switch...case approach first (even if this statement doesn't exists in Python ;):
xx = (x % 4) # Just in case you want (x=7) to rotate 3 times...
if (xx == 1):
new = makeEmptyPicture(height,width)
tarX = 0
for x in range(0,width):
tarY = 0
for y in range(0,height):
p = getPixel(pic,x,y)
color = getColor(p)
setColor(getPixel(new,tarY,width-tarX-1),color)
tarY = tarY + 1
tarX = tarX +1
return new
elif (xx == 2):
new = makeEmptyPicture(height,width)
# Do it yourself...
return new
elif (xx == 3):
new = makeEmptyPicture(height,width)
# Do it yourself...
return new
else:
return pic
Then, may be you'll be able to see a way to merge those cases into a single (but more complicated) double for loop... Have fun...

Algorithm needed to calculate difference between two times

I have an hour selection drop down 0-23 and minutes selection drop down 0-59 for Start time and End time respectively (so four controls).
I'm looking for an algorithm to calculate time difference using these four values.
Since they're not stored in fancy date/time selection controls, I don't think I can use any standard date/time manipulation functions.
How do I calculate the difference between the two times?
This pseudo-code gives you the algorithm to work out the difference in minutes. It assumes that, if the start time is after the end time, the start time was actually on the previous day.
const MINS_PER_HR = 60, MINS_PER_DAY = 1440
startx = starthour * MINS_PER_HR + startminute
endx = endhour * MINS_PER_HR + endminute
duration = endx - startx
if duration < 0:
duration = duration + MINS_PER_DAY
The startx and endx values are the number of minutes since midnight.
This is basically doing:
Get number of minutes from start of day for start time.
Get number of minutes from start of day for end time.
Subtract the former from the latter.
If result is negative, add number of minutes in a day.
Don't be so sure though that you can't use date/time manipulation functions. You may find that you could easily construct a date/time and calculate differences with something like:
DateTime startx = new DateTime (1, 1, 2010, starthour, startminute, 0);
DateTime endx = new DateTime (1, 1, 2010, endhour , endminute , 0);
Integer duration = DateTime.DiffSecs(endx, startx) / 60;
if (duration < 0)
duration = duration + 1440;
although it's probably not needed for your simple scenario. I'd stick with the pseudo-code I gave above unless you find yourself doing some trickier date/time manipulation.
If you then want to turn the duration (in minutes) into hours and minutes:
durHours = int(duration / 60)
durMinutes = duration % 60 // could also use duration - (durHours * 60)
This will compute duration in minutes including the year as factor
//* Assumptions:
Date is in Julian Format
startx = starthour * 60 + startminute
endx = endhour * 60 + endminute
duration = endx - startx
if duration <= 0:
duration = duration + 1440
end-if
if currday > prevday
duration = duration + ((currday-preday) - 1 * 1440)
end-if
First you need to check to see if the end time is greater than or equal to the start time to prevent any problems. To do this you first check to see if the End_Time_Hour is greater than Start_Time_Hour. If they're equal you would instead check to see if End_Time_Min is greater than or equal to Start_Time_Min.
Next you would subtract Start_Time_Hour from End_Time_Hour. Then you would subtract Start_Time_Min from End_Time_Min. If the difference of the minutes is less than 0 you would decrement the hour difference by one and add the minute difference to 60 (or 59, test that). Concat these two together and you should be all set.
$start_time_hr = 5;
$start_time_mi = 50;
$end_time_hr = 8;
$end_time_mi = 30;
$diff = (($end_time_hr*60)+$end_time_mi) - (($start_time_hr*60)+$start_time_mi);
$diff_hr = (int)($diff / 60);
$diff_mi = (int)($diff) - ($diff_hr*60);
echo $diff_hr . ':' . $diff_mi;
simple equation should help:
mindiff = 60 + endtime.min - starttime.min
hrdiff = ((mindiff/60) - 1) + endtime.hr - starttime.hr
This gives you the duration in hours and minutes
h1 = "hora1"
m1 "min1"
h2 "hora2"
m2 = "min2"
if ( m1 > m2)
{
h3 = (h2 - h1) - 1;
}
else
{
h3 = h2 - h1;
}
m1 = 60 - m1;
if (m1 + m2 >= 60)
{
m3 = 60 - (m1 + m2);
} else if (m3 < 0)
{
m3 = m3 * -1;
}
else
{
m3 = m1 + m2;
}
System.out.println("duration:" + h3 + "h" + m3 + "min");
If you have a function that returns the number of days since some start date (e.g. dayssince1900) you can just convert both dates to seconds since that start date, do the ABS(d1-d2) then convert the seconds back to whatever format you want e.g. HHHH:MM:SS
Simple e.g.
SecondsSince1900(d)
{
return dayssince1900(d)*86400
+hours(d)*3600
+minutes(d)*60
+seconds(d);
}
diff = ABS(SecondsSince1900(d1)-SecondsSince1900(d2))
return format(diff DIV 3600)+':'+format((diff DIV 60) MOD 60)+':'+format(diff MOD 60);
Hum: Not that simple if you have to take into account the leap seconds astronomers are keen to put in from time to time.

Resources