I need to optimise this AHK script, currently the script runs in around 2 seconds. I would ultimately like it to run >1 second, the best case would be 0.6 seconds. The basic functionality is the script is clicking on red boxes, of which there can be between 2 - 8. I'd love some help on ways to increase the speed of this script if possible.
Thanks, code below.
1::
; Activate the target window
WinActivate, Paint
; Define the search area
SearchLeft := 1047
SearchTop := 572
SearchRight := 1222
SearchBottom := 650
SetDefaultMouseSpeed, 0
; Start the timer
StartTime := A_TickCount
; Loop through all pixels in the search area and click on them
Loop {
; Search for the next pixel
PixelSearch, Px, Py, SearchLeft, SearchTop, SearchRight, SearchBottom, 0x0000FF, RGBFast, Fastest
if (ErrorLevel = 0) {
; Click on the pixel
Click, %Px%, %Py%, 1
}
else {
; If no pixel is found, exit the loop
break
}
}
; Calculate the elapsed time
ElapsedTime := A_TickCount - StartTime
; Output the elapsed time as a message box
MsgBox, % "Script completed in " . ElapsedTime . " milliseconds."
3::ExitApp
I have this autohotkey script that points to the entire word by pointing to the first word and if the cursor scrolls 110px in one direction. The code uses Ctrl + Shift + {Right} to select the next words, but for the previous words you can't use Ctrl + Shift + {Left} because the current word is deselected.
How could I solve this problem so that it selects well in this direction?
#If WinActive("ahk_exe chrome.exe") && A_Cursor = "IBeam" ; Is in Chrome and cursor is on text field
~LButton::
Click
MouseGetPos, x1
SetTimer, Check, 100
SoundBeep, 1500
KeyWait, LButton
SetTimer, Check, Off
SoundBeep, 1000
Return
#If
Check:
MouseGetPos, x2
f := Floor(Abs((x2 - x1) / 110)) ; calculate if the pointer have travel 110px
Switch
{
Case x2 > x1: Send ^+{Right %f%}
Case x2 < x1: Send % "{Right}^+{Left " f + 1 "}" ;Does not allow selecting the previous word while keeping the current word selected
}
Return
Background info (Optional reading):
I'm running simulations of reflections of sound waves in against boundaries. The medium conditions for the points in space are set using a matrix. Let's say the dimensions of the space is an N by N grid, and there are two speeds of sound I care about, c0 and c1.
Right now I'm using code like the following to generate barrier patterns
medium.sound_speed = c0*ones(N,N); % set the speed of sound to be c0 everywhere
medium.sound_speed(:, N/2:N) = c1; % set the right half of the grid to a different speed
medium.sound_speed(50:70, 50:70) = c1; % set a box to have a different speed
Or
% set all speeds to c0 except set the diagonal to c1
medium.sound_speed = c0*ones(N,N)-(c0*eye(N,N))+c1*eye(N,N);
However, I can't generate more complex boundaries with different curvatures.
Question
I want to programmatically create matrices with patterns reflecting functions. For instance, I want to enter f(x)=2 and for that to create a matrix that looked something like this, assuming N=6.
[ 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 0 0 0 ]
Or f(x)=0.5*x+1
[ 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 1 1
0 0 1 1 0 0
1 1 0 0 0 0
0 0 0 0 0 0]
I would also be able to generate curved patterns like f(x)=1/x, which seems to require some form of the Midpoint circle algorithm, used for drawing curvatures with pixels.
[ 1 0 0 0 0 0
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 1 0 0
0 0 0 0 1 1
0 0 0 0 0 0 ]
In reality, N is at least 128, so manually creating these matrices for shapes with some level of complexity is impractical, and I thought this was an interesting problem.
Does anyone know of some way to do this, or suggestions for alternative approaches?
Thank you in advance.
Edit:
I modified this implementation of Bresenham's algorithm to provide a matrix with the desired line given an origin and an ending point.
function M=bresenham_line(point)
if (abs(point(4)-point(2)) > abs(point(3)-point(1))) % If the line is steep
x0 = point(2);y0 = point(1); x1 = point(4);y1=point(3);% then it would be converted to
token =1; % non steep by changing coordinate
else
x0 = point(1);y0 = point(2); x1 = point(3);y1=point(4);
token = 0;
end
if(x0 >x1)
temp1 = x0; x0 = x1; x1 = temp1;
temp2 = y0; y0 = y1; y1 = temp2;
end
dx = abs(x1 - x0) ; % Distance to travel in x-direction
dy = abs(y1 - y0); % Distance to travel in y-direction
sx = sign(x1 - x0); % sx indicates direction of travel in X-dir
sy = sign(y1 - y0); % Ensures positive slope line
x = x0; y = y0; % Initialization of line
param = 2*dy - dx ; % Initialization of error parameter
for i = 0:dx-1 % FOR loop to travel along X
x_coord(i+1) = x; % Saving in matrix form for plot
y_coord(i+1) = y;
param = param + 2*dy; % parameter value is modified
if (param >0) % if parameter value is exceeded
y = y +1*sy; % then y coordinate is increased
param = param - 2*(dx ); % and parameter value is decreased
end
x = x + 1*sx; % X-coordinate is increased for next point
end
M = zeros(size(x_coord,2), size(y_coord,2));
for i=1:1:size(x_coord,2)
x = x_coord(i);
y = y_coord(i);
M(x,y) = 1;
end
M
Implemented like so:
c1 = 0;
M = bresenham_line([1 1 Nx/2+1 Ny+1]);
medium.sound_speed = c0*ones(Nx,Ny) - (c0*M) + c1*M;
No progress on curved function shapes yet.
A way to get some similar results:
f = #(x)0.5*x; %create the function (x should be written even if the function doesn't depend on x: #(x) 0*x + 2)
N = 6; %choose the size of the atrix
M = zeros(N,N); %create an empty matrix
x = (1:N);
y = round(f(x-1)); %discretization
x(y>N-1|y<0) = [];
y(y>N-1|y<0) = [];
M(sub2ind(size(M),y+1,x)) = 1;
M = flipud(M)
So you can choose your function, then the result in your matrix will look like a discretization of a normal plot.
This is a slightly 'dirty' way of getting something like this, although I you best bet might Bresenham's algorithm.
N = 128;
[X,Y] = meshgrid(1:N,1:N);
bound1 = Y<2*X;
bound2 = Y<2*X+1;
M = xor(bound1,bound2);
bound1 you can define any function y=f(x), and mark the area under it. with bound2 you select and area that is slightly higher (shifted up). Once you take and xor of the two area you get just the desired y=f(x) marked. I think that in order to get reasonable results the shift might be different for more complicated function.
For illustration I used imagesc (the flipud is just for make the (0,0) in the bottom left, instead of the top left):
imagesc(flipud(M));
Edit
Indeed for some function this might not be the best. For example for y=x^2, you have to increase the shift and still does not look great.
bound1 = Y<X.^2;
bound2 = Y<X.^2+15;
M = xor(bound1,bound2);
In image() , how to define an injection of the colour to the value on matrix ?
I'm writing a programme to make colour chart on (x,y) coordinate-plane
Shows the hazard ratio from a value of x-axis and y-axis.
(eg.) x-axis is for "age", and y-axis is for "blood pressure", and if the third or upper dimension (z) is there, one colour chart is made for each z unique value.
I'm trying image(), but it isn't what I want because the colour on chart is defined on each (x,y)coordinate-plane, so only the (x,y) effect is represented.
(the effect of z-value is treated like as intercept.)
I think that to define injection of the colour to the value in my function would solve
this problem.
In my function , I define a matrix
mat.for.map[i,j] <- exp ( yax[i] * yest
+ xax[j] * xest
+ zax * zest
+ cat1
+ cat2 )
'xax' is sequence for x-axis
xax <- seq ( xlow , xup , length.out = xlen )
'yax' is for y-axis
yax <- seq(ylow,yup,length.out = ylen)
'xest' is hazard for variable-x
'yest' is for variable-y
and I got a dataset of hazars ratio
hazards <- c( 0.1302 , 0.0154 , -0.0030 , 0.5971 , 0.3773
, 0.1300 , 0.0159 , -0.0017 , 1.1522 , 0.3390
, 0.1037 , 0.0133, 0.0121 , 1.2249 , 0.3647
, 0.1480 , 0.0045 , 0.0034 , 1.5109 , 0.7472)
rowname1 <- c( "age" , "sbp" , "TotCho" , "DM" , "smk" )
colname2 <- c( "Stoke" , "CHD")
colname1 <- c( "men" , "women" )
array.hazards <- array(hazards, c(5,2,2))
dimnames(hazards)<- list(rowname1,colname1,colname2)
and if the third or upper dimention is defined
in argument 'z'(value) , 'zest'(hazard) and 'cat1' , 'cat2' ,
they are added to the values in 'mat.for.map'.
THIS IS MY PROBLEM
when I change 'z' or 'cat1' or 'cat2' ,the values in 'mat.for.map' changes ,
but the colours on chart does not.
My function is below
chart.make <- function(xest ,yest,
zest, xup,xlow,xlen
,yup,ylow,ylen
,zup=NULL,zlow=NULL,zlen=NULL,
xlab=NULL,ylab=NULL,
cat1=0,cat2=0) {
xax <- seq(xlow,xup,length.out = xlen)
yax <- seq(ylow,yup,length.out = ylen)
zax <- z
mat.for.map <- matrix(c(rep(0,length(xax)*length(yax))),
ncol=length(yax))
for(j in 1:length(xax)) {
for(i in 1:length(yax))
mat.for.map[i,j] <- exp(xax[j]*xest+yax[i]*yest+zax*zest+cat1+cat2)
}
list.chart <- list(xax,yax,mat.for.map)
names(list.chart) <- c("x","y","z")
return (image(list.chart,col=rainbow(100),xlab=xlab,ylab=ylab,useRaster = TRUE))
}
For example
hazards <- c( 0.1302 , 0.0154 , -0.0030 , 0.5971 , 0.3773
, 0.1300 , 0.0159 , -0.0017 , 1.1522 , 0.3390
, 0.1037 , 0.0133, 0.0121 , 1.2249 , 0.3647
, 0.1480 , 0.0045 , 0.0034 , 1.5109 , 0.7472)
rowname1 <- c( "age" , "sbp" , "TotCho" , "DM" , "smk" )
colname2 <- c( "Stoke" , "CHD")
colname1 <- c( "men" , "women" )
array.hazards <- array(hazards, c(5,2,2))
dimnames(array.hazards)<- list(rowname1,colname1,colname2)
pdf("chart1.pdf")
z1 <- chart.make(
array.hazards["sbp","women","CHD"],array.hazards["TotCho","women","CHD"]
,zest=array.hazards["age","women","CHD"]
,240,90,30
,279,160,6,zup=75,
,ylab="Total Cholesterol",xlab="Sistlic Blood Pressure"
,cat1=array.hazards["smk","women","CHD"])
mtext(text="CHD in women 70<age<80,smoker,DM",side=3,cex=1)
dev.off()
pdf("chart2.pdf")
z1 <- chart.make(
array.hazards["sbp","women","CHD"],array.hazards["TotCho","women","CHD"]
,zest=array.hazards["age","women","CHD"]
,240,90,30
,279,160,6,zup=75,
,ylab="Total Cholesterol",xlab="Sistlic Blood Pressure"
,cat1=array.hazards["smk","women","CHD"]
,cat2=array.hazards["DM","women","CHD"])
mtext(text="CHD in women 70<age<80,smoker",side=3,cex=1)
dev.off()
As I comment at Paul Hiemstra, I'm sorry I can't show you a example of what I want ,so I present a simlified one.
x <- seq(1:200,by=2)
z <- 20
mat1 <- matrix(x,ncol=10)
mat2 <- matrix(x:z,ncol=10)
mat3 <- matrix(x+z,ncol=10)
image.1 <- image(mat1,col=rainbow(100))
image.2 <- image(mat2,col=rainbow(100))
image.3 <- image(mat3,col=rainbow(100))
I think my problem is equal to 'image.1 is same to image.3,the effect of adding z is not reflected in colour on chart.'
Thank you very much for your time. (I'm afraid of being closed)
A quick attempt:
library(ggplot2)
ggplot(melt(array4hm), aes(x=X1,y=X2,fill=value))+geom_tile()+facet_grid(.~X3)