본문 바로가기

재밌는 놀이

우리 어디서 볼까? 정중앙에서 보자

 

 3명이 뭉쳐서 친구들끼리 어디서 볼지 정하는데 한참 걸리는 경우가 있다.

 

솔직히 장난삼아 해본다.

 

준이랑 경수랑 볼때, 어디서 만날지 정하다 싸우지말고, 

 

정중앙에서 만나면 어떨까?

 

코드를 올린다. 

 

주소기업란은 코드 1/3쯤 있다.

!pip install folium  #지도 다운받는 라이브러리
!pip install geopy   #위도,경도 받는 라이브러리

import folium #지도 라이브러리
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from geopy.geocoders import Nominatim #위도, 경도

####### 도로명주소 위도 경도 값으로 바꿔주기 ########
from geopy.geocoders import Nominatim
geo_local = Nominatim(user_agent='South Korea')

# 위도, 경도 반환하는 함수
def geocoding(address):
    try:
        geo = geo_local.geocode(address)
        x_y = [geo.latitude, geo.longitude]
        return x_y

    except:
        return [0,0]

##################################################################
########################ㅏ주소 기입란 #############################
##################################################################
first = [*geocoding("여기에 주소를 적어주세요"), 'first']
second = [*geocoding("여기에 주소를 적어주세요"), 'second']
third = [*geocoding("여기에 주소를 적어주세요"),'third']
#################################################################
#################################################################
##################################################################

first, second, third

#데이터넣기 : [위도, 경도, 주소]
##first = [37.3031, 127.0474, 'first'] #예제
##second = [37.3237, 127.1235, 'second'] #예제
##third = [37.1996, 127.0696, 'third'] #예제
data = pd.DataFrame({'latitude' : [first[0], second[0], third[0]],
                     'longitude' : [first[1], second[1], third[1]],
                     'location' : [first[2], second[2], third[2]]})
data_tria = pd.DataFrame({'latitude' : [first[0], second[0], third[0], first[0]],
                     'longitude' : [first[1], second[1], third[1], first[1]],
                     'location' : [first[2], second[2], third[2], first[2]]})
lines = data_tria[['latitude', 'longitude']]
lines
print(data)


##지도의 중심잡기
center = [data['latitude'].mean(axis = 0), data['longitude'].mean(axis = 0)]
meeting = folium.Map(location=center, zoom_start=10)
meeting

##각각 위치 표시하기
for ii in range(len(data)):
    folium.Marker([data.iloc[ii][0],
                   data.iloc[ii][1]],
                  popup=data['location'][ii],
                  tooltip = data['location'][ii]).add_to(meeting)
    
##선따라 그리기
folium.PolyLine(
    locations = lines,
    tooltip = 'PolyLine'
).add_to(meeting)


meeting

##대변 찾기 : 길이가 가장 긴변이 대변
dist_first_second = np.sqrt((data.iloc[0]['latitude'] - data.iloc[1]['latitude'])**2
                             + (data.iloc[0]['longitude'] - data.iloc[1]['longitude'])**2)
dist_first_third = np.sqrt((data.iloc[0]['latitude'] - data.iloc[2]['latitude'])**2
                             + (data.iloc[0]['longitude'] - data.iloc[2]['longitude'])**2)
dist_second_third = np.sqrt((data.iloc[1]['latitude'] - data.iloc[2]['latitude'])**2
                             + (data.iloc[1]['longitude'] - data.iloc[2]['longitude'])**2)
dist_list = [dist_first_second, dist_first_third, dist_second_third]
data_distance_list = pd.DataFrame({'first_to_second' : [0], 
                                   'first_to_third' : [1],
                                   'second_to_third' : [2]})

print('대변은 : '+ data_distance_list.T.iloc[[np.argmax(dist_list)]].index)
# 0 : first와 second가 대변
# 1 : first와 third가 대변
# 2 : second과 third가 대변

##대변의 중앙 구하기
middle = [(second[0] + third[0])/2, (second[1] + third[1])/2]
center_of_gravity = [(2*middle[0] + first[0])/3, (2*middle[1] + first[1])/3]

##무게중심 표시하기
folium.Circle(
    location = center_of_gravity,
    tooltip = 'center_of_gravity',
    radius = 500,
    color = 'red'
).add_to(meeting)
meeting

 

위의 코드는 문제가 있다. 

바로 3명만 가능하든 문제이다.

 

n명일때의 도형의 중심은 어떻게 구할까?

 

이제부턴 방정식을 풀어야한다. 

 

다음과 같은 방법들이 있다. 

  • 방법1  ** n각형의 중심은 모든 꼭짓점을 활용하여 삼각형으로 나눈 후, 그 삼각형의 중심들의 중심을 구하면 된다.**
  • 방법2  ** n각형의 중심은 모든 꼭짓점을 활용하여 모든 꼭짓점에서 거리가 같은 점 1개를 찾으면 된다. (n차방정식 근을 구하기)**

 

코드로 구현해보자 코드가 길기 때문에, 설명은 하되, py파일과 ipynb파일을 첨부한다. 

Mentoring.ipynb
0.03MB
people_middle.py
0.01MB

본 포스팅에선, 방법2를 사용하여 n명의 중심을 구한다. 

 

N각형을 삼각형으로 만들고, 모든 삼각형의 중심의 평균을 구하는 방법이다. 

    ##삼각형으로 쪼개고
    ##각 삼각형의 중심의 중점
    tri = Delaunay(vertices)
    centers = []
    for indices in tri.simplices:
        # 삼각형의 꼭지점 좌표를 가져옵니다.
    #     print('indices : ', indices)
        triangle = vertices.iloc[indices]
    #     print('triangle : ', triangle)
        # 삼각형의 중심을 계산합니다.
        center = triangle.mean(axis=0)
        centers.append(center)
    center_mean = sum(centers) / len(centers)

 

Dealunay라는 간단한 방정식의 근을 구하는 라이브러리를 import 해야한다.

 

이로써 n명의 주소를 통해서, n명의 약속장소를 구할 수 있다!!

 

Wow~~~~!!!!!

 완성~!!

'재밌는 놀이' 카테고리의 다른 글

파이썬에서 무료로 쉽게 위도,경도 불러오기  (0) 2022.10.29