get(0,'screensize') giving result [0 0 1 1] instead of actual pixels - matlab

During MATLAB-sessions,get(0,'screensize') first gives the correct resolution. Later on, the answer will become [0 0 1 1] though. This behaviour will only stop when I restart matlab, it is then the correct value again.
This error always happens when I run a specific part of our programme. It appears to happen after this specific line of code:
set(0,'PointerLocation',[.4*GUI.scrsz(3),.5*GUI.scrsz(4)],'units','normalized');
Even though I managed to isolate the error I can´t to figure out the reason for this behaviour. I am using MATLAB R2010b on Windows 7 64bit.
Please note that I´m not an advanced user of MATLAB, so please forgive me if i overlooked something obvious.Thanks in advance for your help.

The reason is that you set 'units' to 'normalized'. And your screen starts naturally in a corner -> [0 0 ... and fills the whole screen -> ... 1 1] (The first pair defines the position and the second pair height and width)
So the values are correct, just not showing the pixels anymore.
Just set it back to set(0,'units','pixels') after you finished the task before, which needed the normalized units. Or store your screensize at the beginning of your script in a variable to use it later on.
With get(0,...) you are getting default properties and with set(0,...) you change them, thats why it's normal again after restart, because Matlab is setting all values to default with every start, which is in your case 'units','pixels'.

Related

Strange shading behaviour with normal maps in UE4

I've been having some very strange lighting behaviour in Unreal 4. In short, here's what I mean:
Fig 1, First, without any normal mapping on the bricks.
Fig 2, Now with a normal map applied, generated based on the same black-and-white brick texture.
Fig 3, The base pixel normals of the objects in question.
Fig 4, The generated normals which get applied.
Fig 5, The material node setup which produces the issue, as shown in Fig 2
As you can see, the issue occurs when using the generated HeightToNormalSmooth node. As shown, this is not an issue relating to object normals (see Fig 3) or to a badly exported normal map (as there isn't one in the traditional sense), nor is it an issue with the HeightToNormalSmooth node itself (Fig 4 shows that it generates the correct bump normals).
To be clear, the issue here is the fact that using a normal texture at all (this issue occurs across all my materials) causes the positive Y facing faces of an object to turn completely black (or it seems, to become purely reflections-based, as increasing roughness on the material causes the black faces to become less 'shiny' looking).
This is really strange, I've tested with multiple different skylight setups, sun directions, and yet this always happens (even when lit directly), but only on +Y aligned faces.
If anyone can offer insight that would be greatly appreciated.
You're subtracting what looks like 1 from the input that then goes into multiply by 1, if I'm correct. This will, in most cases, make any image return black. This is because in UE4 and many other programs, colors in an image are determined by decimals of Red Green and Blue. These decimals fall in a range of 0 to 1. This means if I wanted to make red, I could use these values- R = 1 G = 0 B = 0. This matters because if R = 0 G = 0 B = 0, the result is black. When you use a multiply node in your example, what you are doing is having UE4 take each pixel of the image you fed into the node (if it was white, R = 1 G = 1 B = 1) and multiply its R, G, and B values by that number. Since zero multiplied by a number equals zero, all the pixels in the image are being set to have values of R = 0, G = 0, and B = 0. thus, all zeros, and you get black.
I also noticed you then multiplied it by one, which in most cases won't do a whole lot, since you're just multiplying the input by 1. If your input is 0, (black), multiplying it by one won't change it, cause 0 * 1 still equals 0.
To fix your issue, try changing the value you subtract from your input to be something smaller than one, say a decimal, such as 0.6 or 0.5
So I've discovered why this was an issue. Turns out there's a little option in the material settings called 'Tangent Space Normal'. This is on by default ('for convenience'), disabling this appears to completely fix the issue with the generated normal maps produced by HeightToNormalSmooth.

How can I control which monitor plots are displayed on?

I have a 3 monitor Gentoo Linux system running MATLAB. MATLAB runs on the center monitor. I need MATLAB to generate plots on the left monitor but it always plots on the right monitor.
I believe this is at least partially caused by the non-standard way I have my monitors arranged physically - essentially 2,3,1:
>> get(0,'MonitorPositions')
ans =
1 1 1920 1080
-3839 1 1920 1080
-1919 1 1920 1080
Is there a way I can control this as a default within MATLAB?
You can set the default figure position on the root object like so:
set(0, 'DefaultFigurePosition', [-3839 1 1920 1080]);
This will create windows that fill the left monitor by default. However, this default will likely reset each time you restart MATLAB, so you will have to put it in your startup file if you want it to persist from session to session.
Note: The documentation for the 'MonitorPositions' property of the root object says this:
The first two elements in each row indicate the display location with respect to the origin point. The last two elements in each row indicate the display size. The origin point is the lower-left corner of the primary display.
If you change which monitor is used as the primary display, the relative coordinates in the left two columns will change, meaning you will have to change the position value in the above line of code. If you think the display setup may change often, or you will be running code on different monitor setups, then you can ensure plots will always appear on the left-most monitor by looking for the monitor position with the lowest value in the left column. Here's how you could do it (also incorporating the previous default window size and position within a monitor):
monitorPos = get(0, 'MonitorPositions');
figurePos = get(0, 'DefaultFigurePosition');
[~, leftIndex] = min(monitorPos(:, 1));
set(0, 'DefaultFigurePosition', figurePos + [monitorPos(leftIndex, 1:2)-1 0 0]);

Can't Remove y = 0 Line in Matlab

edit: I figured it out and don't see a place to mark this as answered. Thanks for the suggestions though everyone!
A couple of weeks ago I was trying to force MATLAB to display a y = 0 line for a plot I was making. It was easy enough to search for, but apparently I made it automatic. Now I can't find anything even remotely similar to this new problem. When I run this code:
plot(x,y_known,x,y_simulated);
legend('Simulated','This stupid line right here','Known')
I get the following:
Notice the line at y = 0, it is not in the code. I wouldn't really care, but it is the second line in the figure and it messes up my ability to create a legend. i.e., if the legend entry was just:
legend('Simulated','Known')
then the legend would say that the known value was green, which is certainly not the case.
I don't really want to create a handle for every single line I plot in the future, and would much rather just get rid of this line. Can anyone provide some help, or at least point me in the right direction?
edit: The y = 0 line also changes its line properties based on whatever is supplied to the first plot entry. So plot(x,y1,'--',x,y2); makes both y1 and y = 0 dashed, but plot(x,y1,x,y2,'--'); would just render the second line dashed
As an absolute last resort (after failing to find how the line actually gets there), what you can do is access the Children property of your axes and delete the child which is the line you don't want.
Something along the lines of:
ch = get(gca,'Children');
delete(ch(2)); %// Where 2 should be replaced by the child index you're trying to delete.
There was an errant two much earlier in the code, giving a variable 2 columns instead of one. I didn't realize Matlab would be helpful be helpful and plot both columns (I've always explicitly told it to plot both). Just another case of someone not thinking in vector mode when using Matlab!

MATLAB colormapping issue with value 0

I already searched the web and stack overflow for answers to this (seemingly simple) question, however could't find the answer:
I am in the progress of writing a cellular automaton in MATLAB. I am using an n*m matrix with values between 0 and 15, from which I make an image using a colormap with 5 grey values (between 0 and 1). See the following code snippet to clarify this:
WIDTH = 100;
HEIGHT = 100;
fields = randi(16,HEIGHT,WIDTH)-1;
% here the grey values 0, 0.25, 0.5, 0.75 and 1 are mapped to the values 1 to 16
cmRow = [1;0.75;0.75;0.5;0.75;0.5;0.5;0.25;0.75;0.5;0.5;0.25;0.5;0.25;0.25;0];
specialGray = [cmRow, cmRow, cmRow];
colormap(specialGray);
image(fields)
Well my problem is, that there is no 0th row in the colormap that MATLAB would use, if a value 0 occurs. As a result, there is always one color missing.
Just using values from 1 to 16 instead of from 0 to 15 is unfortunately not an option, as I heavily rely on these values later in the script.
Is there something obvious, I am missing? Do you have any ideas how to tackle this issue?
Thank you very much!
Best regards,
René
The image function knows two type of color mapping: direct' (the default) and 'scaled'. If you use 'scaled', you can set the scale for the color with thecaxis` function. Thus, the following code should do the trick (but you can of course also transform the values as suggested by Oleg):
image(fields,'CDataMapping','scaled');
colormap(specialGray);
caxis([0 15]);

Matlab: opening propertyeditor or plotbrowser forces correct textbox annotation; annotation fails without it

I have a generally happily running program that takes files, plots them, spits out a pdf (letter size). I use annotations to put in a title above a set of three subplots, and to use as a footer with file info and date. I would like the title to be at the top of the page, filling up from margin to margin, centered.
I have two ways of running the program: in 'batch' mode and 'interactive' mode. When in 'interactive' mode, I create the figure with a simple figure() command. When in 'batch' mode, I create the figure with figure('visible','off'). Here is my command for making the annotation:
annotation(obj.hFigure(f),'textbox',[0 0.9 1 0.1],...
'String',title,...
'HorizontalAlignment','center',...
'FontSize',18,...
'LineStyle','none',...
'FitBoxToText','off');
Here, "obj.hFigure(f)" is simply a handle to the figure I am currently processing. As you can see, I place the figure near the top of the figure, and make sure that the text runs off the bottom of the box (in case it is larger).
My problem is with margins on the above annotation. In batch mode (no figures showing), I get 10% or so margins on either side of the text, which ruins the layout. In interactive mode (figures show up), I don't get the margins: the text correctly flows from one edge to the other.
I have narrowed down the problem to the following: I can get the correct response to the ps printing in batch mode if I make the figures visible (figure('visible','on')) AND open up
propertyeditor(gcf);
plotbrowser(gcf);
after each figure is plotted. This makes the program take about twice as long (which isn't a huge deal). But what I don't understand is: what do those two commands do that drawnow or refresh don't accomplish?!
I am unsure about your specific case, but when encountering this kind of problem in the past I have had great success by explicitly setting the figure size with:
set(gcf, 'Position', [100 100 300 300])
and then, before printing/saving setting the PaperPositionMode to auto, which seems to force the printed figure to be the same size as the one shown on screen:
set(gcf, 'PaperPositionMode','auto')