Форум программистов, компьютерный форум, киберфорум
Unity, Unity3D
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
1

Генерация 3d-модели города по координатам

08.04.2019, 22:38. Показов 2878. Ответов 27
Метки нет (Все метки)

Здравствуйте. Изучаю Unity недавно. Возникла такая проблема: передо мной стоит задача отстройки 3d-модели города, имеются типы объектов с их координатами. Сам вопрос: есть ли в Unity возможность создания криволинейной области по координатам и функция ее выдавливания на необходимую высоту? Или дома сложной формы прийдется строить из преобразованных кубов? Все это нужно прописать в коде. Такая же проблема с участками травы, воды и дорожек - они далеко не всегда прямоугольной формы. Подскажите пожалуйста, в интернете я подобной информации не нашла.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.04.2019, 22:38
Ответы с готовыми решениями:

Определение города по координатам. Оффлайн
Как узнать в каком городе ты находишься по координатам, оффлайн. Геокодер не пытался юзать - там...

Получить зумм по имени города или координатам
Задача изначально спарсить все города по списку их координаты + зумм что бы был виден весь город. ...

Вращение 2d модели по координатам
Всем привет! Учусь работаю с OpenGL по данным урокам: http://pmg.org.ru/nehe/index.html и вот...

Генерация 3D модели по заданным параметрам
Доброго времени суток!) Необходимо создать приложение на С#, которое по заданным различным...

__________________

Записывайтесь на профессиональные курсы геймдизайнеров
27
Эксперт .NETАвтор FAQ
9852 / 4807 / 1730
Регистрация: 11.01.2015
Сообщений: 5,988
Записей в блоге: 34
08.04.2019, 23:40 2
Цитата Сообщение от Virero Посмотреть сообщение
Сам вопрос: есть ли в Unity возможность создания криволинейной области по координатам и функция ее выдавливания на необходимую высоту?
Нет.
Цитата Сообщение от Virero Посмотреть сообщение
Или дома сложной формы прийдется строить из преобразованных кубов? Все это нужно прописать в коде. Такая же проблема с участками травы, воды и дорожек - они далеко не всегда прямоугольной формы. Подскажите пожалуйста, в интернете я подобной информации не нашла.
Генерируйте необходимую форму в виде меша. Сам меш - в виде полигонов (вершин и ребер).
https://docs.unity3d.com/ScriptReference/Mesh.html
0
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
09.04.2019, 00:28  [ТС] 3
Спасибо, попробую через них.
0
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
14.04.2019, 17:34  [ТС] 4
Здравствуйте еще раз. Пытаюсь сделать плоскость через меш, вроде все делаю правильно, но в Unity он не отображается, подскажите пожалуйста в чем проблема? Меш строится вроде верно, но его не видно. Функция pr_coord() служит для преобразования долготы и ширины в координаты x, y. Массив mas_x содержит координаты x, а mas_y координаты y.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void createGrass (){
        GameObject newObject = new GameObject ("Landuse");
        for (int i = 0; i < 1; i++) {
 
            GameObject newObj = new GameObject ("Grass");
 
            newObj.transform.SetParent (newObject.transform);                           // делаем дочерним элементом Landuse
            MeshFilter m_f = newObj.AddComponent <MeshFilter> () as MeshFilter;         // добавляем компаненты
            MeshRenderer m_r = newObj.AddComponent <MeshRenderer> () as MeshRenderer;
            Mesh mesh = new Mesh ();
            m_f.mesh = mesh;
 
            // вершины
            pr_coord();
            print (mas_x[0]);
            print (mas_y[0]);
            int len = mas_x.Length;
            Vector3[] versh = new Vector3[len];
            for (int i_2 = 0; i_2 < len; i_2++){
                versh[i_2] = new Vector3(mas_x[i_2],0,mas_y[i_2]);
            }
            
 
            // треугольники
            int[] tri = new int[6]{0,1,2,2,3,0};
 
            // uv (отображение текстур)
            /*Vector2[] uvs = new Vector2[versh.Length];
            for (int j = 0; j < uvs.Length; j++){
                uvs[j] = new Vector2(versh[j].x, versh[j].z);
            }*/
 
 
            mesh.vertices = versh;
            mesh.triangles = tri;
            //mesh.uv = uvs;
 
            print(mesh.vertices[0]);
        }
}
0
Миниатюры
Генерация 3d-модели города по координатам  
Эксперт .NETАвтор FAQ
9852 / 4807 / 1730
Регистрация: 11.01.2015
Сообщений: 5,988
Записей в блоге: 34
14.04.2019, 17:57 5
Virero,
Скорее всего, вы смотрите просто не с той стороны, посмотрите снизу.

Вершины треугольника должны задаваться по часовой стрелке. Если вы задаете против часовой стрелки, то поверхность треугольника смотрит в другую сторону (вниз).
1
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
14.04.2019, 20:36  [ТС] 6
Как только не меняла порядок координат, не помогает. Почему-то всегда генерируется в начале координат, хотя должно быть совсем не там. Снизу тоже смотрела - пусто.
0
Миниатюры
Генерация 3d-модели города по координатам   Генерация 3d-модели города по координатам  
Эксперт .NETАвтор FAQ
9852 / 4807 / 1730
Регистрация: 11.01.2015
Сообщений: 5,988
Записей в блоге: 34
14.04.2019, 22:00 7
Virero,
А что это у вас за огромные координаты?
Генерация 3d-модели города по координатам


Конечно же их не видно, они же очень далеко.
Нужно сдвигать координаты вершин так, что бы они были около нулевой точки.
Например, вы можете найти сначала центр точек (как среднее всех координат), и затем сдвигать вершины, отнимая от них координаты центра. Тогда все вершины будут находиться вокруг нулевой точки.
0
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
15.04.2019, 01:25  [ТС] 8
Спасибо, проблема правда с координатами, они либо были на слишком маленьком расстоянии друг от друга и float записывал им одно и то же значение либо были слишком большими.
C#
1
2
3
4
5
6
7
    private float[,] mas = new float[,]{
        {48.7283818f,44.5224288f},
        {48.7281903f,44.5227128f},
        {48.7283466f,44.5229551f},
        {48.7285382f,44.5226711f}
 
    };
Это исходные данные одного объекта - широта и долгота.
Вот примерные широта и долгота переведенные в координаты х и у:
4202698,4467484
4202714,4467506
4202701,4467525
4202686,4467503

Меш строила на основе расстояния между ними от начала координат. Получилось.
Однако возник вопрос: по каким данным мне теперь делать его перемещение? Если по широте с долготой, то объектов много и различие между ними мизерное, все будет наслаиваться. Подскажите пожалуйста. И еще раз спасибо.
0
Эксперт .NETАвтор FAQ
9852 / 4807 / 1730
Регистрация: 11.01.2015
Сообщений: 5,988
Записей в блоге: 34
15.04.2019, 01:52 9
Цитата Сообщение от Virero Посмотреть сообщение
Однако возник вопрос: по каким данным мне теперь делать его перемещение? Если по широте с долготой, то объектов много и различие между ними мизерное, все будет наслаиваться. Подскажите пожалуйста. И еще раз спасибо.
Что значит "делать его перемещение"? Перемещение чего?

Что означают ваши 4 точки? Это координаты углов здания? Тогда непонятно почему они будут наслаиваться, ведь здания не могут пересекаться друг с другом.

Объясните задачу более подробно. А еще лучше выложите исходные данные и сформулируйте что с ними нужно сделать.
0
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
15.04.2019, 22:41  [ТС] 10
Исходные данные - это файл формата OSM с типами объектов, их координатами, различной информацией.
Координаты имеют свой номер id, некоторую информацию, которая не нужна для построения и собственно lan и lon - широту и долготу. Располагаются они в начале файла:

XML
1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.6.1 (1961 thorn-01.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
 <bounds minlat="48.7266900" minlon="44.5197700" maxlat="48.7287100" maxlon="44.5252200"/>
 <node id="419063196" visible="true" version="2" changeset="23955381" timestamp="2014-07-04T18:25:43Z" user="MacVit" uid="673252" lat="48.7201477" lon="44.5078437"/>
 <node id="419063232" visible="true" version="5" changeset="31925805" timestamp="2015-06-12T16:30:12Z" user="b108" uid="621253" lat="48.7193508" lon="44.5064603"/>
 <node id="419063237" visible="true" version="6" changeset="31925805" timestamp="2015-06-12T16:30:12Z" user="b108" uid="621253" lat="48.7192771" lon="44.5065619"/>
 <node id="419063326" visible="true" version="2" changeset="8274208" timestamp="2011-05-28T18:04:28Z" user="andword" uid="406013" lat="48.7210783" lon="44.5095209"/>
.... и т.д.

Так выглядит структура объектов:
XML
1
2
3
4
5
6
7
8
9
10
11
12
 <way id="118682595" visible="true" version="4" changeset="9436062" timestamp="2011-09-30T15:10:33Z" user="acsd" uid="345493">
  <nd ref="1334285832"/>
  <nd ref="1334285834"/>
  <nd ref="1334285833"/>
  <nd ref="1334285830"/>
  <nd ref="1334285832"/>
  <tag k="addr:housenumber" v="18"/>
  <tag k="addr: postcode" v="400050"/>
  <tag k="addr:street" v="улица Хиросимы"/>
  <tag k="building" v="yes"/>
  <tag k="building:levels" v="4"/>
 </way>
Строчки <nd ref="1334285832"/> это отсылка к id координат из начала файла. Они представляют из себя набор из точек, при том начальная и конечная точки совпадают, т.е. линия замкнутая. Да, это вершины области (здания\травы и д.р.).
Все это еще нужно структурировать, но этой проблемой я еще не занялась.
Суть в том, что объектов много, нужно построить участок города как минимум, т.е. их нужно передвигать на нужное место. При том надо располагать их недалеко от начала координат? Тогда по каким параметрам измерять это расстояние?
На изображении представлена тестовая область, для которой создаю код, так планируется минимум для города.
0
Миниатюры
Генерация 3d-модели города по координатам  
745 / 593 / 203
Регистрация: 06.08.2015
Сообщений: 2,429
16.04.2019, 02:48 11
1. Координаты вертексов (вершин меша) - это локальные координаты, которые от положения (ну и поворота тоже) не зависят. Построить меш по координатам относительно центра и переместить сам объект в эти координаты.
2. В юнити координаты задаются типом float (он же single), а у него не настолько большая точность, чтобы использовать тысячные в координатах далеко за 100 000 целых. Вообще, ограничиваются 10 000 максимум, иначе возникают проблемы с позиционированием (наиболее заметно в анимациях).
3. Координата в 4 миллиона - это 4 тысячи километров. С масштабом нет ошибки? 1 юнит - это 1 метр. Если ошибки нет, то перемещайте центр всей этой композиции в ноль и от него стройте по относительным координатам.
0
Эксперт .NETАвтор FAQ
9852 / 4807 / 1730
Регистрация: 11.01.2015
Сообщений: 5,988
Записей в блоге: 34
16.04.2019, 03:54 12
Лучший ответ Сообщение было отмечено Virero как решение

Решение

Цитата Сообщение от Virero Посмотреть сообщение
Исходные данные - это файл формата OSM
OSMBuilder
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml;
using UnityEngine;
 
public class OSMBuilder : MonoBehaviour
{
    public double Latitude = 40.66961;
    public double Longitude = -73.79330;
    public double RadiusLat = 0.002d;
    public double RadiusLon = 0.002d;
 
    public Material Material;
 
    void Start()
    {
        StartCoroutine(Build());
    }
 
    IEnumerator Build()
    {
        //calc rectangle
        var fromLat = (Latitude - RadiusLat).ToString(CultureInfo.InvariantCulture);
        var toLat = (Latitude + RadiusLat).ToString(CultureInfo.InvariantCulture);
 
        var fromLon = (Longitude - RadiusLon).ToString(CultureInfo.InvariantCulture);
        var toLon = (Longitude + RadiusLon).ToString(CultureInfo.InvariantCulture);
 
        //download OSM data
        var url = $"https://www.openstreetmap.org/api/0.6/map?bbox={fromLon}%2C{fromLat}%2C{toLon}%2C{toLat}";
        var www = new WWW(url);
        yield return www;
 
        if (!string.IsNullOrEmpty(www.error))
            yield break;
 
        //build mesh
        var xml = www.text;
        BuildMesh(xml);
    }
 
    private void BuildMesh(string xml)
    {
        //parse XML
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(new StringReader(xml));
 
        //parse points, translate to Cartesian coordinates
        var points = ParsePoints(xmlDoc);
 
        //parse buildings
        var buildings = ParseBuildings(xmlDoc, points);
 
        //create holder
        var buildingsObj = new GameObject("Buildings");
        buildingsObj.transform.SetParent(transform);
        var mf = buildingsObj.AddComponent<MeshFilter>();
        var mr = buildingsObj.AddComponent<MeshRenderer>();
        var mesh = new Mesh();
        mf.mesh = mesh;
        mr.material = Material;
 
        //build mesh
        BuildMesh(mesh, buildings);
    }
 
    private void BuildMesh(Mesh mesh, List<Building> buildings)
    {
        var verticies = new List<Vector3>();
        var triangles = new List<int>();
        var normals = new List<Vector3>();
 
        foreach (var b in buildings)
        {
            var startIndex = verticies.Count;
            var vertCount = b.Path.Count;
 
            //triangulate roof
            var tr = new Triangulator(b.Path.ToArray());
            triangles.AddRange(tr.Triangulate().Select(t=>t + startIndex));
            verticies.AddRange(b.Path.Select(p=>new Vector3(p.x, b.Height, p.y)));
 
            //create walls
            for(int i=0;i < b.Path.Count; i++)
            {
                var P0 = b.Path[(i + 1) % vertCount];
                var P1 = b.Path[i];
 
                var p0 = new Vector3(P0.x, b.Height, P0.y);
                var p1 = new Vector3(P1.x, b.Height, P1.y);
                var p2 = new Vector3(P1.x, 0, P1.y);
                var p3 = new Vector3(P0.x, 0, P0.y);
 
                //one
                startIndex = verticies.Count;
                verticies.Add(p0);
                verticies.Add(p1);
                verticies.Add(p2);
                triangles.Add(startIndex + 0);
                triangles.Add(startIndex + 1);
                triangles.Add(startIndex + 2);
 
                //two
                startIndex = verticies.Count;
                verticies.Add(p0);
                verticies.Add(p2);
                verticies.Add(p3);
                triangles.Add(startIndex + 0);
                triangles.Add(startIndex + 1);
                triangles.Add(startIndex + 2);
            }
        }
 
        mesh.vertices = verticies.ToArray();
        mesh.triangles = triangles.ToArray();
 
        mesh.RecalculateNormals();
    }
 
    private static List<Building> ParseBuildings(XmlDocument xmlDoc, Dictionary<long, Vector2> points)
    {
        var buildings = new List<Building>();
        foreach (XmlNode node in xmlDoc.SelectNodes("/osm/way"))
        if (node.SelectSingleNode("tag[@k='building']") != null)
        {
            var building = new Building();
            //parse path points
            foreach (XmlNode n in node.SelectNodes("nd"))
            {
                Vector2 p;
                var reference = long.Parse(n.Attributes["ref"].Value, CultureInfo.InvariantCulture);
                if (points.TryGetValue(reference, out p))
                    building.Path.Add(p);
            }
            //remove last point
            if (building.Path.Count > 1)
                building.Path.RemoveAt(building.Path.Count - 1);
            //get height
            var heightNode = node.SelectSingleNode("tag[@k='height']");
            if (heightNode != null)
            {
                building.Height = float.Parse(heightNode.Attributes["v"].Value, CultureInfo.InvariantCulture);
            }
            //add to list
            buildings.Add(building);
        }
 
        return buildings;
    }
 
    private Dictionary<long, Vector2> ParsePoints(XmlDocument xmlDoc)
    {
        //parse points, translate to Cartesian coordinates
        var center = new Vector2d(Longitude, Latitude);
        var points = new Dictionary<long, Vector2>();
        foreach (XmlNode node in xmlDoc.SelectNodes("/osm/node"))
        {
            var id = long.Parse(node.Attributes["id"].Value);
            var lat = double.Parse(node.Attributes["lat"].Value, CultureInfo.InvariantCulture);
            var lon = double.Parse(node.Attributes["lon"].Value, CultureInfo.InvariantCulture);
            var point = LocationHelper.LocationToCartesian(center, new Vector2d(lon, lat));
            points[id] = point;
        }
 
        return points;
    }
 
    class Building
    {
        public List<Vector2> Path = new List<Vector2>();
        public float Height = 5;
    }
}


LocationHelper
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public static class LocationHelper
{
    public const double MetersPerLongitudeOnEquator = 111319.9;
    public const double MetersPerLatitude = 111132.9;
 
    public static double GetDistanceInMeters(Vector2d from, Vector2d to)
    {
        // Z -> north
        var dz = (from.y - to.y) * MetersPerLatitude;
 
        // X -> east
        var d = (from.x - to.x);
        if (d <= -180) d += 360;
        if (d > 180) d -= 360;
        var dx = d * Math.Cos(from.y * Mathf.Deg2Rad) * MetersPerLongitudeOnEquator;
 
        return Math.Sqrt(dz * dz + dx * dx);
    }
 
    public static Vector2 LocationToCartesian(Vector2d center, Vector2d point)
    {
        // Z -> north
        var dz = (center.y - point.y) * MetersPerLatitude;
 
        // X -> east
        var d = (center.x - point.x);
        if (d <= -180) d += 360;
        if (d > 180) d -= 360;
        var dx = d * Math.Cos(center.y * Mathf.Deg2Rad) * MetersPerLongitudeOnEquator;
 
        return new Vector2((float)dx, (float)dz);
    }
}
 
public struct Vector2d
{
    /// <summary>
    /// Longitude
    /// </summary>
    public double x;
    /// <summary>
    /// Latitude
    /// </summary>
    public double y;
 
    public Vector2d(double lon, double lat)
    {
        this.x = lon;
        this.y = lat;
    }
 
    public override string ToString()
    {
        return string.Format(" X={0:0.0000} Y={1:0.0000}", x, y);
    }
 
    public double magnitudeSqr => x * x + y * y;
    public double magnitude => Math.Sqrt(x * x + y * y);
 
    public static Vector2d Lerp(Vector2d from, Vector2d to, double t)
    {
        var t0 = 1 - t;
        return new Vector2d(from.x * t0 + to.x * t, from.y * t0 + to.y * t);
    }
 
    public static Vector2d operator +(Vector2d v1, Vector2d v2)
    {
        return new Vector2d(v1.x + v2.x, v1.y + v2.y);
    }
 
    public static Vector2d operator -(Vector2d v1, Vector2d v2)
    {
        return new Vector2d(v1.x - v2.x, v1.y - v2.y);
    }
 
    public static Vector2d operator *(Vector2d v1, double k)
    {
        return new Vector2d(v1.x * k, v1.y * k);
    }
 
    public static Vector2d operator /(Vector2d v1, double k)
    {
        return new Vector2d(v1.x / k, v1.y / k);
    }
 
    public static double Dot(Vector2d v1, Vector2d v2)
    {
        return v1.x * v2.x + v1.y * v2.y;
    }
}


Triangulator
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System.Collections.Generic;
using UnityEngine;
 
public class Triangulator
{
    private List<Vector2> m_points = new List<Vector2>();
 
    public Triangulator(Vector2[] points)
    {
        m_points = new List<Vector2>(points);
    }
 
    public int[] Triangulate()
    {
        List<int> indices = new List<int>();
 
        int n = m_points.Count;
        if (n < 3)
            return indices.ToArray();
 
        int[] V = new int[n];
        if (Area() > 0)
        {
            for (int v = 0; v < n; v++)
                V[v] = v;
        }
        else
        {
            for (int v = 0; v < n; v++)
                V[v] = (n - 1) - v;
        }
 
        int nv = n;
        int count = 2 * nv;
        for (int v = nv - 1; nv > 2;)
        {
            if ((count--) <= 0)
                return indices.ToArray();
 
            int u = v;
            if (nv <= u)
                u = 0;
            v = u + 1;
            if (nv <= v)
                v = 0;
            int w = v + 1;
            if (nv <= w)
                w = 0;
 
            if (Snip(u, v, w, nv, V))
            {
                int a, b, c, s, t;
                a = V[u];
                b = V[v];
                c = V[w];
                indices.Add(a);
                indices.Add(b);
                indices.Add(c);
                for (s = v, t = v + 1; t < nv; s++, t++)
                    V[s] = V[t];
                nv--;
                count = 2 * nv;
            }
        }
 
        indices.Reverse();
        return indices.ToArray();
    }
 
    private float Area()
    {
        int n = m_points.Count;
        float A = 0.0f;
        for (int p = n - 1, q = 0; q < n; p = q++)
        {
            Vector2 pval = m_points[p];
            Vector2 qval = m_points[q];
            A += pval.x * qval.y - qval.x * pval.y;
        }
        return (A * 0.5f);
    }
 
    private bool Snip(int u, int v, int w, int n, int[] V)
    {
        int p;
        Vector2 A = m_points[V[u]];
        Vector2 B = m_points[V[v]];
        Vector2 C = m_points[V[w]];
        if (Mathf.Epsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x))))
            return false;
        for (p = 0; p < n; p++)
        {
            if ((p == u) || (p == v) || (p == w))
                continue;
            Vector2 P = m_points[V[p]];
            if (InsideTriangle(A, B, C, P))
                return false;
        }
        return true;
    }
 
    private bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
    {
        float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
        float cCROSSap, bCROSScp, aCROSSbp;
 
        ax = C.x - B.x; ay = C.y - B.y;
        bx = A.x - C.x; by = A.y - C.y;
        cx = B.x - A.x; cy = B.y - A.y;
        apx = P.x - A.x; apy = P.y - A.y;
        bpx = P.x - B.x; bpy = P.y - B.y;
        cpx = P.x - C.x; cpy = P.y - C.y;
 
        aCROSSbp = ax * bpy - ay * bpx;
        cCROSSap = cx * apy - cy * apx;
        bCROSScp = bx * cpy - by * cpx;
 
        return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
    }
}


Генерация 3d-модели города по координатам
2
Вложения
Тип файла: zip OSM Builder.zip (85.7 Кб, 6 просмотров)
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
19.04.2019, 21:23  [ТС] 13
Благодарю!!! Большое Вам спасибо)

Добавлено через 47 минут
Ругается на значение Vector2d в OSMBuilder:
The type or namespace name `Vector2d' could not be found. Are you missing a using directive or an assembly reference?
Не видит он его.
Если изменить на Vector2, то ругается, что значения не типа float:
The best overloaded method match for `UnityEngine.Vector2.Vector2(float, float)' has some invalid arguments
0
488 / 285 / 128
Регистрация: 30.10.2018
Сообщений: 1,309
19.04.2019, 21:26 14
Virero, скорее всего там и должно быть Vector2, но тип дабл не приемлем для конструктора, поэтому приведи ко флоату,
C#
1
var center = new Vector2d((float)Longitude, (float)Latitude);
0
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
19.04.2019, 21:59  [ТС] 15
Спасибо, все нашла.

Добавлено через 24 минуты
Ругается на знак "=>" в LocationHelper в строке:
public double magnitudeSqr => x * x + y * y;

Ошибки:
Identifier expected: `=>' is a keyword
Parsing error

Это знак присваивания/следования или что он означает?
0
Эксперт .NETАвтор FAQ
9852 / 4807 / 1730
Регистрация: 11.01.2015
Сообщений: 5,988
Записей в блоге: 34
19.04.2019, 22:19 16
Цитата Сообщение от Virero Посмотреть сообщение
public double magnitudeSqr => x * x + y * y;
Это аналог геттера:

C#
1
public double magnitudeSqr{ get{ return x * x + y * y;} }
0
2066 / 1323 / 765
Регистрация: 26.10.2018
Сообщений: 3,837
19.04.2019, 22:26 17
Virero, обнови юнити и студию до последней версии, там есть поддержка нового шарпа.
0
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
20.04.2019, 12:47  [ТС] 18
Благодарю)
0
0 / 0 / 0
Регистрация: 30.07.2018
Сообщений: 27
04.05.2019, 18:40  [ТС] 19
По мере моего разбирательства с кодом возник вопрос: каким методом производится триангуляция треугольников? Есть где-нибудь в интернете словесное описание алгоритма?
0
Эксперт .NETАвтор FAQ
9852 / 4807 / 1730
Регистрация: 11.01.2015
Сообщений: 5,988
Записей в блоге: 34
04.05.2019, 19:20 20
Цитата Сообщение от Virero Посмотреть сообщение
каким методом производится триангуляция
Я просто взял первый попавшийся алгоритм отсюда http://wiki.unity3d.com/index.php/Triangulator
Это "наивная" реализация. В принципе наверное можно найти где-то триангуляцию Делоне, если текущая смущает.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.05.2019, 19:20

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Как можно получить доступ к координатам модели в графическом окне (STL и матлаб)
Всем доброго времени суток! В solidworks 2015 sp5 я создал STL модель, чтобы импортировать её в...

Генерация таблиц по классам модели в существующую БД
Здравствуйте. Создал классы C# (code first) и как добавить таблицы в существующую БД не мапя...

Автоматическая генерация макро кода в Solidworks при открытии готовой модели
Доброго форумчане, вопрос возник от фичи с Компасом - 3D - перед записью в нем макроса -&gt; выделить...

Генерация каталога базы данных из модели данных
Суть такова, что по заданию нужно создать физическую модель данных (сущности, ключи, атрибуты,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.