C#Windows窗体 - 参数无缘无故变为零

时间:2014-07-26 13:30:53

标签: c# winforms

我有这个任务,我必须制作类似Paint的程序(但不使用任何内置方法进行形状绘制,形状变换等)。出于轮换目的,我实现了一种转换变换方法。问题是,当调用此方法时,由于某种未知原因,_center参数中的任何内容都会变为零(在使用断点进行调试期间找到)。任何人都有任何线索?

相关代码如下。

public static PPoint TranslatePointTo(PPoint target, PPoint _source, PPoint _center)
    {
        if (_source == null || target == null)
            throw new InvalidOperationException();

        if(_center == null)
        {
            return _source;
        }


        //... _center's X coordinate gets turned to zero for no reason at all.
        _source.X = _source.X + (target.X - _center.X);

        //... _center's Y coordinate gets turned to zero for no reason at all.
        _source.Y = _source.Y + (target.Y - _center.Y);
        return _source;
    }

其中PPoint是具有可直接编辑的X和Y坐标的点类。

class PPoint
{


    public int X { get; set; }
    public int Y { get; set; }

    /// <summary>
    /// Represents an empty point.
    /// </summary>
    public const PPoint Empty = null;

    /// <summary>
    /// Initializes an object of type PPoint.
    /// </summary>
    public PPoint(int x,int y)
    {
        X = x;
        Y = y;
    }

    public static PPoint operator +(PPoint p1, PPoint p2)
    {
        p1.X += p2.X;
        p1.Y += p2.Y;
        return p1;
    }

    /// <summary>
    /// Rotates a point by <paramref name="radians"/> and returns the resulting point.
    /// </summary>
    /// <param name="point">The point to rotate.</param>
    /// <param name="radians">The radians by which to rotate it.</param>
    /// <returns>The rotated point.</returns>
    public static PPoint RotatePoint(PPoint point, double radians)
    {
        //Performs rotation.
    }

    /// <summary>
    /// Performs a variant of Translation Transform.
    /// Translates the <paramref name="_source"/> to the target,
    /// then offsets the translated point by the distance of <paramref name="_source"/>
    /// and <paramref name="_center"/>.
    /// </summary>
    public static PPoint TranslatePointTo(PPoint target, PPoint _source, PPoint _center)
    {
        //Code for this method is above.
    }
}

我目前在我的Polygon课程中使用该代码进行翻译。

public override void RotateByDegrees(int degrees)
{
        //...
        PPoint polyCenter = Polygon.FindCenter(this);

        var prevPosition = this.Edges[0];

        for (int i = 0; i < this.Edges.Count; i++)
        {
            prevPosition = this.Edges[i];

            //The bug was found here (didn't need to test further).
            this.Edges[i] = PPoint.TranslatePointTo(PPoint.Origin, this.Edges[i], polyCenter);

            this.Edges[i] = PPoint.RotatePoint(this.Edges[i], Mathf.ToRadians(degrees));

            this.Edges[i] = PPoint.TranslatePointTo(prevPosition, this.Edges[i], polyCenter);
        }
        //...
}

多边形类定义。

    abstract class Polygon : Shape
{
    /// <summary>
    /// This array will always have 2 points that represent the midpoints between
    /// the first and last lines of the polygon.
    /// </summary>
    private PPoint[] midpoints;

    /// <summary>
    /// The inner point in PPoint form.
    /// </summary>
    public PPoint innerPoint { get; protected set; }

    /// <summary>
    /// The edge points of the polygon. (Is used in rotation)
    /// </summary>
    public List<PPoint> Edges { get; private set; }

    /// <summary>
    /// Creates a new instance of a drawable polygon.
    /// </summary>
    public Polygon(string shapeName, System.Drawing.Pen pen, Identifier id, bool isFilled) : base(shapeName,pen,id,isFilled)
    {
        innerPoint = PPoint.Empty;
        midpoints = new PPoint[2];
        Edges = new List<PPoint>();
    }


    /// <summary>
    /// In order to conserve space, this method adds all the points of a line
    /// to the polygon.
    /// The line is defined by its starting and ending point.
    /// </summary>
    public virtual void AddLine(PPoint start, PPoint end)
    {
        //Adds a line to the polygon. For drawing purposes.
    }

    //Shape.Points() does not do anything in the Polygon class.
    public override void Points()
    {

    }

    /// <summary>
    /// Utility function that performs a fast swap operation between
    /// two integers.
    /// </summary>
    private void fast_swap(ref int left, ref int right)
    {
        left = right - left;//x = y - x;
        right = right - left;//y = y - x (y=y+x-y=x)
        left = left + right;//x = x + y;(x=y-x+x=y)
    }


    /// <summary>
    /// Returns the inner pixel as the midpoint pixel between
    /// the midpoints stored during the Polygon object's creation.
    /// </summary>
    /// <returns>An pixel inside the shape.</returns>
    public override Pixel FindInnerPixel()
    {
        //...CODE...
    }

    /// <summary>
    /// Calculates the area of the target polygon.
    /// </summary>
    public static int Area(Polygon _p)
    {
        //...Irrelevant Code...
    }

    /// <summary>
    /// Finds the center point of a polygon.
    /// </summary>
    public static PPoint FindCenter(Polygon _p)
    {
        //Finds the center of the polygon.
    }


    public override void RotateByDegrees(int degrees)
    {
        //Performs rotation by the given degrees.
    }
}

2 个答案:

答案 0 :(得分:2)

    _source.X = _source.X + (target.X - _center.X);

这是您代码中相当讨厌的错误。它可能存在于代码中的多个位置,导致您描述的问题。

问题是它修改 _source对象。没有人预计会发生这种情况,你可能也不会。该方法应该这样写:

public static PPoint TranslatePointTo(PPoint target, PPoint _source, PPoint _center)
{
    return new PPoint(
       _source.X + (target.X - _center.X),
       _source.Y + (target.Y - _center.Y));
}

或者你应该使PPoint类不可变,这样你就不会犯这个错误,从X和Y属性中删除setter。或者你应该将PPoint声明为 struct 而不是类,这样它就像一个值而不是一个对象,与.NET Point类型进行比较。

答案 1 :(得分:0)

我不能告诉你为什么这些值是0,但是,在我看来,你的解决方案会遇到一些设计问题,如果你纠正它们,可能你的问题会得到解决并自动解决#34;

首先,最重要的是 a&#34; point&#34;应始终表示为不可变结构。它代表一个原子对象,就像一个数字一样,唯一的区别在于维度。例如,如果您使用点进行平移,旋转或执行任何操作,结果将是另一个,即平面中的新点,而不是具有不同坐标的相同实例。一个点不能走路&#34;在飞机上。

其次,这段代码定义了&#34;空&#34;成员为null完全没有意义。如果你考虑到我之前的话,坚持设计点是一个类而不是一个结构,那么一个未定义的点将始终为null,不需要为它引入别名。但是,我猜你要存储原点(0,0),在这种情况下你应该实例化它,使它static readonly而不是const