Click here to Skip to main content
15,880,469 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
I have a small app I use to visualize a starmap of a few hundred local stars, currently I'm using XAML to "draw" UI elements based on database's tables and it works incredibly well. HOWEVER, I am thinking of doing it in 3D and I'm in need of some guidance. How could I implement something similar, yet 3D?

Image of app:
https://lh4.googleusercontent.com/-ysg7ALD_dSE/UcV6CPOUYTI/AAAAAAAAAPk/UT1WlqlsAAE/w1598-h866-no/StarMapApp01.png[^]

Relevant XAML code:
XML
<TabItem Header="Starmap" Name="tab_itm_starmap">
<Grid Name="grid_starmap">
    <Grid.LayoutTransform>
        <ScaleTransform CenterX="0" CenterY="0" ScaleX="{Binding ElementName=uiScaleSlider,Path=Value}" ScaleY="{Binding ElementName=uiScaleSlider,Path=Value}" />
    </Grid.LayoutTransform>
    <Canvas Background="Black" Panel.ZIndex="-1500" />
    <Canvas Name="gridPattern" VerticalAlignment="Center" HorizontalAlignment="Center" Background="Blue" Height="1px" Width="1px" Panel.ZIndex="-1499" Visibility="Visible">
        <Canvas Style="{StaticResource myCanvasStyle}" Name="lightyear_grid" Margin="0,0,0,-5.00000000000003" Width="2000" Height="2000" Canvas.Top="-1000" Canvas.Left="-1000" Panel.ZIndex="-1498"></Canvas>
        <Line X1="1" Y1="1" X2="1" Y2="2000" Stroke="White" StrokeThickness="1" Width="1" Canvas.Left="0" Canvas.Top="-1000" Panel.ZIndex="-900" />
        <Line X1="1" Y1="1" X2="2000" Y2="1" Stroke="White" StrokeThickness="1" Height="1" Canvas.Left="-1000" Canvas.Top="0" Panel.ZIndex="-900" />
        
    </Canvas>
    <Canvas  VerticalAlignment="Center" HorizontalAlignment="Center" Background="Blue" Height="1px" Width="1px" Panel.ZIndex="-1000">
        
    </Canvas>

    <!--Working specimens-->
    <!--HorizontalAlignment="Center" VerticalAlignment="Center" Width="0" Height="0" RenderTransform="1 0 0 -1 0 0"--> <!--Starfield canvas-->
    <Canvas Name="starfield" VerticalAlignment="Center" HorizontalAlignment="Center" Background="Blue" Height="1px" Width="1px" Panel.ZIndex="-900">
        
    </Canvas>
</Grid>


</TabItem>


Relevant C# code:
C#
//Funtion to add stars (ellipses) to the XAML canvas 'starfield', from the 'stars_db' database
public void AddStarsFromDB(object StarID, object HIP, object HD, object Gliese, object BayerFlamsteed, object ProperName, object Distance, object Spectrum, object ColorIndex, object X, object Y, object Z)
{
    //set up all information from DB as string variables, with explanatory names
    String StarID_str = StarID.ToString();
    String HIP_str = HIP.ToString();
    String HD_str = HD.ToString();
    String Gliese_str = Gliese.ToString();
    String BayerFlamsteed_str = BayerFlamsteed.ToString();
    String ProperName_str = ProperName.ToString();
    String Distance_str = Distance.ToString();
    String Spectrum_str = Spectrum.ToString();
    String ColorIndex_str = ColorIndex.ToString();
    String X_str = X.ToString();
    String Y_str = Y.ToString();
    String Z_str = Z.ToString();

    //converting X-coordinates to double then converting to light-years and multiplying by 10
    double X_ly = double.Parse(X_str);
    X_ly = X_ly * 3.26163344 * 10;

    //converting Y-coordinates to double then converting to light-years and multiplying by 10
    double Y_ly = double.Parse(Y_str);
    Y_ly = Y_ly * 3.26163344 * 10;

    //converting Z-coordinates to double then converting to light-years and multiplying by 10
    double Z_ly = double.Parse(Z_str);
    Z_ly = Z_ly * 3.26163344 * 10;
    
    //Get star classifications using dedicated function
    int StarType = DetermineStarType(Spectrum_str);

    //Ellipse size and color settings based on star type
    int HeightWidthValTmp = 0;
    String StarColorValTmp = null;
    int xIndexVal = 0;
    switch (StarType)
    {
        case 1:
            HeightWidthValTmp = 23;
            StarColorValTmp = "Blue";
            xIndexVal = 1;
            break;
        case 2:
            HeightWidthValTmp = 19;
            StarColorValTmp = "LightBlue";
            xIndexVal = 2;
            break;
        case 3:
            HeightWidthValTmp = 17;
            StarColorValTmp = "White";
            xIndexVal = 3;
            break;
        case 4:
            HeightWidthValTmp = 13;
            StarColorValTmp = "LightYellow";
            xIndexVal = 4;
            break;
        case 5:
            HeightWidthValTmp = 9;
            StarColorValTmp = "Yellow";
            xIndexVal = 5;
            break;
        case 6:
            HeightWidthValTmp = 7;
            StarColorValTmp = "Orange";
            xIndexVal = 6;
            break;
        case 7:
            HeightWidthValTmp = 5;
            StarColorValTmp = "Red";
            xIndexVal = 7;
            break;
        default:
            HeightWidthValTmp = 3;
            StarColorValTmp = "Green";
            xIndexVal = 8;
            break;
    }

    //declearing variables to make 
    int StarSizeHeightWidth = HeightWidthValTmp;
    string StarColorVal = StarColorValTmp;
    int CoordOffsetVal = StarSizeHeightWidth / 2 * -1;

    //Setting up a "tooltip" to give information on stars
    var StarInfo = new StackPanel();
    StarInfo.Children.Add(new TextBlock() { Text = "name: " + ProperName_str + ", " + BayerFlamsteed_str});
    StarInfo.Children.Add(new TextBlock() { Text = "Catalog no: " + Gliese_str + ", HD: " + HD_str });
    StarInfo.Children.Add(new TextBlock() { Text = "coordinates: " + X_ly / 10 + ";" + Y_ly / 10 + ";" + Z_ly / 10 + " ly" });
    StarInfo.Children.Add(new TextBlock() { Text = "Distance from sol: " + ParsecToLightYearConverter(double.Parse(Distance_str)) + "ly" });

    //creates a colorbrush from string
    BrushConverter conv = new BrushConverter();
    SolidColorBrush brush = conv.ConvertFromString(StarColorVal) as SolidColorBrush;

    //setting up and adding new star
    var star = new Ellipse
    {
        Height = StarSizeHeightWidth,
        Width = StarSizeHeightWidth,
        Fill = brush,
        RenderTransform = new TranslateTransform(CoordOffsetVal, CoordOffsetVal),
        ToolTip = StarInfo,
        Cursor = Cursors.Hand
    };
    star.SetValue(Canvas.LeftProperty, X_ly);   //left-right distance from center in pixles
    star.SetValue(Canvas.TopProperty, Y_ly);    //top-bottom distance from center in pixles
    star.SetValue(Canvas.ZIndexProperty, -400 + xIndexVal); //

    starfield.Children.Add(star);

}
Posted

1 solution

Use ModelVisual3D and place spheres instead of circles.

Generating a sphere-mesh in XAML[^]

You will also have to supply the Z coordinate for the sphere you use. You can then use a camera object to be able to move around in the 3D world:

3D Graphics in WPF[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900