Предположим, мы хотим создать метки с единичным кругом.

Что сделано: я создал первую точку внутри единичной окружности и присвоил ей метку 1. Я создал вторую точку внутри единичной окружности и присвоил ей метку 0.

Остальные k-2 точки я хочу обозначить следующим образом: если точка лежит в половине круга 1 -> она помечена 1. Если в половине круга 0 ->, то это отметка 0. Значит, что после создания первых двух точек мне нужно провести линию через центр круга, который разделяет первые две точки. После этого мы сравниваем вновь созданную точку с этой линией и маркируем ее. Как я могу делать тонкие на Python?

0
LiverToll92 20 Май 2021 в 01:26

2 ответа

Лучший ответ

Сохраните один из двух углов, назовите его saved_angle и для всех точек x, y проверьте, есть ли x * np.sin(saved_angle) - y * np.cos(saved_angle) < 0. Вот пример кода:

import matplotlib.pyplot as plt
import numpy as np

plt.xlim([-1, 1])
plt.ylim([-1, 1])

# Get two random points, saving the angle of one.

length = np.random.uniform(0, 1)
angle = np.pi * np.random.uniform(0, 2)
x = np.sqrt(length) * np.cos(angle)
y = np.sqrt(length) * np.sin(angle)
plt.plot([x], [y], 'ko')

length = np.random.uniform(0, 1)
saved_angle = np.pi * np.random.uniform(0, 2)
x = np.sqrt(length) * np.cos(saved_angle)
y = np.sqrt(length) * np.sin(saved_angle)
plt.plot([x], [y], 'ko')

# Plot a bunch of random points, checking the condition.

for _ in range(100):
    length = np.random.uniform(0, 1)
    angle = np.pi * np.random.uniform(0, 2)
    x = np.sqrt(length) * np.cos(angle)
    y = np.sqrt(length) * np.sin(angle)
    plt.plot([x], [y], 'bo' if x * np.sin(saved_angle) - y * np.cos(saved_angle) < 0 else 'ro')

plt.show()
1
wjm 19 Май 2021 в 23:19

Как насчет этого?

Идея состоит в том, что после построения первых двух точек x[0,:] и x[1,:], обозначенных y[0] = 0 и y[1] = 1 соответственно, вы можете построить вектор n, перпендикулярный линии который является биссектрисой угла между векторами x[0,:] и x[1,:]. Поэтому этот вектор строится как

n = x[0,:] / norm(x[0,:])  -  x[1,:] / norm(x[1,:])

После этого точка, которая находится на одной стороне, стороне, в которой n указывает, биссектрисы угла, тогда вектор помечается 0 и 1, если он находится на другой стороне биссектрисы угла. Скалярное произведение n.dot(x[i,:]) > 0 означает, что x[i,:] находится на стороне биссектрисы угла, на которую указывает n.

import numpy as np
import matplotlib.pyplot as plt

k = 12
x = np.empty((k, 2), dtype=float)
y = np.empty(k, dtype=int)
n = np.array([0.,0.])
for i in range(k):
    if i < 2:        
        angle = np.pi * np.random.uniform(0, 2)
        x[i,:] = np.array([np.cos(angle), np.sin(angle)])
        n = n + ((-1)**i) * x[i,:]
        length = np.random.uniform(0, 1)
        x[i,:] = np.sqrt(length)*x[i,:]
        y[i] = i
    else:
        angle = np.pi * np.random.uniform(0, 2)
        length = np.random.uniform(0, 1)
        x[i,:] = np.array([np.cos(angle), np.sin(angle)])
        if n.dot(x[i,:]) > 0: 
            y[i] = 0 
        else: 
            y[i] = 1
        x[i,:] = np.sqrt(length) * x[i,:]



s = np.linspace( 0 , 2 * np.pi , 150 )
xc = np.cos( s )
yc = np.sin( s )

xl = np.linspace( -1, 1, 150)  
yl = (- n[0]/n[1]) * xl


figure, axes = plt.subplots( 1 )

axes.plot( xc, yc )
axes.plot(0, 0)
axes.plot( xl, yl )

axes.plot(x[y==1, 0], x[y==1, 1], 'ro')
axes.plot(x[y==0, 0], x[y==0, 1], 'bo')

axes.set_aspect( 1 )  
plt.show()

enter image description here

1
Futurologist 20 Май 2021 в 14:19