wpf 地球旋转(向量计算)

代码

# 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>
上一篇
下一篇