Calculate the X and Y (top and left) values for the shape after setting the rotation for it - openxml

Need help in adjusting the top and left of the shape when rotation value is set.
For Ex :
<p:spPr bwMode="auto">
<a:xfrm rot="5400000">
<a:off x="2443049" y="-1042472" />
<a:ext cx="304800" cy="4419600" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
<a:ln>
<a:headEnd />
<a:tailEnd />
</a:ln>
I have the above data. I have calculated the rotation angle accordingly. Now when creating the shape and displaying it in an html format, need to adjust the top and left (off x="2443049" y="-1042472") values to align it properly. Kindly provide a solution to calculate proper top and left values to set.
thanks

As mentioned in how to calculate the rotation value for the MS Office Powerpoint Shapes from the xml data given, their is no need to change the left and top of a shape - if it is rotated or not-rotated, the shape will have the same left/top as it is an in-place rotation (it rotates on the Center X/Y).
If you're looking for how to translate EMU to points/pixels so that it can be converted to a different format such as HTML, use EMU/12700. So in this case <a:off x="2443049" y="-1042472" /> would be left="192.37" top="-82.08" and <a:ext cx="304800" cy="4419600" /> would be width=24 height=348.

Related

Increase the BBOX size but keep the ratio (Lon/Lat)

I have a Bbox that is defined by the following values:
xmin: 11.555333537980914
ymin: 47.76067947037518
xmax: 11.995692579075694
ymax: 48.281587762758136
I would like to increase the size of this Bbox but keep the ratio.
One approach I tried is to calculate the middle point of the Bbox and calculate a new Bbox with the value of radius increased by 50%.
The problem: the ratio gets lost.
How could I increase the size of Bbox to 50% but keep the ratio.
Perhaps ST_Expand is what you're looking for. You could first calculate the area of the input bbox using ST_Area and then use the output as a unit to expand the bbox.
SELECT -- here you can play with different sizes
ST_Expand(geom, ST_Area(geom)/2)
FROM yourtable;
Example:
WITH j (geom) AS (
SELECT ST_MakeEnvelope(11.555333537980914,
47.76067947037518,
11.995692579075694,
48.281587762758136,4326)
)
SELECT
ST_Expand(geom,ST_Area(geom)/2)
FROM j;
The image below represents the result set. The inner bbox is the one you provided and the outer one was created with ST_Expand.
Demo: db<>fiddle
The answer provided by #Jim Jones works perfectly. Is there something PostGIS can not do? :)
I did not wanted to be dependend on PostGIS
so I tried to solve the problem with R. My approach:
I prolong each diagonal of the bbox and calculate the bearing for that diagonal. Based on that data I calculate new edge points of the bbox. It kind of works but the left side of the bbox looks a bit small. I think there is a misstake somwhere but i dont know yet where.
xmin<- 11.555333537980914
ymin<- 47.76067947037518
xmax<- 11.995692579075694
ymax<- 48.281587762758136
###calculate bearing clockwise of diagonal for each corner of the BBOX
######## right bottom, left und top
######## left and bottom, right and top
######## left and top and right and bottom
######## right and top, left and bottom
##bearing(p1, p2, a=6378137, f=1/298.257223563)
bearing1 <- geosphere::bearingRhumb(c(xmax,ymin),c(xmin,ymax))
bearing2 <- geosphere::bearingRhumb(c(xmin,ymin),c(xmax,ymax))
bearing3 <- geosphere::bearingRhumb(c(xmin,ymin),c(xmax,ymin))
bearing4 <- geosphere::bearingRhumb(c(xmax,ymax),c(xmin,ymin))
#new bbox points
########################## left und top
########################## right und top
########################## right und bottom
########################## left und bottom
p1<- geosphere::destPointRhumb(c(xmin,ymax), bearing1, 10000, r = 6378137)
p2<- geosphere::destPointRhumb(c(xmax,ymax), bearing2, 10000, r = 6378137)
p3<- geosphere::destPointRhumb(c(xmax,ymin), bearing3, 10000, r = 6378137)
p4<- geosphere::destPointRhumb(c(xmin,ymin), bearing4, 10000, r = 6378137)
data<-rbind.data.frame(p1,p2,p3,p4)
xmin<-min(data$lon)
ymin<-min(data$lat)
xmax<-max(data$lon)
ymax<-max(data$lat)
cat(xmin,",",ymin,",",xmax,",",ymax)
One solution would be to translate the box so that its center is at the origin, multiply everything with 1.5, and then translate back. This should be possible with a single ST_Affine(), but I'm too lazy to work out the details. :)

Loop to change block position

I have a Matlab script that creates a Model Block for each element i found in a text file.
The problem is that all Models are created on each other in the window. So i'm trying to make a loop like:
for each element in text file
I add a Model block
I place right to the previous one
end
So it can look like this:
As you can see on the left, all models are on each other and I would like to place them like the one on the right.
I tried this:
m = mdlrefCountBlocks(diagrammeName)+500;
add_block('simulink/Ports & Subsystems/Model',[diagrammeName '/' component_NameValue]);
set_param(sprintf('%s/%s',diagrammeName,component_NameValue), 'ModelFile',component_NameValue);
size_blk = get_param(sprintf('%s/%s',diagrammeName,component_NameValue),'Position');
X = size_blk(1,1);
Y = size_blk(1,2);
Width = size_blk(1,3);
Height = size_blk(1,4);
set_param(sprintf('%s/%s',diagrammeName,component_NameValue),'Position',[X+m Y X+Width Y+Height]);
Inside the loop but it returns an error Invalid definition of rectangle. Width and height should be positive.
Thanks for helping!
The position property of a block does actually not contain its width and height, but the positions of the corners on the canvas (see Common Block Properties):
vector of coordinates, in pixels: [left top right bottom]
The origin is the upper-left corner of the Simulink Editor canvas before any canvas resizing. Supported coordinates are between -1073740824 and 1073740823, inclusive. Positive values are to the right of and down from the origin. Negative values are to the left of and up from the origin.
So change your code to e.g.:
size_blk = get_param(sprintf('%s/%s',diagrammeName,component_NameValue),'Position');
set_param(sprintf('%s/%s',diagrammeName,component_NameValue),'Position', size_blk + [m 0 0 0]);

Change transform rotation from X to Z axis

I have a transform which is being rotated around the X axis. But while transferring this rotation to another transform, i want it to do the exact same rotation. But then around the Z axis.
However, this rotation is not a "rotation" it is just a transform which rotation gets edited from the outside. So i have to rotate the original transform to match the 2nd transform, but take the rotation into account.
Axis in below images: RED = X, GREEN = Y, BLUE = Z
Rotation original:
Rotation it should have after:
What would be the correct way to go about this frame by frame?
Thanks in advance,
Smiley
I can give you an answer that solves the general problem of changing the rotation from one axis to another.
Each transform object has a transform.localRotation property that represents the orientation of the transform, relative to the parent's orientation. If the transform has no parent, than this orientation is relative to World Space.
Quaternion is the data type used to represent rotations, and it has a useful method called ToAngleAxis.
float angle;
Vector3 axis;
transform.localRotation.ToAngleAxis(out angle, out axis);
Will set the variables angle and axis to the angle and axis of localRotation. The out part means that you're passing in a variable meant to be set by the function, rather than to be used as input.
In this case, the angle variable is the part you want to actually use. If you use Quaternion.AngleAxis, providing this angle value and your desired axis, you'll get a new rotation that will match your desired parameters.
For example: To change any rotation of transform1 to a Z-axis rotation on transform2, you would use
float angle;
float axis;
transform1.localRotation.ToAngleAxis(out angle, out axis);
transform2.localRotation = Quaternion.AngleAxis(angle, Vector3.forward);
Hope this helps

how to calculate the rotation value for the MS Office Powerpoint Shapes from the xml data given

I want to get the proper rotation value to draw the shape of the MS office Powerpoint 2007 file from the given OOXML data as below :
<p:sp>
<p:nvSpPr>
<p:cNvPr id="3" name="Rectangle 66" />
<p:cNvSpPr>
<a:spLocks noChangeArrowheads="1" />
</p:cNvSpPr>
<p:nvPr />
</p:nvSpPr>
<p:spPr bwMode="auto">
***<a:xfrm rot="5400000">***
<a:off x="2443049" y="-1042472" />
<a:ext cx="304800" cy="4419600" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
<a:ln>
<a:headEnd />
<a:tailEnd />
</a:ln>
</p:spPr>
The value of rotation is given as "xfrm rot = 5400000". Considering this, its proper value has to be calculated and accordingly the height and width of the shape has to handled to draw the shape.
Divide it by 60000 to get the rotation angle. In this case, 5400000/60000=90 degrees. It is an in-place rotation, meaning it rotates on Center X and Center Y.

CGAffineTransform help, flipping a label

I basically have a pie chart where I have lines coming out of each segment of the pie chart. So in the case where the line comes out of the circle to the left, when I draw my text, it is reversed. "100%" would look like => "%001" (Note, the 1 and % sign are actually drawn in reverse to, like if a mirror. So the little overhang on top of the 1 points to the right, rather than the left.)
I tried reading through Apple's docs for the AffineTransform, but it doesn't make complete sense to me. I tried making this transformation matrix to start:
CGAffineTransform transform1 = CGAffineTransformMake(-1, 0, 0, 1, 0, 0);
This does flip the text around its x-axis so the text now looks correct on the left side of the circle. However, the text is now on the line, rather than at the end of the line like it originally was. So I thought I could translate it by moving the text in the x-axis direction by changing the tx value in the matrix. So instead of using the above matrix, I used this:
CGAffineTransform transform1 = CGAffineTransformMake(-1, 0, 0, 1, -strlen(t1AsChar), 0);
However, the text just stays where it's at. What am I doing wrong? Thanks.
strlen() doesn't give you the size of the rendered text box, it just gives you the length of the string itself (how many characters that string has). If you're using a UITextField you can use textField.frame.size.width instead.