Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A better solution would be to use one or more System.Windows.Media.Geometry object to store your paths, points etc.</p> <p>This geometry can be drawn with a Pen, so you could indeed change the stroke thickness when you zoom, but more flexible is to use the Transform property.</p> <p>Using the transform, you can "zoom" the actual coordinates of the geometric representation and not the visualization - so when you draw it, you don't need to fiddle with render transforms.</p> <p>To compute the transform, I use the following code like:</p> <pre><code>public static Matrix TransformShape(Rect fromPosition, Rect toPosition, bool flipVertical) { Matrix translateThenScale = Matrix.Identity; //we first translate to origin since that's just easier translateThenScale.Translate(-fromPosition.X, -fromPosition.Y); //now we scale the graph to the appropriate dimensions translateThenScale.Scale(toPosition.Width / fromPosition.Width, toPosition.Height / fromPosition.Height); //then we flip the graph vertically around the viewport middle since in our graph positive is up, not down. if (flipVertical) translateThenScale.ScaleAt(1.0, -1.0, 0.0, toPosition.Height / 2.0); //now we push the graph to the right spot, which will usually simply be 0,0. translateThenScale.Translate(toPosition.X, toPosition.Y); return translateThenScale; } </code></pre> <p>where the fromPosition Rect should contain the untransformed bounds, and the toPosition Rect should contain the transformed bounds. This also trivially allows for scaling X and Y separately, which is often necessary for plotting.</p> <p>It's easy to compute the bounds of your geometry:</p> <pre><code>Geometry graphGeom; //[...] //the bounds are modified by the transform, so we want no transform! graphGeom.Transform = Transform.Identity; Rect graphBounds = graphGeom.Bounds; //then set the transform again //or, if the transform is axis-aligned, the following _should_ work: Rect graphBoundsAlt = graphGeom.Transform.Inverse.TransformBounds(graphGeom.Bounds); </code></pre> <p>And of course WPF can tell you which bounds you need to render into, should that be necessary. Putting it together, you could do something like</p> <pre><code>public void RecomputeTransform(Rect targetRect, bool flipVertical) { graphGeom.Transform = Transform.Identity; Rect graphBounds = graphGeom.Bounds; Matrix transMat = TransformShape(graphBounds,targetRect,flipVertical); graphGeom.Transform = new MatrixTransform(transMat); } </code></pre> <p>The advantage of using this solution is that you don't need to mess with RenderTransforms, you're free to use transforms that shear and/or scale X and Y independently without getting weird distortions in your lines, and you can treat the Pen as an opaque object (i.e. easier to customize from the UI - if you select Pen width or whatnot, no further correction is necessary).</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COI would assume that using this solution would require the parts of the drawing that you do not wish to scale to be separate from the main canvas which may scale. Example would be a vector drawing application where the drawing itself scales but the anchor point visuals and such scale positionally but not as far as their thickness and such. Am I correct in this assumption?
      singulars
    2. COI'm sorry, I don't *quite* understand your question... Indeed this is something you'd do in a vector drawing scenario where you care about a idealized lines or points and not about their thickness. This approach will scale (or otherwise linearly transform) a line drawing without transforming the line widths. I.e., you're transforming the idealized geometry and only *then* converting that into the "real" shape which of course has lines of non-zero width. If you were to transform the `Drawing`, you'd be transforming details such as line withs and line joins etc. too. Does that clarify it?
      singulars
    3. COI think so, My assumption was that the drawing application would have some parts that scale everything such as drawings and some parts which are more like decorators that don't scale in terms of thickness but are still positioned relative to scaled drawing. Such as vector drawing applications like Inkscape where the drawing lines are scaled in terms of thickness but anchor points that are shown for the selected object are not scaled in the same manner. So my assumption is to accomplish this in .NET you would still need to have these parts in two disjoint panels that are scaled independently.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload