How to select an axes child in MATLAB? - user-interface

I have been looking everywhere but I can't find a site that shows how to do this.
The thing I want is to be able to select an object from an axes when I click it, so that I can change its colours and stuff.
I just can't figure out how to select a child, I can create objects but not select them.
I have this piece of code I use to create a line:
coord = ginput (2)
x = coord(:,1)
y = coord(:,2)
hline = line(x,y)
I'm not sure If i need to create the objects in an array so that I can select edit/delete them.
I believe I would need to use ButtonDownFcn, but probably I'm doing something completely wrong.
Any help would be appreciated, If I'm missing any information please let me know
Thanks

It is not necessary to use ginput and extract the coordinates. This is done automatically by an built-in "listener" in the figure-window. You are correct in assuming that you can use the ButtonDownFcn property on the object (line, lineseries, or other handle graphics object).
Try to create at simple line from (0,0) to (1,1):
hline = line([0,1],[0,1]) %# create line, save handle in hline
Then you can set the ButtonDownFcn to, for instance, a function handle to an anonymous function:
set( ...
hline, ...
'ButtonDownFcn', #(handle,event)(disp(['You clicked on the line!'])) ...
);
Now try to click on the line. It should print the text in the command window.
The function needs to be able to receive atleast two arguments: (1) the handle of the object itself (the line) and (2) an "event structure". I believe the second argument is just empty when you use line-objects. But your function still needs to receive atleast these two arguments (even if you do not use them).
Read more here: http://www.mathworks.com/help/techdoc/ref/line_props.html.
You can also use your own function (a named function in a file):
set( ...
hline, ...
'ButtonDownFcn', #(handle,event)(namedFunction(handle,event)) ...
);
... or you can use a struct-array if you (expectedly) have other arguments beyound those two.

Related

Selection script for maya

I'm noob in script but good in animation, I need some help to create a script selection.
I found an exemple :
import maya.cmds as cmds
# Get selected objects
curSel = maya.cmds.ls(sl=True)
# Or, you can also specify a type in the listRelatives command
nurbsNodes = maya.cmds.listRelatives(curSel, allDescendents=True, noIntermediate=True, fullPath=True, type="nurbsCurve", path=True)
cmds.select(nurbsNodes)
But It doesn't select all the character's controlers...
I would like If I select a character controler curve or locator and I run the script, the result is all controls who can be keyed should be selected. Without the referenced character name.
Thanks a lot for the one who can help
Currently the listRelatives command is being used to list all child nodes under the currently selected transforms, whose type is a NURBS Curve, e.g. type="nurbsCurve". Typically all nodes in Maya inherit from some other node type (It's worth checking the nodes in Maya help -> technical documents ->nodes). Luckily locator nodes and curves both inherit from 'geometryShape', so you should be able to replace "nurbsCurve" with "geometryShape", and that will probably get you most of the way there. You may need to ignore certain returned nodes though - i.e. polygonal meshes you are using for rendering.

Why in THREE.js the arithmetic expression in Object3D.translateX isn't evaluated as expected or Vector.copy doesn't work correctly in animate loop?

I'm trying to move an object called "car" via the dat.gui. If the user changes the x value using the dat.gui slider, the car should move along the x-axis of its local coordinate system.
here I have copied the part of the code that is causing me problems:
var m = new THREE.Vector3;
m.copy(car.position);
if (changed.key=='X') car.translateX(changed.value-car.worldToLocal(m).x);
My problem is that the expression in car.translateX always evaluates to the value that is in changed.value. The part after the minus has no effect at all or maybe is permanently 0. I have printed the values ​with console.log and the values ​​of car.position.x and m change in each step, but the subtraction still delivers in every step only the result that is already in changed.value anyway. Can someone help me and tell me why this happens?
Unfortunately, I am absolutely stuck.
car.worldToLocal(m)
I'm afraid this piece of code makes no sense since car.position (and thus m) already represents the car's position in local space.
Instead of using translateX() you achieve the same result by modifying car.position directly:
car.position.x = changed.value;

How can I add the P5-property to a s.Vector object?

I have two different variations of the
let diff = nearby.boid.velocity
console.log(diff.p5) //undefined
diff = p5.Vector.div(diff, nearby.d*nearby.d)
steering.add(diff)
Second:
let diff = p5.Vector.sub(this.position, nearby.boid.velocity);
console.log(diff.p5) // an object with the p5-property
console.log('')
diff.div(nearby.d*nearby.d);
steering.add(diff);
I want to normalize the code so I can put it in a function. In the first example, I can't use diff.div and in the second, I can't use p5.vector.div. p5.vector.sub is adding a the p5 property, can I do that without subtraction somehow?
I'm a little confused about what you're trying to do: why do you need the p5 reference inside your function? Why can't you use p5.Vector.div() in your second example? Can you post a small example that shows what you're trying to do, and why it won't work?
Keep in mind that there are two versions of the functions: static and non-static. For example:
p5.Vector.div() is static, takes two parameters, and returns a result without modifying the parameters.
myVectorInstance.div() is non-static. It takes one parameter, and modifies myVectorInstances to it contains the result.
If you want to create a function that does not affect the parameters, then you probably want to use the static version.
If you're curious, you can look at the code for p5.Vector here. Looks like it uses the p5 reference internally to convert between degrees and radians using the p5.toRadians() and p5.fromRadians() functions. I don't know why some instances of p5.Vector populate it and others do not, but it seem like an implementation detail that you aren't supposed to rely on.

MATLAB ConnectedComponentLabeler does not work in for loop

I am trying to get a set of binary images' eccentricity and solidity values using the regionprops function. I obtain the label matrix using the vision.ConnectedComponentLabeler function.
This is the code I have so far:
files = getFiles('images');
ecc = zeros(length(files)); %eccentricity values
sol = zeros(length(files)); %solidity values
ccl = vision.ConnectedComponentLabeler;
for i=1:length(files)
I = imread(files{i});
[L NUM] = step(ccl, I);
for j=1:NUM
L = changem(L==j, 1, j); %*
end
stats = regionprops(L, 'all');
ecc(i) = stats.Eccentricity;
sol(i) = stats.Solidity;
end
However, when I run this, I get an error says indicating the line marked with *:
Error using ConnectedComponentLabeler/step
Variable-size input signals are not supported when the OutputDataType property is set to 'Automatic'.'
I do not understand what MATLAB is talking about and I do not have any idea about how to get rid of it.
Edit
I have returned back to bwlabel function and have no problems now.
The error is a bit hard to understand, but I can explain what exactly it means. When you use the CVST Connected Components Labeller, it assumes that all of your images that you're going to use with the function are all the same size. That error happens because it looks like the images aren't... hence the notion about "Variable-size input signals".
The "Automatic" property means that the output data type of the images are automatic, meaning that you don't have to worry about whether the data type of the output is uint8, uint16, etc. If you want to remove this error, you need to manually set the output data type of the images produced by this labeller, or the OutputDataType property to be static. Hopefully, the images in the directory you're reading are all the same data type, so override this field to be a data type that this function accepts. The available types are uint8, uint16 and uint32. Therefore, assuming your images were uint8 for example, do this before you run your loop:
ccl = vision.ConnectedComponentLabeler;
ccl.OutputDataType = 'uint8';
Now run your code, and it should work. Bear in mind that the input needs to be logical for this to have any meaningful output.
Minor comment
Why are you using the CVST Connected Component Labeller when the Image Processing Toolbox bwlabel function works exactly the same way? As you are using regionprops, you have access to the Image Processing Toolbox, so this should be available to you. It's much simpler to use and requires no setup: http://www.mathworks.com/help/images/ref/bwlabel.html

how to pass parameters to a Matlab GUI file

i am new to matlab. While working through the Matlab GUI, i faced a problem which is as follows..i want to have 2 figure files, with one figure file calling the other. i know that just by calling the name of the 2nd fig file from the first fig file, we can call the 2nd figure. however, i also wish to send some parameters from one fig file to another.here i need to send the arguments and also obtain these parameters so as to do further processing.i havent been able to find a solution to this problem. i would be glad if someone helps me out with this problem. thanking you in advance
There are three ways I found to do this:
Method 1: Use setappdata and getappdata like so:
setappdata(0,'some_var',value)
some_other_var = getappdata(0,'some_var')
You would use setappdata() in the m-file for fig1 to store whatever data you wanted to pass around, and then call getappdata() in another m-file to retrieve it. The argument 0 to the two functions specifies the MATLAB root workspace, which is accessible by your program everywhere (i.e. it is global). As such, when you close your figures that data will still be available. You may want to use rmappdata to remove them.
Method 2: Use guidata:
Assuming you created your GUI with GUIDE, then you have access to a structure called handles which is passed around everywhere and which you can edit, and so you can do this in a GUI callback:
handles.some_var = some_value
guidata(hObject,handles)
Then you can access handles.some_var elsewhere in some other callback (because handles is automatically passed into it for you) in your other m-file:
some_other_var = get(handles.some_var)
Method 3: Use UserData:
Store the variable you want from your first figure:
set(name_of_fig, 'UserData', some_var)
Then to get it from your other one:
some_other_var = get(name_of_fig, 'UserData')
(Disclaimer: My actual knowledge of MATLAB is not all that great, but it helps to be able to find good resources like this and this, and even this from the official docs. What I've written here may be wrong, so you should definitely consult the docs for more help.)
I would do like this (assuming you're using the GUI builder GUIDE).
Let's say that your figures/m-files are named firstFigure.fig/m and secondFigure.fig/m. In the code of firstFigure, just call secondFigure and pass your parameters as arguments:
someNumber = 1;
someText = 'test';
aMatrix = rand(3);
secondFigure(someNumber, someText, aMatrix);
The arguments will be available to secondFigure as a variable varargin in the callback functions
function varargout = secondFigure(varargin)
and
function secondFigure_OpeningFcn(hObject, eventdata, handles, varargin)
varagin is a cell structure; use cell2mat and char to convert it back:
theNumber = cell2mat(varargin(1));
theText = char(varargin(2));
theTextAgain = cell2mat(varargin(2));
theMatrix = cell2mat(varargin(3));
This may help:
http://www.mathworks.ch/matlabcentral/newsreader/view_thread/171989
The easiest method is to wrap the parameters in a cell array and send them directly to the GUI constructor. A call with two parameters might look like:
figure2({param1, param2})
Then you can unpack the arguments in the opening function (figure2_OpeningFcn) with code like:
handles.par1 = varargin{1}{1};
handles.par2 = varargin{1}{2};
These lines must be placed somewhere before the line that says guidata(hObject, handles);. Then you can access handles.par1 and handles.par2 directly in all the other callbacks.
I assume you are using GUIDE to generate your GUI. You can find figure2_OpeningFcn in figure2.m which will be located in the same directory as figure2.fig.
Note: you can also return values from a figure, returnvalue = my_figure({my_input}). If you'd like instructions on that too, leave a comment and I'll extend my answer.

Resources