Android Question Large number of x and y coordinate points

fernando.oliboni

Member
Licensed User
Longtime User
Could someone tell me what is the best way to work with a lot of x and y points, like (3.789056, 0.456789)?

I also need to include points among those that are already on the list.

Could you show me an example?
 

fernando.oliboni

Member
Licensed User
Longtime User
You need to provide more information, including: how many? what do you want to do with them?
Hi Erel, close to 5000 coordinates. I need to: 1) be able to create a vector 2) resize the vector 3) add points at the end of the vector 4) include points between two points that already exist, as in the photo below for example.
1596537625010.png
 
Upvote 0

Brian Dean

Active Member
Licensed User
Longtime User
If you are in any way involved with digital mapping then 5000 points is not very many. I assume that you are storing your data in a List. Decide whether you are really going to work with points (coordinate pairs) or with line segments (vectors - point pairs). If it is the latter then consider making your data a list of vectors rather than a list of points - it increases the storage but simplifies the logic.
B4X:
    Type point (x As Double, y As Double)
    Type vector (p1 As point, p2 As point)
You do not say whether the points are ordered (representing one or more linear features) but I assume that they are. If you are going to be doing fairly complex operations, like finding intersections or doing work where the direction of the vector might change, then I would consider using a linked list of line segments rather than a simple list ...
B4X:
    Type segment (segPrev as segment, p1 as point, p2 as point, segNext as segment)
After that you might want to consider whether the best structure for the work that you want to do is a list or a tree, but that is probably not the case here.

I think that my main piece of advice, from the information that you have given, would be to look at working with vectors rather than simple points. Hope that helps
 
Upvote 0

fernando.oliboni

Member
Licensed User
Longtime User
[QUOTE = "Brian Dean, post: 755793, membro: 69362"]
Se você está de alguma forma envolvido com o mapeamento digital, então 5000 pontos não são muitos. Presumo que você esteja armazenando seus dados em uma lista. Decida se você realmente vai trabalhar com pontos (pares de coordenadas) ou com segmentos de linha (vetores - pares de pontos). Se for o último, considere transformar seus dados em uma lista de vetores em vez de uma lista de pontos - isso aumenta o armazenamento, mas simplifica a lógica.
[CODE = b4x] Ponto de tipo (x como duplo, y como duplo)
Tipo vector (p1 como ponto, p2 como ponto) [/ CODE]
Você não diz se os pontos estão ordenados (representando um ou mais recursos lineares), mas presumo que sejam. Se você estiver realizando operações bastante complexas, como encontrar interseções ou trabalhar onde a direção do vetor pode mudar, consideraria usar uma lista vinculada de segmentos de linha em vez de uma lista simples ...
[CODE = b4x] Digite o segmento (segPrev como segmento, p1 como ponto, p2 como ponto, segNext como segmento) [/ CODE]
Depois disso, convém considerar se a melhor estrutura para o trabalho que você deseja fazer é uma lista ou uma árvore, mas esse provavelmente não é o caso aqui.

Penso que o meu conselho principal, a partir das informações que você forneceu, seria trabalhar com vetores em vez de pontos simples. espero que ajude
[/CITAR]


[CODE = b4x] Ponto de tipo (x como duplo, e como duplo) [/ CODE]
This option seems more appropriate, my points represent a path where I will make interpolations, so I need to be able to insert new points to those that already exist. I will not check intersections or directions, I will only do length and angle calculations between the lines. What are the best practices for adding and addressing these points?
 
Upvote 0

Brian Dean

Active Member
Licensed User
Longtime User
I will only do length and angle calculations between the lines. What are the best practices ...
I don't think that you need to worry too much - just use a list of points. Unfortunately all my work in this subject has been for desktops and mostly with vectors, so I do not have any proven B4A samples to show you. But if I wanted to write a subroutine to split a line segment into two equal parts I would use something like this ...

B4X:
Sub Process_Globals
    
    Type point (x As Double, y As Double)
    
End Sub

' Divide segment starting at point(index) into equal parts
Sub divideSegmentAt(index As Int, points As List)
    Dim p0 As point = points.Get(index)
    Dim p1 As point = points.Get(index + 1)
    Dim newPoint As point
    newPoint.x = (p0.x + p1.x) / 2
    newPoint.y = (p0.y + p1.y) / 2
    points.InsertAt(index + 1, newPoint)   
End Sub
This is the simplest form of interpolation, but it should be a pattern for what you want to do.

Just a word of warning - if you start getting involved with calculations of angles between lines and similar computations, sometimes you can get caught out by unexpected "division-by-zero" errors, usually caused by "vertical" lines. If you have good control over your data that is fine, but if your app is going to be used by other people then be careful or one day you will get caught out.
 
Upvote 0

fernando.oliboni

Member
Licensed User
Longtime User
[QUOTE = "Brian Dean, post: 755812, membro: 69362"]
Eu não acho que você precise se preocupar muito - basta usar uma lista de pontos. Infelizmente, todo o meu trabalho neste assunto foi para desktops e principalmente com vetores, por isso não tenho amostras B4A comprovadas para mostrar a você. Mas se eu quisesse escrever uma sub-rotina para dividir um segmento de linha em duas partes iguais, usaria algo assim ...

[CODE = b4x] Subprocessos_Globais

Tipo de ponto (x como duplo, y como duplo)

End Sub

'Divida o segmento começando no ponto (índice) em partes iguais
SubdivisãoSegmentAt (índice como Int, pontos como lista)
Dim p0 Como ponto = pontos.Get (index)
Dim p1 Como ponto = pontos.Get (index + 1)
Dim newPoint As point
newPoint.x = (p0.x + p1.x) / 2
newPoint.y = (p0.y + p1.y) / 2
points.InsertAt (índice + 1, newPoint)
End Sub
[/CÓDIGO]
Essa é a forma mais simples de interpolação, mas deve ser um padrão para o que você deseja fazer.

Apenas uma palavra de aviso - se você começar a se envolver com cálculos de ângulos entre linhas e cálculos semelhantes, às vezes poderá ser pego por inesperados erros de "divisão por zero", geralmente causados por linhas "verticais". Se você tem um bom controle sobre seus dados, tudo bem, mas se seu aplicativo será usado por outras pessoas, tenha cuidado ou um dia você será pego de surpresa.
[/CITAR]
 
Upvote 0

fernando.oliboni

Member
Licensed User
Longtime User
B4X:
Sub Process_Globals
    Type point (x As Double, y As Double)
    Dim Points As List
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Points.Initialize
    
    'creating vector
    insere(0, Points, 2.345 , 3.890)
    
    insere(1, Points,  2.432 , 1.456)
    
    insere(2, Points,  3.456 , 5.876)
    
    insere(3, Points,  2.876 , 1.456)
    
    insere(4, Points,  10.789 , 11.456)
    
    insere(3, Points,  35.890 , 41.666)
    
    'returning the new positions
    Log(Points.Get(2))
    Log(Points.Get(3))
    Log(Points.Get(5))
End Sub

Sub insere(index As Int, aPoints As List, x As Float, y As Float)
    Dim newPoint As point
    newPoint.x = x
    newPoint.y = y
    aPoints.InsertAt(index , newPoint)
End Sub

worked perfectly
thank you very much

[IsInitialized=false, x=3.4560000896453857, y=5.875999927520752
]
[IsInitialized=false, x=35.88999938964844, y=41.66600036621094
]
[IsInitialized=false, x=10.788999557495117, y=11.456000328063965
]
 
Upvote 0

Brian Dean

Active Member
Licensed User
Longtime User
What you have done is okay, but I think that you might want to look up Lists and their methods. Here is how I would have written your code example ...

B4X:
Sub createPoint(x As Double, y As Double) As point
    Dim p As point
    p.Initialize
    p.x = x
    p.y = y
    Return p  
End Sub

Sub createPoints
    Dim points As List
    points.Initialise
    points.Add(createPoint(2.345 , 3.890))
    points.Add(createPoint(2.432 , 1.456))
    points.Add(createPoint(3.456 , 5.876))
    points.Add(createPoint(2.876 , 1.456))
    points.Add(createPoint(10.789 , 11.456))
    points.Add(createPoint(35.890 , 41.666))
End Sub
 
Upvote 0

fernando.oliboni

Member
Licensed User
Longtime User
What you have done is okay, but I think that you might want to look up Lists and their methods. Here is how I would have written your code example ...

B4X:
Sub createPoint(x As Double, y As Double) As point
    Dim p As point
    p.Initialize
    p.x = x
    p.y = y
    Return p 
End Sub

Sub createPoints
    Dim points As List
    points.Initialise
    points.Add(createPoint(2.345 , 3.890))
    points.Add(createPoint(2.432 , 1.456))
    points.Add(createPoint(3.456 , 5.876))
    points.Add(createPoint(2.876 , 1.456))
    points.Add(createPoint(10.789 , 11.456))
    points.Add(createPoint(35.890 , 41.666))
End Sub
Okay, you've already taken another step perfectly. I am very grateful. Thank you
 
Upvote 0
Top