星を表示する（４）　データを変換する

[前回](https://qiita.com/ELIXIR/items/af92c2995f5c44cd95b7)使用した[データ](http://astronomy.webcrow.jp/hip/)は、色や視差の情報が一部の星で足りていないので、[こちら](https://heasarc.gsfc.nasa.gov/cgi-bin/W3Browse/w3query.pl?&tablehead=name%3Dheasarc_hipparcos%26description%3DHipparcos+Main+Catalog%26url%3Dhttp%3A%2F%2Fheasarc.gsfc.nasa.gov%2FW3Browse%2Fstar-catalog%2Fhipparcos.html%26archive%3D%26radius%3D1%26mission%3DSTAR%2BCATALOG%26priority%3D3&mission=STAR+CATALOG&Action=More+Options&Action=Parameter+Search&ConeAdd=1)のサイトから元データを取得してみます

![スクリーンショット 2018-02-25 2.38.00.png](https://qiita-image-store.s3.amazonaws.com/0/59911/c435035e-e372-0def-3ea4-9569f5f51e18.png)

ra,dec,parallax,vmag,bv_color

にチェックをつけ、データをダウンロードします。

![スクリーンショット 2018-02-27 14.12.23.png](https://qiita-image-store.s3.amazonaws.com/0/59911/9dc7ab36-8810-269b-03bc-d3bf53d0900f.png)

Output FormatにCSVはないようなので、PureTextでダウンロードしました
ダウンロードデータ数の上限はNo Limitにします。

```
Results from heasarc_hipparcos: Hipparcos Main Catalog
Coordinate system:  Equatorial
|ra           |dec          |parallax|hip_number|vmag |bv_color|
|00 00 00.2188|+01 05 20.448|    3.54|         1| 9.10|   0.482|
|00 00 00.9114|-19 29 55.815|   21.90|         2| 9.27|   0.999|
|00 00 01.2019|+38 51 33.430|    2.81|         3| 6.61|  -0.019|
|00 00 02.0116|-51 53 36.766|    7.75|         4| 8.06|   0.370|
|00 00 02.3917|-40 35 28.408|    2.87|         5| 8.55|   0.902|
|00 00 04.3539|+03 56 47.360|   18.80|         6|12.31|   1.336|
|00 00 05.4117|+20 02 11.768|   17.74|         7| 9.64|   0.740|
|00 00 06.5500|+25 53 11.308|    5.17|         8| 9.05|   1.102|
|00 00 08.4821|+36 35 09.376|    4.81|         9| 8.59|   1.067|
|00 00 08.7007|-50 52 01.465|   10.76|        10| 8.59|   0.489|
|00 00 08.9513|+46 56 24.006|    4.29|        11| 7.34|   0.081|
|00 00 09.8202|-35 57 36.809|    4.06|        12| 8.43|   1.484|

```

こんな感じでデータが出力されるので、前回のプログラムがそのまま使えるよう変換します
まずはいらない部分を省いて

```
|00 00 00.2188|+01 05 20.448|    3.54|         1| 9.10|   0.482|
|00 00 00.9114|-19 29 55.815|   21.90|         2| 9.27|   0.999|
|00 00 01.2019|+38 51 33.430|    2.81|         3| 6.61|  -0.019|
|00 00 02.0116|-51 53 36.766|    7.75|         4| 8.06|   0.370|
|00 00 02.3917|-40 35 28.408|    2.87|         5| 8.55|   0.902|
|00 00 04.3539|+03 56 47.360|   18.80|         6|12.31|   1.336|
|00 00 05.4117|+20 02 11.768|   17.74|         7| 9.64|   0.740|
|00 00 06.5500|+25 53 11.308|    5.17|         8| 9.05|   1.102|
|00 00 08.4821|+36 35 09.376|    4.81|         9| 8.59|   1.067|
|00 00 08.7007|-50 52 01.465|   10.76|        10| 8.59|   0.489|
|00 00 08.9513|+46 56 24.006|    4.29|        11| 7.34|   0.081|
|00 00 09.8202|-35 57 36.809|    4.06|        12| 8.43|   1.484|
```

変換はエクセルで整形したり、例えばこのような変換プログラムを作って行います
Assetsフォルダの外（同じ階層）にデータを置くと、同じ場所に変換されたデータがセーブされます

```StringReadWriteTest.cs
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class StringReadWriteTest : MonoBehaviour {
    [SerializeField] string filePath = "stringSaveData.csv";
    [SerializeField] bool usePersistentDataPath = false;
    private List<string> dataList;

	// Use this for initialization
	void Start () {
        dataList = readData(filePath);
	}
	
	// Update is called once per frame
	void Update () {
		
	}

    private void OnDestroy()
    {
        writeData(filePath,dataList);
    }

    private List<string> readData(string _path){
        List<string> _dataList = new List<string>();
        string path = _path;
        if(usePersistentDataPath){
            path = Application.persistentDataPath + "/" + path;
        }
        if(System.IO.File.Exists(path)){
            StreamReader sr = new StreamReader(path);
            int cnt = 0;
            while (sr.Peek() > -1)
            {
                cnt++;
                string lineStr = sr.ReadLine();
                if(!lineStr.StartsWith("//",System.StringComparison.CurrentCulture)){
                    string reData = reCreateData(lineStr);
                    _dataList.Add(reData);
                    Debug.Log(">"+cnt);
                }
            }
            sr.Close();
        }else{
            for (int i = 0; i < 10; ++i){
                _dataList.Add("0,1,2,3,4,5,6,7,8,9");
            }
        }
        return _dataList;
    }

    private bool writeData(string _path, List<string> _dataList)
    {
        bool ret = false;
        string path = "out_"+_path;
        if(usePersistentDataPath){
            path = Application.persistentDataPath + "/" + path;
        }
        StreamWriter sw = new StreamWriter(path);
        foreach (string data in _dataList)
        {
            sw.WriteLine(data);
        }
        sw.Flush();
        sw.Close();
        return ret;
    }

    private string reCreateData(string _dataStr){
        string[] dataArr = _dataStr.Split('|');
        string data = "";
        string hipId = dataArr[4];
        string[] rkd = dataArr[1].Split(' ');
        string[] rid = dataArr[2].Split(' ');
        string mag = dataArr[5];
        string palla = dataArr[3];
        string vbcol = dataArr[6];

        int id = 0;
        int.TryParse(hipId,out id);
        float fKdH = 0f;
        float fKdM = 0f;
        float fKdS = 0f;
        float.TryParse(rkd[0], out fKdH);
        float.TryParse(rkd[1], out fKdM);
        float.TryParse(rkd[2], out fKdS);
        int iKdSGN = rid[0].Substring(0,1)=="+" ? 1 : 0;
        float fidD = 0f;
        float fidM = 0f;
        float fidS = 0f;
        float.TryParse(rid[0], out fidD);
        float.TryParse(rid[1], out fidM);
        float.TryParse(rid[2], out fidS);
        float vmag = 0f;
        float.TryParse(mag, out vmag);
        float iPara = 0f;
        float.TryParse(palla, out iPara);
        float vb = 0f;
        float.TryParse(vbcol, out vb);

        data = "";
        data += id.ToString() + ",";
        data += fKdH.ToString() + ",";
        data += fKdM.ToString() + ",";
        data += fKdS.ToString() + ",";
        data += iKdSGN.ToString() + ",";
        data += (Mathf.Abs(fidD)).ToString() + ",";
        data += fidM.ToString() + ",";
        data += fidS.ToString() + ",";
        data += vmag.ToString() + ","; // 8
        data += iPara.ToString() + ","; // 9
        data += "0,0,";
        data += vb.ToString() + ","; // 12
        return data;
    }
}
```

変換結果はこのようになります

```
1,0,0,0.2188,1,1,5,20.448,9.1,3.54,0,0,0.482,
2,0,0,0.9114,0,19,29,55.815,9.27,21.9,0,0,0.999,
3,0,0,1.2019,1,38,51,33.43,6.61,2.81,0,0,-0.019,
4,0,0,2.0116,0,51,53,36.766,8.06,7.75,0,0,0.37,
5,0,0,2.3917,0,40,35,28.408,8.55,2.87,0,0,0.902,
6,0,0,4.3539,1,3,56,47.36,12.31,18.8,0,0,1.336,
7,0,0,5.4117,1,20,2,11.768,9.64,17.74,0,0,0.74,
8,0,0,6.55,1,25,53,11.308,9.05,5.17,0,0,1.102,
9,0,0,8.4821,1,36,35,9.376,8.59,4.81,0,0,1.067,
10,0,0,8.7007,0,50,52,1.465,8.59,10.76,0,0,0.489,
11,0,0,8.9513,1,46,56,24.006,7.34,4.29,0,0,0.081,
12,0,0,9.8202,0,35,57,36.809,8.43,4.06,0,0,1.484,
```

>Parallax
The trigonometric parallax pi in units of milliarcseconds: thus to calculate the distance D in parsecs, D = 1000/pi. 

とあるので距離を入れてみました（かなりデフォルメしてあります）。

![スクリーンショット 2018-02-25 8.35.11.png](https://qiita-image-store.s3.amazonaws.com/0/59911/82e41f6b-5b00-d6bb-c625-910abb50480b.png)


また、[こちらのサイト](https://stackoverflow.com/questions/21977786/star-b-v-color-index-to-apparent-rgb-color)に bv_color を RGBに変換するコードが乗っていたので参考にさせていただきました

```
    static Color BV2Col(float _bv){
        Color col = Color.white;
        float t = 4600f * ((1 / ((0.92f * _bv) + 1.7f)) + (1f / ((0.92f * _bv) + 0.62f)));

        // t to xyY
        float x=0f, y=0f;
        if (t >= 1667f && t <= 4000f){
            x = ((-0.2661239f * Mathf.Pow(10f, 9f)) / Mathf.Pow(t, 3f)) + ((-0.2343580f * Mathf.Pow(10, 6)) / Mathf.Pow(t, 2f)) + ((0.8776956f * Mathf.Pow(10f, 3f)) / t) + 0.179910f;
        }
        else if (t > 4000f && t <= 25000f){
            x = ((-3.0258469f * Mathf.Pow(10f, 9f)) / Mathf.Pow(t, 3f)) + ((2.1070379f * Mathf.Pow(10f, 6f)) / Mathf.Pow(t, 2f)) + ((0.2226347f * Mathf.Pow(10f, 3f)) / t) + 0.240390f;
        }

        if (t >= 1667f && t <= 2222f){
            y = -1.1063814f * Mathf.Pow(x, 3f) - 1.34811020f * Mathf.Pow(x, 2f) + 2.18555832f * x - 0.20219683f;
        }
        else if (t > 2222f && t <= 4000f){
            y = -0.9549476f * Mathf.Pow(x, 3f) - 1.37418593f * Mathf.Pow(x, 2f) + 2.09137015f * x - 0.16748867f;
        }
        else if (t > 4000f && t <= 25000f){
            y = 3.0817580f * Mathf.Pow(x, 3f) - 5.87338670f * Mathf.Pow(x, 2f) + 3.75112997f * x - 0.37001483f;
        }

        // xyY to XYZ, Y = 1
        float Y = (y == 0f) ? 0f : 1f;
        float X = (y == 0f) ? 0f : (x * Y) / y;
        float Z = (y == 0f) ? 0f : ((1f - x - y) * Y) / y;

        // XYZ to RGB
        col.r = 0.41847f * X - 0.15866f * Y - 0.082835f * Z;
        col.g = -0.091169f * X + 0.25243f * Y + 0.015708f * Z;
        col.b = 0.00092090f * X - 0.0025498f * Y + 0.17860f * Z;
        col.a = 1f;
        return col;
    }
```

![スクリーンショット 2018-02-25 2.56.00.png](https://qiita-image-store.s3.amazonaws.com/0/59911/8154dd80-c9dd-70df-4c6e-78d8350e53d1.png)

[星を表示する（１）　CSVデータを読み込む](https://qiita.com/ELIXIR/items/65e6fb2804c761954ac4)
[星を表示する（２）　星をパーティクルで表示する](https://qiita.com/ELIXIR/items/022fa7490f0f4cfcd491)
[星を表示する（３）　星座線を表示する](https://qiita.com/ELIXIR/items/af92c2995f5c44cd95b7)
星を表示する（４）　データを変換する
[星を表示する（５）　星を点群メッシュで表示する](https://qiita.com/ELIXIR/items/f68b03e71c7bd1a6ed2c)