1

我有一些代表和一个方法:

delegate Point Translate(Point p);
delegate Translate Transform(Translate t);

Translate forward = p => new Point(p.X + 1, p.Y);

问题:如何实现这样的方法:

Transform Rotate90 = ??

这样就可以将Rotate90任何Translate函数顺时针旋转 90 度。所以:

Point startPoint = new Point(1, 1);
Point endPoint = (Rotate90(forward))(startPoint);
//desired output: Point(1, 0)

编辑 1: 我不会Translate一个一个地应用函数。我需要的是Translate在一个点上应用一些转换的函数(已经旋转或反射的函数)。

我需要什么:如何编写一个Rotate90which 如果我通过它(p=>new Point(p.X+1, p.y)),它会返回一个与(p=>new Point(p.X, p.Y-1)).

编辑2:一些例子:

Translate forward =         p => new Point(p.X + 1, p.Y);
Translate backward =        p => new Point(p.X - 1, p.Y);
Translate downward =        p => new Point(p.X, p.Y - 1);
Translate runningForward =  p => new Point(p.X + 5, p.Y);

Transform Rotate90Cw = ??

Point samplePoint = new Point(1, 1);

Point p1 = (Rotate90Cw(forward))(samplePoint);          //must be (1,0)
Point p2 = (Rotate90Cw(backward))(samplePoint);         //must be (1,2)
Point p3 = (Rotate90Cw(downward))(samplePoint);         //must be (0,1)
Point p4 = (Rotate90Cw(runningForward))(samplePoint);   //must be (1,-4)
Point p4 = (Rotate90Cw(Rotate90Cw(forward)))(samplePoint);   //must be (0,1)

我需要一个可以 Rotate90Cw应用于任何Translate函数并返回正确函数的Translate函数。所以应用在一个点上的效果和应用Rotate90Cw(forward)在一个点上的效果是一样downward的。等等...

我不会Rotate为每种情况创建一个单独的函数(例如 forwardRotated、downRotated 和...

4

2 回答 2

3

目前尚不清楚您是否真的需要两个代表。似乎您真的想要一个代表从Pointto的任意转换Point- 然后您可以组合转换。例如:

delegate Point Transform(Point input);

private static Transform Compose(Transform first, Transform second)
{
    return p => second(first(p));
}

Transform forward = p => new Point(p.X + 1, p.Y);
Transform rotate90 = p => new Point(p.Y, -p.X);
Transform forwardThenRotate = Compose(forward, rotate);

编辑:看起来你真正想要的是一个转换(进行转换),如下所示:

  • 将原始变换应用于 (0, 0)
  • 旋转结果
  • 将输入点翻译那么多

我们可以很容易地做到这一点:

Transform forward = p => new Point(p.X + 1, p.Y);
Transform rotate90 = p => new Point(-p.Y, p.X);
Point forwardRotatedPoint = rotate90(forward(new Point(0, 0));

Transform forwardRotated = p => new Point(forwardRotatedPoint.X + p.X,
                                          forwardRotatedPoint.Y + p.Y);

正如我在其他地方所说,你可能实际上想要一个Vector类型,它有XY组件......然后你可以有几个可组合的概念:

  • 从向量创建转换(点到点)
  • 旋转一个向量以创建另一个向量
  • 组合变换
于 2013-03-28T15:08:00.873 回答
0

我以这种方式解决它(已编辑):

Translate Rotate90Cw(Translate moveFunction)
{
    return Rotate(moveFunction, Math.PI / 2.0);
}

Translate Rotate(Translate moveFunction, double angle)
{
    Point tempPoint = moveFunction(new Point(0, 0));
    double sin = Math.Sin(angle);
    double cos = Math.Cos(angle);
    return p => new Point(p.X + tempPoint.X * cos + tempPoint.Y * sin,
                           p.Y - tempPoint.X * sin + tempPoint.Y * cos);
}

检查它是否工作:

Rotate90Cw(Rotate90Cw(runningForward))(new Point(1, 1)); //output: (-4,0.9999999)
Rotate90Cw(runningForward)(new Point(1, 1));             //output: (1,-4)
Rotate90Cw(backward)(new Point(1, 1));                   //output: (1,2)
Rotate90Cw(downward)(new Point(1, 1));                   //output: (0,1)
于 2013-03-29T08:12:14.110 回答