Click here to Skip to main content
15,916,951 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I draw a polygon line with 100 points, the startPoint is (10.000001, 10.000001), the offset = 0.000001, the next point is plus the offset (10.000002, 10.000002), then I zoom the line to 1e6 times or more by matrixTransform, but I saw the the line is not a beeline, is a sawtooth line.
Why does it not work? Do you have any solution for this issue?

MoreInfo:
I draw the line in a coordinate system (x axis & y axis, like x axis range is the point.x's range, 10.000001~10.0001), and the points are the real data. I want to just draw it by the real points and by the matrixTransform to show the real line I needed.
A strange problem is, I transform the points by matrixTransform, and draw the line is not missing the precision. there is a simple demo for it.

Here is my code:
Xaml:
C#
<Window x:Class="TestMatrix.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="700">
    <Grid x:Name="grid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>
        <Canvas Background="Blue" x:Name="canvas" Width="300" Height="500" Margin="25">
            <Path Stroke="Red" x:Name="path">
                <Path.Data>
                    <PathGeometry x:Name="geometry">
                        <PathGeometry.Figures>
                            <PathFigure x:Name="pathFigure" >
                                <PathFigure.Segments>
                                    <PolyLineSegment x:Name="polyLineSegment" ></PolyLineSegment>
                                </PathFigure.Segments>
                            </PathFigure>
                        </PathGeometry.Figures>
                    </PathGeometry>
                </Path.Data>
            </Path>
        </Canvas>
        <Canvas x:Name="noMatrixCanvas" Grid.Column="1" Width="300" Height="500" Background="LightBlue">
            <Path Stroke="Red">
                <Path.Data>
                    <PathGeometry x:Name="geometryNo">
                        <PathGeometry.Figures>
                            <PathFigure x:Name="pathFigureNo" >
                                <PathFigure.Segments>
                                    <PolyLineSegment x:Name="polyLineSegmentNo" ></PolyLineSegment>
                                </PathFigure.Segments>
                            </PathFigure>
                        </PathGeometry.Figures>
                    </PathGeometry>
                </Path.Data>
            </Path>
        </Canvas>
    </Grid>
</Window>


CS:
C#
private List<Point> m_listPoints = new List<Point>();
private int count = 100;
private double c_offset = 1e-7;
private MatrixTransform m_transform;
public MainWindow()
{
    InitializeComponent();
    InitPoints(count);
    DrawWithMatrix();
    DrawNoMatrixTransform();
}

private void DrawWithMatrix()
{
    pathFigure.StartPoint = m_listPoints[0];
    PolyLineSegment poly = new PolyLineSegment(m_listPoints, true);
    polyLineSegment.Points = poly.Points;

    m_transform = new MatrixTransform();
    m_transform.Matrix = GetMatrix(canvas, count);
    geometry.Transform = m_transform;
}

private void InitPoints(int count)
{
    double xValue = 4.989826;
    double yValue = 9.012345;
    for (int i = 0; i < count; i++)
    {
        m_listPoints.Add(new Point(xValue + i * c_offset, yValue + i * c_offset));
    }
}
private Matrix GetMatrix(FrameworkElement fe, int count)
{
    double scaleX = fe.Width / (count * c_offset);
    double scaleY = fe.Height / (count * c_offset);

    Matrix matrix = new Matrix();

    matrix.Translate(-m_listPoints[0].X, -m_listPoints[count - 1].Y);
    matrix.Scale(scaleX, -scaleY);

    return matrix;
}
private void DrawNoMatrixTransform()
{
    var realPoints = GetRealPoints();
    pathFigureNo.StartPoint = realPoints[0];
    PolyLineSegment poly = new PolyLineSegment(realPoints, true);
    polyLineSegmentNo.Points = poly.Points;
}

private List<Point> GetRealPoints()
{
    List<Point> pixelPoints = new List<Point>();
    m_listPoints.ForEach(point =>
    {
        //get realPoint by compute
        //double x = (point.X - m_listPoints[0].X) * noMatrixCanvas.Width / (count * c_offset);
        //double y = -(point.Y - m_listPoints[count - 1].Y) * noMatrixCanvas.Height / (count * c_offset);
        //pixelPoints.Add(new Point(x, y));

        //get realPoint by matrix
        Point realPoint = m_transform.Transform(point);
        pixelPoints.Add(realPoint);
    }
    );
    return pixelPoints;
}


Thanks
Weiqiang
Posted
Updated 20-Nov-12 23:33pm
v6
Comments
Sergey Alexandrovich Kryukov 20-Nov-12 14:22pm    
It is possibly that this is precision, right. The solution is usually possible, but needs a lot more detail. And the solution is very likely lies in the application architecture, not implementation detail. You need to explain your purpose, and the purpose of zoom and other related behaiors...
--SA
songwq 21-Nov-12 0:19am    
Thank you for your reply. And I add more info, please pay attention to it.
earloc 21-Nov-12 2:54am    
your sample is missing definition of
field "m_transform" and method "GetMatrix"
songwq 21-Nov-12 5:35am    
I had updated the code. Thank you for your reminder. :)
songwq 23-Nov-12 23:37pm    
Is there any solution for this issue?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900