I have a rectangular image which gets transformed applying
image.setLayoutMatrix3D(matrix3D).
I need to calculate the actual dimensions and position (in pixels) of the image after the transformation.
In this scenario there are no rotations to the image applied. The matrix3D has the following structure:
1 0 0 0
0 1 0 0
0 0 1 0
value1 value2 value3 1
Provided that the original position and size of image are originalWidth, originalHeight, originalX and originalY how can I calculate the new dimension and position?
Thanks!
Admittedly, I've never done this with a matrix applied, but, I believe you can use: image.getLayoutBoundsWidth(), image.getLayoutBoundsHeight(), image.getLayoutBoundsX(), and image.getLayoutBoundsY() to get these values.
These methods from the ILayoutElement interface have a default boolean argument, postLayoutTransform (defaults to to true). When postLayoutTransform is true, the functions return values with the transformation applied.
Related
I have a set of scatter points which I want to connect, as shown below. I want to connect the points, but I want to hide the origin while keeping the point (x1, y1). How do I do this?
fig.add_trace(go.Scatter(x=[0, x1], y=[0, y1])
You can set the opacity of the markers to a value between 0 and 1; 0 meaning invisible, and 1 meaning totally opaque
fig=go.Figure()
data=[0,1,2]
dot_opacity=np.ones(len(data))
dot_opacity[0]=0
fig.add_trace(go.Scatter(x=[0, 1,3], y=[0, 1,2], marker=dict(opacity=dot_opacity)))
fig.add_trace(go.Scatter(x=[0, x1], y=[0, y1], alpha=0)
set alpha between 0 to 1
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html
You can use mode parameter to hide markers as follows:
fig.add_trace(go.Scatter(x=[0, x1], y=[0, y1], mode="lines")
The API reference of Scatter states:
mode – Determines the drawing mode for this scatter trace. If the provided mode includes “text” then the text elements appear at the coordinates. Otherwise, the text elements appear on hover. If there are less than 20 points and the trace is not stacked then the default is “lines+markers”. Otherwise, “lines”.
This is what happens in my Tetris game right now: The hitbox for the J block is 60x40, and even though there is in reality nothing there in the actual image editor, it is taken as a hitbox. Meaning, the two invisible squares at the top right of the J block count in the hitbox, and I want to exclude it.
This is the spritesheet seen in the photo editor -- GIMP.
I tried to copy and paste the code from this example, but python immediately bugged out and said, "No module named math". I'm using python 2.7 & pygame 1.9.1.
I have pastebins for all of the code... mcve is the main one to run.
`https://pastebin.com/Zze42KmZ`
`https://pastebin.com/q5rEpk3e`
`https://pastebin.com/ChGvrMu8`
`https://pastebin.com/ppb3cREL`
How can I exclude the squares in the hitbox? Thank you and I apologize for sucking.
I'd have to argue that using one 'hitbox' for J element is not possible. That is why you have pygame detecting hit with two boxes that are not there.
Why is that?
Because 'hitbox' is one rectangle. That rectangle has its height and width and it matches the J's element height and width. Everything inside that rectangle is part of same 'hitbox'. It really doesn't matter if image that represents that element has transparent part or not.
Hitbox is not based on image and its transparent parts, it's based on rectangle that surrounds image.
That is why you have to have at least 2 rectangles that will cover both parts of J element i.e. 3 vertical squares and 2 horizontal ones. That kind of complicates the whole thing a bit. But you should be able to use child subsurfaces and use collision detection on both of them.
I'd also argue that it is not good to use pygame's collision detecting at all for this purpose. Better approach would be that you do it by using 2D matrix where you store 'O' for empty square and 'X' for occupied one. In each step you have your element at X,Y coordinate and you test if lowering it by 1 step you encounter occupied space in matrix. This is just a suggestion though.
Example of clear 5 rows x 4 columns matrix:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
Example of J element at (1, 1) coordinate:
0 0 0 0
0 0 J 0
0 0 J 0
0 J J 0
0 0 0 0
Pay attention that pygame's coordinate system has (0,0) coordinate in top left corner of the screen. That matches with coordinates of 2D matrix generated.
I am trying to include a simple density calculation in access 2016, but the form returns a value of 0 if the input dimensions (mass or sphere diameter) are < 0.5. The field works fine for larger dimensions, so I assume that the smaller values are getting rounded to 0 somewhere along the way, but I can't figure out where.
For the inputs in my table, I have Field Names "green mass", "green pole", and "green equator" where the data type for each is set to "number," the Field Size is set to "single" (vs. double or decimal), and the Decimal Places is set to 4 digits
The resulting density is displayed in the Field "apparent green density" where the data type is set to "calculated," the Result Type is set to "single" and the Decimal Places is set to 4 digits.
After looking at various access forums and websites, I'm pretty sure I want to use single or double as my field size, but I've also tried decimal and byte and integer I keep getting 0.
Can anyone explain why this isn't working?
The equation is below. It's a bit complicated because it's a 3-part If statement (if dimensions for a sphere are given, caclulate density of a sphere, if dimensions of a disc are give, calculate density of a disc, if dimensions of a cube...) All three cases work for large dimensions (>0.5), but all 3 result in 0 for dimensions <0.5.
IIf([GreenPole],[GreenMass]/(3.14159265359/6*2.54^3*(([GreenPole]+[GreenEquator])/2)^3),IIf([GreenDia],([GreenMass]/(3.14159265359*([GreenDia]/2)^2*[GreenHeight]*2.54^3)),IIf([GreenLength],[GreenMass]/([GreenLength]*[GreenWidth]*[GreenThickness]*2.54^3),0)))
The first part of the equation for density of a sphere, is:
`IIf([GreenPole],[GreenMass]/(3.14159265359/6*2.54^3*(([GreenPole]+[GreenEquator])/2)^3),0)
Oliver Jacot-Descombes got me started in the right direction. I don't have much experience at all with coding, but I think what happened is that field identified in my IIf statement is somehow transformed into a boolean or yes/ no field and anything less than 0.5 is rounded to a no and the result of the truepart is then 0.
I modified the code to:
IIf([GreenPole]>0,[GreenMass]/(3.14159265359/6*2.54^3*(([GreenPole]+[GreenEquator])/2)^3),0)
And everything works now. (I also modified the second and third IIf statments to IIf([GreenLength]>0 and IIF([GreenDia]>0..)
How is a transformation matrix defined?
I have the values defining scale, skew, and translation. I would like to find the transformation matrix they represent.
Scale x/y can be any number.
Translation x/y can be any number.
Skew x/y is in degrees between -180 and 180.
How can I find the transformation matrix for these values?
I am working with values from Flash, and would like the matrix to be formatted like this, so that I can export this matrix and apply the same transformation in another language :
| a c u |
| b d v |
| 0 0 1 |
I need to be able to go from the parameters to the matrix outside of AS3/JSFL/Flash.
(Specifically I want to use C#, but I want an answer that doesn't depend on a given language.)
This link talks about how matrices work in Flash, and I understand most of it. However from what I can tell, it does not describe how to go from position/scale/skew values to a matrix.
http://www.senocular.com/flash/tutorials/transformmatrix/
I know there is a .matrix property of flash display objects, but I am working with the given values outside of flash, and need to find a solution without using that.
Actionscript's skew is misbehaving
Given the usual definitions of tranformations in Cimbali's answer, I'm still having problems with building a matrix from its skew parameter.
Here is an example set of data:
A) Object Properties (logged directly from Flash using JSFL, element.x, element.skewX, etc...)
x: 0
y: 0
scaleX: 1
scaleY: 1.0000152587890625
skewX: 19.9998779296875
skewY: 0
B) Transform Matrix (logged directly from Flash using JSFL, element.matrix)
1 | 0 | 0
-0.342 | 0.94 | 0
0 | 0 | 1
Here is what I tried:
sx = tan(19.9998779296875 * PI / 180) = tan(0.34906372) = 0.36396782164
Scale Matrix Skew X Matrix Result Matrix
1 | 0 | 0 1 | 0 | 0 1 | 0 | 0
0 | 1 | 0 x 0.36 | 1 | 0 = 0.36 | 1 | 0
0 | 0 | 1 0 | 0 | 0 0 | 0 | 1
SkewY is 0, so there's no reason to multiply again using a Skew Y Matrix.
So why is my Result Matrix so much different than the matrix posted by Flash?
In this example my graphic is originally 200 x 100 px. It does not inherit transformations from any parent (the parent is definitely not transformed in any way). However, when I place the graphic on the stage and ONLY change the skew X value to 20°, the Height in the properties panel changes from100 to 94px, but Scale Y stays at 100%.
In case you're not familiar with Flash IDE, when you adjust ONLY the skew X value, it does not simply push the corners of the graphic left/right. It actually makes the corners move on an arc, as you increase skew X, the parallelogram comes shorter vertically.
(I realize I have rounded some numbers, but that is only for ease of displaying them here.)
Applying successive transformations is, for some strange reason, called "concatenating matrices" in actionscript 3, which as your link explains, and is done by multiplying matrices : read section "Matrix Multiplication" completely : it starts by defining matrix multiplications and ends litteraly by A*B -> B.concat(A);.
Note that the order in which transformations are applied is important : B*A is not A*B. In both A*B and B.concat(A);, B is applied before A. You can think of it as A*(B*(x,y,1)) thanks to the associativity of the matrix product. This is also explained in the section "Concatenated Matrices" of your link, where a child element is transformed by its matrix, and then by its parent matrix, which is shown to be equivalent to a single transformation by child_matrix.concat(parent_matrix);
However the missing piece of the puzzle is that for each operation you describe, there is a corresponding transformation matrix. They are all illustrated and explained in adobe's reference on Matrices. There is however a small mistake on the illustration of skew matrices, you should refer to this stackoverflow question instead.
Here is the illustration from the wikipedia page on the topic, which is just as clear :
Note that all reflections can be expressed by scaling with W and/or H having -1 value. For shear expressed as angles, just use A = tan(a) in the images above.
However, it seems that flash disagrees on the meaning of "skew", and instead of preserving one coordinate while skewing the other, it preserves the lengths that were originally along that coordinate. Or, as you describe it, if you skew along X a rectangle, (some of) its vertices aren't pushed left or right, but move on an arc.
As it seems, they skew one coordinate, then correct the elongation of the figure by scaling the other coordinate. Luckily the factor by which this happens is easily predictable since we know trigonometry : it is the cosine of the angle.
So whenever you have a skewX by an angle a in flash, you have to use the following product of matrices (expressed using definitions from the image above) : matrix(scale with W=1 and H=cos(a)) * matrix(skew along x with A=-tan(a))
It would only be logical that defining a skewY in flash would yield in a reasonable programming language matrix(scale with W=cos(a) and H=1) * matrix(skew along y with B=-tan(a))
I'm currently making a color picker (pretty standard one, pretty much the same as photoshop with less options at the moment: still in early stage). Here's the picture of the actual thing : http://i.stack.imgur.com/oEvJW.jpg
The problem is : to retrieve the color of the pixel that is under the color selector (the small one, the other is the mouse), I have this line that I thought would do it :
_currentColor = Convert.hsbToHex(new HSB(0,
((_colorSelector.x + _colorSelector.width/2)*100)/_largeur,
((_colorSelector.y + _colorSelector.height/2)*100)/_hauteur
));
Just to clarify the code, I simply use the coordinates of the selector in order to create a new HSB Color (saturation is represented on the X axis and brightness (value) on the Y axis of such a color picker). I then convert this HSB Color to Hexadecimal and assign it to a property. The hue is always set to 0 at the moment but this is irrelevant as I only work with pure red to test.
It partially does what I wanted, but the returned color values are inversed for most of the corners:
for (0,0) it's supposed to return 0xFFFFFF, but it returns 0x000000 instead
for (256, 0) it's supposed to return 0xFF0000, but it returns 0x000000 instead
for (0, 256) it's supposed to return 0x000000, but it returns 0xFFFFFF instead
for (256, 256) it's supposed to return 0x000000, but it returns 0xFF0000 instead
I tried many variations in my code, but I just can't seem to fix it properly. Any reply/suggestions are more than welcomed!
I think the error (or one of them) is using values in the range 0..256 which seems to lead to overflows, try to use 0..255 instead.
Just swap the X and Y axis and it's solved.
Assuming the registration point is centered, which seems to be the case since you're doing:
(_colorSelector.x + _colorSelector.width/2)
I think you formula should look something like this:
(_colorSelector.x + _colorSelector.width/2) / _colorSelector.width
If your registration point is at (0,0), it should be just:
(_colorSelector.x / _colorSelector.width);
The above should give you a number in the range 0...1
Also, you should invert this value for brightness (because a low y value represents a high brightness and a high y value, low brightness; so brightness decreases along the y axis, while saturation increases along the x axis). So for your y axis you should do:
1 - ((_colorSelector.y + _colorSelector.height/2) / _colorSelector.height)
(Again, assuming the registration point is centered).
If your conversion function expects percentages, then you should multiply by 100
(_colorSelector.x + _colorSelector.width/2) / _colorSelector.width * 100
(1 - ((_colorSelector.y + _colorSelector.height/2) / _colorSelector.height)) * 100
Maybe I'm missing something, though. I'm not sure where _largeur and _hauteur come from, but it looks like these are width and height. I think you should use the _colorSelector height and width, but I could be wrong.
PS: I hope you get the idea, because I haven't compiled the above code and maybe I screwed up some parenthesis or made some other dumb mistake.