Point selection in pictures with custom scale - imagej

I try to analyze images with Fiji. Therefore I first “calibrate” the scale with set scale run(“Set Scale…”, “distance=52.6 known=30 pixel=1 unit=no global”); and then make a rectangle as seen in the picture: Pic 1. Then I execute a measurement with run(“Measure”); and try to make a point at the centre of the rectangle with makePoint(XPos, YPos, “small yellow hybrid”); as shown here: Pic 2.
XPos and YPos refer to the measured center coordinates of the rectangle. However the point is totally misplaced. I saw that the point is placed based on the pixels in the brackets and not based on my scale as seen in the second picture. Does anyone understand this behaviour, and how to help it?
Full Code:
run("Set Measurements...", "area centroid fit display redirect=None decimal=3");
run("Measure");
XPos=getResult("X", nResults-1);
YPos=getResult("Y", nResults-1);
print("Point placed at X "+XPos+" and Y "+YPos+".");
makePoint(XPos, YPos, "small yellow hybrid");
Would be happy if you could help me.
Best Max

Answer from biovoxxel on forum.image.sc
You can try the following after running the measurement. waitForUser("make a rectangular selection"); getSelectionBounds(x, y, width, height); makePoint(x+width/2, y+height/2); This is independent of the Results table and should produce the correct point position.

Related

How to reset a Rectangle's x,y,width,height, after transform

I have an app that uses konvajs, where I set rectangles to be resizable. I have it set such that after I transform the rectangle I set the scaleX and scaleY to 1 so I can just use x, y, width, and height. I do this with the following code:
myRectangle.on('transformend', function() {
myRectangle.width(Math.round(myRectangle.width() * myRectangle.scaleX()));
myRectangle.height(Math.round(myRectangle.height() * myRectangle.scaleY()));
myRectangle.scaleX(1);
myRectangle.scaleY(1);
});
However, sometimes after I resize (usually if I "flip" the rectangle by dragging up or to the left), the x, y, width and height are strange values. Sometimes the width or height is negative, sometimes it seems like the x and y positions do not refer to the top left of the rectangle. I want to be able to extract information about the rectangle, so I would like position to be top left of the rectangle with positive width and height values. I don't mind resetting these values after the rectangle is tranformed, but I am not quite sure how konvajs is calculating the x,y,width, and height so I can't properly reset them. Is there some metric indicating when a tranform "flips" a rectangle? Or some other way to reset it?
It seems that setting flipEnabled and rotationEnabled to false on the transformer prevents rotations from happening.
To get a visual sense of what is happening to the attrs during the transform, take a look at the demo in the official docs here and pay special attention to width/height, rotation and scale as you resize by dragging the right edge first, then repeat with the bottom edge.
It will help to understand that dragging a Transformer handle changes the scale of the rectangle - not the width or height. However this is not the end of the story - if you 'flip' the shape in the horizontal axis then you will see that the rotation is changed from zero to 180 degrees and the scaleX remains positive. But if you drag and flip the shape in the vertical axis then there is no rotation effect and the scaleY switches to negative.
Long story short - at the moment I can't think of a useful use-case that requires trying to redraw the rectangle without scale or rotation affects, which I will refer to as the 'plain' rect versus the 'exotic' rect you get after using the Transformer.
If the use-case is hit detection via your own math then you have everything you need to know in the rects x & y, width & height, rotation and scaleX & scaleY. Even if you could get the attrs for a plain rect you would still have the same params to plug into your math, so recomputing the plain rect is wasted effort.
If the use-case is storage (serialization) of the rect's attrs then again the same point as above - you need to store the position, rotation, size, and scale so as to be able to redraw it later.
A legitimate use-case for resetting scale to 1 would be if your app's business case requires it. But this only covers resetting:
rect.seAttrs({
width: rect.width() * scaleX,
height: rect.height() * scaleY,
scaleX: 1,
scaleY: 1
}
and leaves the rect at the same position and rotation.
Conclusion: attempting to recompute a plain rect from an exotic rect may not be worth the effort in some cases.

Offset two child-charts within a VictoryChart

I have a boxplot and a scatterplot within a VictoryChart and want them shifted a number of pixels in the non-domain axis.
My current code and resulting chart are here: https://codesandbox.io/s/beautiful-violet-opclp?file=/index.js
Now I want the red triangle to be placed a bit higher, so about 15 pixels in the y-direction upwards. I tried padding, domainPadding, dx, dy, but nothing works really.
Any hints are appreciated!
By creating a custom point, the actual position can be set. See https://codesandbox.io/s/focused-lederberg-i8ddx?file=/index.js

Convert Scene's (x, y) to screen's (x, y)

I have an application built with SceneKit that is currently displaying several nodes. I can figure out which node is pressed and want to use that to make a label appear below the Node that was touched. Now, when I set the label's center the following way...
nameLabel.center = CGPointMake(CGFloat(result.node.position.x), CGFloat(result.node.position.y+20)
…it appears in the upper left corner since the node is on (1, 0). What I figured is that the sceneView's (0, 0) is in the center of the screen while the actual physical display's (0, 0) is in the top left corner.
Is there a way to convert the two different numbers into each other? (I could hardcode since I know where the Node's are or create a separate label for each Node but that is not really a perfect solution.)
Thanks in advance :)
You can use the projectPoint: method:
var projected = view.projectPoint(result.node.position))
//projected is an SCNVector3
//projected.x and y are the node's position in screen coordinates
//projected.z is its depth relative to the near and far clipping planes
nameLabel.center = CGPointMake(CGFloat(projected.x), CGFloat(projected.y+20)

CATransform3D - understanding the transform values

The picture shows a simple UIView after applying the following transform:
- (CATransform3D) transformForOpenedMenu
{
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0 /450;
transform = CATransform3DRotate(transform, D2R(40), 0, 1, 0);
transform = CATransform3DTranslate(transform, 210, 150, -500);
return transform;
}
I'm trying to make the distances highlighted with black to have equal length. Could you please help me understand the logic behind the values and calculations?
Cheers
UPD Sept 13
Looks like removing 3DTranslate keeps distances equal. I see I can use layer's frame property to reposition rotated view to the bottom left of the screen. Not yet sure, but this might actually work.
The .m34 value you are setting is best set on the sublayerTransform of the containing view rather than the view you are transforming.
I don't fully understand the maths behind affine transforms so I made this project which allows me to play around with the transform values to achieve the effect I want. You can plug in the values from your code above and see what it looks like, though note that there is already a perspective value applied using the sublayerTransform property mentioned above.
For your specific case, I think you want to adjust the anchor point of the layer to (0.0,0.5) and apply the rotation transform only. This assumes you want the menu to swing back like a door, with the hinges on the left edge.
The problem you're seeing is caused by your CATransform3DTranslate call. You're essentially setting the Y Axis off center, and hence seeing a different perspective view of the frame.
Think of it this way;
You're standing in the center of a long narrow field stretching off into the horizon. The edge of the field appears as if it is converges to a center point somewhere off in the distance. The angle of each edge to the converging point will appear equal if you are at the center of the field. If, on the other hand, you move either to the left or the right, the angles change and one will seem greater than the other (inversely opposite of course).
This is essentially what is happening with your view; As your converging points are to the right, changing the Y axis away from 0 will have the same effect as moving to the left or right in my example above. You're no longer looking at the parallel lines from the center.
so in your code above Setting the ty in CATransform3DTranslate to 0 Should fix your problem I.E.
transform = CATransform3DTranslate(transform, 210, 0, -500);
You may also need to alter the tz and tx Value to make it fit.
OK, so what eventually solved my question is this:
3D transform on Y axis to swing the view like a door transform = CATransform3DRotate(transform, D2R(40), 0, 1, 0);
set Z anchor point on a layer, to move it back targetView.layer.anchorPointZ = 850;
adjust layer position so that the view is located slightly to the bottom left of the parent view:
newPosition.x += 135 * positionDirection;
newPosition.y += 70 * positionDirection;
This sequence adjusts position without CATransform3DTranslate and keeps the 'swinged' effect not distorted.
Thanks everybody!

How do I find the lowest or highest point on a UIView being dragged with UIAttachmentBehavior?

Depending on where the anchorPoint is with UIAttachmentBehavior, the view can be quite rotated, so it's in more of a diamond shape than a square. In these situations, where it's rotated say 90°, how do I find what the lowest or highest point of this UIView is (in relation to the window)?
It's easy enough when the UIView is a (non-rotated) square, as I can just use CGRectGetMaxY (or min) and the x value doesn't matter, and then use convertPoint, but with the rotation the x value seems to have a real importance, as if I choose maxX, it will tell me the bottom right's point, while minX will give me the bottom left's.
I just want the lowest point that exists in the UIView. How do I get this?
EDIT: Here's some code showing how I'm attempting it currently:
CGPoint lowestPoint = CGPointMake(CGRectGetMinX(weakSelf.imageView.bounds), CGRectGetMaxY(weakSelf.imageView.bounds));
CGPoint convertedPoint = [weakSelf.imageView convertPoint:lowestPoint toView:nil];
The tracking of convertedPoint's y value completely changes depending on what I supply for the x value in lowestPoint's CGPointMake.
The view's frame is its bounding box. Normally you should be careful about using the frame of a transformed view, which is precisely what a rotated-by-UIKit-Dynamics view is. But it does give the info you are after.

Resources