我有这个任务,我必须制作类似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.
}
}
答案 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
。