In XAML, the ProjectionPlane is used pivot an element on a three-dimensional axis. For example if I wanted to tilt the right edge of a rectangle toward me, I do this:
<!-- zero rotation -->
<Rectangle Fill="White" Height="200" Width="200">
<Rectangle.Projection>
<PlaneProjection RotationY="0" />
</Rectangle.Projection>
</Rectangle>
<!-- 45 deg rotation -->
<Rectangle Fill="White" Height="200" Width="200">
<Rectangle.Projection>
<PlaneProjection RotationY="45" />
</Rectangle.Projection>
</Rectangle>
<!-- 85 deg rotation -->
<Rectangle Fill="White" Height="200" Width="200">
<Rectangle.Projection>
<PlaneProjection RotationY="85" />
</Rectangle.Projection>
</Rectangle>
The resulting rectangle(s) would look like this:
So far so good. Here's my problem. As the angle increases closer to 90 degrees, the rectangle is skewed more and more. Is there a property or technique that could allow the ProjectionPlane to rotate along the Y axis all the way to 90 degrees but reduce the scewing (or change the field of view)?
In other words, the angle from the back corners to the from corners would be decreased and as a result if the rectangle had content in it, it would be more discernible.
Here's a before and after to make the question as clear as possible. On the left is what I get. On the right is what I want. It is slightly exaggerated to make the point. I hope this makes sense.
Unfortunately PlaneProjection doesn't allow you change projection matrix. To get control over projection you would have to go with Matrix3DProjection. You can use sample code provided in the documentation or you could look into porting Matrix3DEx library to WinRT.
One more thing you can try is to push your object back along Z axis and scale it up so it keeps it size. Since object would be further away from the camera it would show less distortion on flip.
BTW Accordingly to Jaime Rodriguez fov for PlaneProjection is set to 57 degrees, a bit wide for most displays.
Related
Consider the following SVG:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 40 20">
<g shape-rendering="crispEdges">
<rect x="0" y="0" width="20" height="20" fill="#b4b4b4"/>
<rect x="20" y="0" width="20" height="20" fill="#b4c4b4"/>
</g>
</svg>
The intended effect of the shape-rendering="crispEdges" annotation is to prevent there being a visible seam between the two rectangles, no matter how the rendering is scaled. This works as intended when viewing the SVG file in both Firefox and Chromium. However, when I convert the SVG into a PDF using inkscape -A and view the PDF, I can still see a visible seam at some zoom levels, e.g. as in this screen shot:
Moreover, the PDF page stream produced by inkscape is identical with and without shape-rendering="crispEdges"
1 0 0 -1 0 15 cm
q
0.705882 0.705882 0.705882 rg /a0 gs
0 0 15 15 re f
0.705882 0.768627 0.705882 rg 15 0 15 15 re f
Q
and the /ExtGState dictionary referenced as /a0 is also identical:
/ExtGState <<
/a0 <<
/CA 1
/ca 1
>>
>>
This could mean that there is no equivalent in PDF of this SVG feature, or it could mean that Inkscape's PDF exporter doesn't implement the equivalent. I'm not having any luck finding anything that sounds like this SVG feature in the PDF specification, which is an argument in favor of "no equivalent", but the PDF spec is gigantic and I could easily have missed something.
So the question is: Is or isn't there an equivalent in PDF of this SVG feature, and if there is, how do I use it? I am prepared to edit my exported PDF by hand if I have to.
Note 1: The example is minimal; I originally noticed the problem with a much more complicated figure from an academic paper, in which there are many such rectangles aligned to a grid, but some grid positions are empty. I tried enlarging the rectangles in the original figure so they would overlap, and I was not able to find an amount of enlargement that eliminated all visible seams without also visibly causing the rectangles to bleed into the empty spaces.
Note 2: With the original figure, the problem is visible with Evince, pdf.js, and two printers manufactured by different companies.
The closest thing in PDF would be to use shading meshes (e.g. tensor and lattice free form meshes). This will remove the slivers in most viewers.
Some PDF viewers ( like Acrobat, Xodo/PDFTron) have options that minimize the appearance of these slivers, but generally it's not well implemented across many implementations.
I've got this ContentPage:
<ContentPage.Content>
<Grid>
<Image
Source="background.png"
Aspect="AspectFill"
/>
<Image
Source="logo.png"
VerticalOptions="Center"
HorizontalOptions="Center"
/>
</Grid>
</ContentPage.Content>
But logo.png (while vertically and horizontally entered), stretches to take up the entire width of the screen.
How do I stop it from stretching and just maintaining its original size?
And yes, XAML solution definitely preferred.
Edit 1 (based on Paul Kertscher's answer):
If I set the Image source to a URL (e.g. https://via.placeholder.com/450x300.png?text=Computer+Says+No), I get the expected result, i.e the image does not stretch. However, if I save this same image to the specific platform directory (say Resources/ComputerSaysNo.png for iOS), it stretches to take up the entire screen width.
Tested on iPhone 7 simulator.
Edit 2
If I make #2x and #3x copies of my logo.png in the iOS Resources directory, and have all three images the same size, it works differently; the logo does not stretch to take up the entire width of the page.
From the documentation about AspectFill
Scale the image to fill the view. Some parts may be clipped in order to fill the view.
You should use AspectFit instead, it does not stretch the image to fill the control, but to fit the whole image in the control:
Scale the image to fit the view. Some parts may be left empty (letter boxing).
EDIT
I've tried the following
<Grid>
<Image HorizontalOptions="Center"
VerticalOptions="Center"
Source="http://lorempixel.com/output/abstract-q-c-200-200-6.jpg" />
</Grid>
and it yielded the following layout:
Hence it looks like what I've proposed is right - at least principally. I'd guess your image is simply too large.
Anyway, if you want to keep that image or would like to have more control over how the image is displayed, you could opt to either one of the following options.
Use the grid system to determine the size of the image
Within the Grid you can define columns and rows. Columns (and rows respectively) defined with the width (height) of * will take all the available space. If there are multiple columns or rows with * size, they will devide the remaining space equally. Furthermore you can give the * columns and rows weights. Ar column with the width 2* will have twice the width of one with the width *. Hence you could define columns with width 3*, *, and 3* and place your image in the second column (column index 1) for the image to take 1/7th of the screen width.
Use an AbsoluteLayout
Within an AbsoluteLayout you can define positions and sizes of child elements. Instead of positioning the images in a Grid, you could do the following
<AbsoluteLayout>
<Image AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1" /> <!-- Background -->
<Image AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds=".5,.5,.2,.2" /> <!-- Logo with 20% width/height -->
</AbsoluteLayout>
If you preferred setting the size of the image absolutely, you can do the following
<Image AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds=".5,.5,150,150" />
Another option which I use quite often is AbsoluteLayout. Combining PositionProportional (LayoutFlags) with LayoutBounds="0.5,0.5,-1,-1 (X, Y, Width, Height) will put image in the center of the screen. The LayoutBounds "0.5" means it will be in the center of X and Y, and "-1" will help to ignore the width and height.
Make sure to set VerticalOptions to in your AbsoluteLayout.
Here is the code:
<AbsoluteLayout VerticalOptions="FillAndExpand">
<StackLayout AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1" AbsoluteLayout.LayoutFlags="PositionProportional">
<Image Source="http://lorempixel.com/output/abstract-q-c-200-200-6.jpg" />
</StackLayout>
</AbsoluteLayout>
I hope it helps.
I'm working on a Win8 editor which is basically based on a Canvas and Shapes like Line, Rectangle, etc. on it. Those shapes can be manipulated by the user. Now I want to implement a custom shape that take a list of 2D points from a laser scan (used in architecture).
So my question is, which base primitive would you use to display lets say 500 points? I was thinking of a Path but then I get rather a set of connected lines (path, polygone) instead of just the dots. So what else?
This picture illustrates what I want to achieve. All blue dots should be in one shape that can be dragged by the user.
My first guess would be the PathGeometry filled with a lot of RectangleGeometries or EllipseGeometries. But I wonder what this means in terms of performance.
<Path Fill="LemonChiffon" Stroke="Black" StrokeThickness="1">
<Path.Data>
<RectangleGeometry Rect="50,50,5,5" />
<RectangleGeometry Rect="60,50,5,5" />
<RectangleGeometry Rect="70,50,5,5" />
...
</Path.Data>
</Path>
I'm trying to create a poker chip like the one here: http://www.casinowholesalers.com/shop/product_info.php?cPath=57&products_id=379 using Expression Blend 4 for a WP7.1 Silverlight 4 app.
I'm trying to create the six white "boxes" on the edge of the chip (ignoring for now the dice images and inner dashed line). The way I did it was two create two ellipses, one with no stroke, the other is the exact same size but with a stroke of 24, a color of White, and the StrokeDashArray to 1.8 (that's not "1 8", it's actually 1.8 with no second value). It looks pretty close to evenly sized and spaced (but not quite); I found it by trial and error. The XAML is below.
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Ellipse Fill="#FFC83838" Margin="112,253,128,275" Grid.Row="1" Stroke="#FFC83838" StrokeThickness="3"/>
<Ellipse Fill="#FFC83838" Margin="112,253,128,275" Grid.Row="1" Stroke="White" StrokeThickness="30" StrokeDashArray="1.79" StrokeDashOffset="6" RenderTransformOrigin="0.5,0.5"/>
</Grid>
I guess I have two questions:
Is there a better way to create this shape besides using two ellipses?
How can I mathematically determine what the StrokeDashArray value should be so the dashes are evenly spaced and sized instead of using trial and error?
I'll start from the second point.
First, the inner logic of StrokeDashArray is explained here. The important point is that the stroke dash array is not expressed in pixels, it's dependent upon stroke thickness to get the final pixel value for each number in the array.
So, for the math part, lets define some variables:
S - visible portion of the stroke (same as in the link).
G - the non-visible portion of the stroke (same as in the link).
r - the radius of your chip. It will be half of the actual width or half of the actual height.
n - the number of repetitions of S+G that you want. Integer.
T - stroke thickness
p - the mathematical pi (3.14...)
So we have:
2*p*r = n*(T*S+T*G)
Or,
S+G = 2pr/nT
In your case, and what I see from the image of the chip, the visible part of the stroke is square so S=1, there are six white squares with six gaps so n=6 and you decided for thickness of 30px so T=30. This gives you the value of G as:
G = 2pr/180 - 1
You can get the value of r from blend, the actual width and height will be written in parenthesis in the Width and Height boxes - divide it by two. From the details that you provided, I guess the radius is 102.55. And the final stroke dash array is:
StrokeDashArray="1,2.58"
For your first point, the answer is: it depends. If your chip is the same throughout the life-time of the application - this is the best way. It gives you the slight curvature on the outside to make the "square" flush with the outer contour of the chip and it requires a one-time calculation in design time.
Even if you have different sizes for the chip, this might be the best way to implement the graphics for the chip. Provided, you can design it with fixed size and then sticking it into a ViewBox and it still looks good.
If there's a need for variable sizes and the view box route doesn't work - there's another way to implement it (because Silverlight fails when you bind to ActualWidth\ActualHeight properties) - with Borders that hold rectangles. But it opens a whole new can of worms, and this answer is long enough. :)
How can I make a rounded corner triangle in XAML-Silverlight?
I think the below Path will solve your problem, Only you need to change the points of your triangle according to your requirement. For more idea about Path
<Path Data="M 300 100 L 500 400 100 400 Z"
StrokeThickness="48"
StrokeLineJoin="Round"
Stroke="Blue"
Fill="Blue" />