Drawing diamond shapes


My token number is JTKTU2AV-202322110417:059b4e141afb382956cd2ecd8e0f1c23f06b58088ede94174ffe9a41f7e09387

I need to present 6 diamond shapes simultaneously for a short duration of 50 ms followed by 150ms blank, and this is presented in a loop for n times. The shape is basically a square rotated 45 degrees, but now I’m not sure if I can use the ‘FillRect’ command to draw diamond shapes.

I see I could use ‘FillPoly’ for this, but it says in the documentation that this is “rather compute intense and slow operation”. Also, I’m not sure whether ‘FillPoly’ allows for multiple drawing in one command as in ‘FillRect’, apparently I’d need to write six ‘FillPoly’ commands independently for each diamond shape. Is that correct?

Basically, the code I have now looks like:

% Pos 1
circleangle_Pos1 = 120 * t_params.degree;
stimX_Pos1= cos(circleangle_Pos1) * t_params.cueRadius_Pixels;
stimY_Pos1= sin(circleangle_Pos1) * t_params.cueRadius_Pixels;
% Pos 2
circleangle_Pos2 = 60 * t_params.degree;
stimX_Pos2= cos(circleangle_Pos2) * t_params.cueRadius_Pixels;
stimY_Pos2= sin(circleangle_Pos2) * t_params.cueRadius_Pixels;
% Pos 3
circleangle_Pos3 = 180 * t_params.degree;
stimX_Pos3= cos(circleangle_Pos3) * t_params.cueRadius_Pixels;
stimY_Pos3= sin(circleangle_Pos3) * t_params.cueRadius_Pixels;
% Pos 4
circleangle_Pos4 = 360 * t_params.degree;
stimX_Pos4 = cos(circleangle_Pos4) * t_params.cueRadius_Pixels;
stimY_Pos4 = sin(circleangle_Pos4) * t_params.cueRadius_Pixels;
% Pos 5
circleangle_Pos5 = 240 * t_params.degree;
stimX_Pos5 = cos(circleangle_Pos5) * t_params.cueRadius_Pixels;
stimY_Pos5 = sin(circleangle_Pos5) * t_params.cueRadius_Pixels;
% Pos 6
circleangle_Pos6 = 300 * t_params.degree;
stimX_Pos6 = cos(circleangle_Pos6) * t_params.cueRadius_Pixels;
stimY_Pos6 = sin(circleangle_Pos6) * t_params.cueRadius_Pixels;

%% Compute diamond probe coordinates
diamWidth = 16;
diamHeight = 16;
xdiamCoord = [centerX, centerX - (diamWidth/2), centerX, centerX + (diamWidth/2)]';
ydiamCoord = [centerY + (diamHeight /2), centerY, centerY - (diamHeight /2), centerY]';
diamCoords = [xdiamCoord+stimX_Pos1 ydiamCoord+stimY_Pos1, xdiamCoord+stimX_Pos2 ydiamCoord+stimY_Pos2];
diamCoords1= [xdiamCoord+stimX_Pos1 ydiamCoord+stimY_Pos1];
diamCoords2= [xdiamCoord+stimX_Pos2 ydiamCoord+stimY_Pos2];
diamCoords3= [xdiamCoord+stimX_Pos3 ydiamCoord+stimY_Pos3];
diamCoords4= [xdiamCoord+stimX_Pos4 ydiamCoord+stimY_Pos4];
diamCoords5= [xdiamCoord+stimX_Pos5 ydiamCoord+stimY_Pos5];
diamCoords6= [xdiamCoord+stimX_Pos6 ydiamCoord+stimY_Pos6];

Screen('FillPoly', mainwin, [255 255 255], diamCoords1, 1);
Screen('FillPoly', mainwin, [50 50 50], diamCoords2, 1);
Screen('FillPoly', mainwin, [255 50 0], diamCoords3, 1);
Screen('FillPoly', mainwin, [255 50 0], diamCoords4, 1);
Screen('FillPoly', mainwin, [255 50 0], diamCoords5, 1);
Screen('FillPoly', mainwin, [255 50 0], diamCoords6, 1);

Screen('Flip', mainwin);

So, I’m not sure whether this is the most efficient way possible to draw diamond shapes, or I could rather use ‘FillRect’ for this too. Any hint would be very much appreciated.


FillPoly is one way, indeed you need one call per shape. “Compute intense” is relative, for something simple as a diamond square with four corners / vertices, it is negligible. Also, for convex shapes like these, one can set the optional ‘isConvex’ flag to tell the function, so it can save a lot of computations normally needed for convexity checks and processing of non-convex shapes. But you do that already.

Another way would be ‘FillRect’, but applying a rotation transform, cfe. DrawMirroredTextDemo.m lines 118-144, for applying a local transformation to any drawing commands. In that example replacing the Screen('glScale', w, 1, -1, 1); commands with a Screen('glRotate', w, 45); would rotate the text drawin in line 135 by 45 degrees, so if you’d use a ‘FillRect’ instead of a ‘DrawText’, you’d get a 45 degrees rotated rectange → your diamond shape. This is best done for complex shapes though, as the overhead of setting up the transform is much more than the actual drawing.

Yet another way is creating a texture that is just a solid color, and the use Screen(‘DrawTexture’) or Screen(‘DrawTextures’) to draw the image(s) of a square rotated by an angle. This might be more efficient than the two previous methods for not too big squares/diamonds. This latter method is conveniently implemented via the PsychDrawSprites2D() function and demonstrated in/via DotDemo(2); It can also do anti-aliasing for you.

I’d probably recommend the last PsychDrawSprites2D() approach for you.

But at only 6 such shapes and the speed of modern graphics card, it doesn’t really matter with your inter-stimulus intervals.


[18 minutes for this support incident, a total of 37 minutes used up out of 30 minutes paid for → This paid support license now completely exhausted.]

Thanks a lot for the suggestions. I’ll probably use ‘FillPoly’ then, but I’ll also have a look to the ‘PychDrawSprites2D’ function, considering that I was using ‘DrawDots’ for drawing small dots instead of small diamond shapes in a previous version of my code.
All the best,