[英]Functions with other functions as input using delegates in C#
我有一些代表和方法:
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
函数)。
我需要什么:如何写一个Rotate90
,如果我通过它(p=>new Point(p.X+1, py))
它会返回一个效果与(p=>new Point(pX, pY-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和......
目前尚不清楚你真的想要两位代表。 看起来你真的想要一个代表从Point
到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);
编辑:看起来你真正想要的是一个变换(接受转换)沿着以下方向:
我们可以轻松地做到:
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
类型,它有X
和Y
组件......那么你可以有几个可组合的概念:
我这样解决(EDITED):
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.