代码
# loaded 时计算地球公转的地球中心
// 使用向量法计算太阳相对于地球的中心
var point = this.GetRotateTransformCenterWithTranslatePoint();
// 使用 TranslatePoint 法计算太阳相对于地球的中心
var checkPoint = this.GetRotateTransformCenterWithVector();
Debug.Assert(Math.Abs(point.X - checkPoint.X) < 0.000001 && Math.Abs(point.Y - checkPoint.Y) < 0.000001, "point != checkPoint");
// 设置地球的旋转中心为太阳的中心
this.EarthRotateTransform.CenterX = point.X;
this.EarthRotateTransform.CenterY = point.Y;
// 使用 TranslatePoint 法获取旋转中心点,
// 因为要绕着太阳绕转,所以要获取太阳中心点相对于地球的坐标点即可
private Point GetRotateTransformCenterWithTranslatePoint()
{
var sun = this.SunRectangle;
var earth = this.EarthGrid;
var sunPoint = sun.TranslatePoint(new Point(sun.ActualWidth / 2, sun.ActualHeight / 2), earth);
return sunPoint;
}
// 使用向量法进行计算,
// 1. 以地球 0, 0 不坐标轴原点
// 2. 原点至地球中心为 AB
// 3. 地球中心至太阳中心为 BC
// 4. 向量 AB + BC = AC , 得到太阳原心
private Point GetRotateTransformCenterWithVector()
{
var sun = this.SunRectangle;
var earth = this.EarthGrid;
// 向量 AB
var a = new Vector(earth.ActualWidth / 2, earth.ActualHeight / 2);
// 太阳中心
var sunPoint = sun.TranslatePoint(new Point(sun.ActualWidth / 2, sun.ActualHeight / 2), earth);
// 向量 BC
var b = new Vector(sunPoint.X - earth.ActualWidth / 2, sunPoint.Y - earth.ActualHeight / 2);
// 向量AC
var c = a + b;
var point = new Point(c.X, c.Y);
return point;
}
XAML
<Grid>
<!-- 轨道 -->
<Ellipse
Width="380" Height="380"
HorizontalAlignment="Center" VerticalAlignment="Center"
Opacity=".1" Stroke="Blue" StrokeThickness="5" />
<!-- 公转用的地球, 里面包一个自转的地球 -->
<Grid
x:Name="EarthGrid"
Width="120" Height="120"
Margin="0,0,350,0">
<!-- 在动画中计算公转时的旋转角度,但是要在启动时计算旋转的中心为太阳 -->
<Grid.RenderTransform>
<RotateTransform x:Name="EarthRotateTransform" Angle="0" />
</Grid.RenderTransform>
<Grid.Triggers>
<!-- loaded 时进行公转 -->
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard TargetName="EarthGrid">
<DoubleAnimation
RepeatBehavior="Forever"
Storyboard.TargetProperty="RenderTransform.Angle" From="0" To="360" Duration="0:0:10" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<!-- 自转的地球 -->
<Rectangle
x:Name="EarthRectangle"
Width="90" Height="90"
RenderTransformOrigin=".5 .5">
<Rectangle.Triggers>
<!-- loaded 时启动旋转动画 -->
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="EarthRectangle">
<DoubleAnimation
RepeatBehavior="Forever"
Storyboard.TargetProperty="RenderTransform.Angle" From="0" To="360" Duration="0:0:15" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
<Rectangle.RenderTransform>
<!-- 用动画调整的旋转角度 -->
<RotateTransform Angle="0" />
</Rectangle.RenderTransform>
<Rectangle.Fill>
<ImageBrush ImageSource="/Resource/Images/earth.png" />
</Rectangle.Fill>
<Rectangle.Effect>
<DropShadowEffect Opacity=".3" ShadowDepth="5" />
</Rectangle.Effect>
</Rectangle>
</Grid>
<!-- 自转的太阳 -->
<Rectangle
x:Name="SunRectangle"
Width="100" Height="100"
RenderTransformOrigin=".5 .5">
<Rectangle.RenderTransform>
<!-- 用动画调整的旋转角度 -->
<RotateTransform Angle="0" />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<!-- loaded 时启动旋转动画 -->
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" Storyboard.TargetName="SunRectangle">
<DoubleAnimation
RepeatBehavior="Forever"
Storyboard.TargetProperty="RenderTransform.(RotateTransform.Angle)" From="0" To="360" Duration="0:0:30" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
<Rectangle.Fill>
<ImageBrush ImageSource="/Resource/Images/sunII.png" />
</Rectangle.Fill>
<Rectangle.Effect>
<DropShadowEffect Opacity=".5" ShadowDepth="3" />
</Rectangle.Effect>
</Rectangle>
<!-- 全局中心点 -->
<Ellipse
Width="15" Height="15"
HorizontalAlignment="Center" VerticalAlignment="Center"
Fill="Red" Opacity=".1" />
</Grid>