Python 创建一条线,该线穿过一个点并围绕该点旋转,直到它碰到另一个点,从而使其围绕新点旋转
我决定在2011年数学奥林匹克竞赛中创建第二道题的可视化。我需要创建一条穿过一个点的线,一旦它与另一个点相交,我需要它围绕它旋转 更多信息: 我现在有两条线从我的点数组的最后一点开始,但一旦线开始旋转,两条线都需要移动,我不知道如何计算Python 创建一条线,该线穿过一个点并围绕该点旋转,直到它碰到另一个点,从而使其围绕新点旋转,python,zelle-graphics,Python,Zelle Graphics,我决定在2011年数学奥林匹克竞赛中创建第二道题的可视化。我需要创建一条穿过一个点的线,一旦它与另一个点相交,我需要它围绕它旋转 更多信息: 我现在有两条线从我的点数组的最后一点开始,但一旦线开始旋转,两条线都需要移动,我不知道如何计算 随机导入 输入数学 从图形导入* winWidth=300 winHeight=240 def show(): pointSetX=[] 点集=[] totalSet=[] ''显示屏幕上的所有点'' 对于范围内的i(random.randrange(2,10)
随机导入
输入数学
从图形导入*
winWidth=300
winHeight=240
def show():
pointSetX=[]
点集=[]
totalSet=[]
''显示屏幕上的所有点''
对于范围内的i(random.randrange(2,10)):
x=数学地板(随机.randrange(0,winWidth))
y=数学层(随机.randrange(0,winWidth))
pt=点(x,y)
圆形旋转=圆形(pt,4)
circleForRotation.setFill('白色')
圆圈旋转。抽签(赢)
pointSetX.append(x)
pointSetY.append(y)
totalSet=zip(pointSetX,pointSetY)
''打印集合以查看所有点的位置''
打印(全集)
''在屏幕上显示行''
ln=直线(点,点(点x,高度))
ln2=线(点,点(点x,0))
ln.setFill('red')
ln2.设置填充(“蓝色”)
ln2.平局(赢)
ln.平局(赢)
win=GraphWin('IMO 20011 P2',winWidth,winHeight)
show()
代码中的所有内容都按预期工作,但这两行都以点为端点,我不知道如何在不让一行而不是两行通过点的情况下继续处理问题。下面是我尝试使用Zelle graphics将您的问题可视化。我的解决方案是使线条的大小为窗口的两倍,并且每次碰到一个点时,重新调整其中心:
from random import randrange, choice
from math import sin, cos
from graphics import *
NONCOLLINEAR_POINTS = 6
CIRCLE_RADIUS = 4
WINDOW_SIZE = 500
DELTA = -0.0001 # in radians
def rotateLine(line, theta):
cosine, sine = cos(theta), sin(theta)
points = [line.getP1(), line.getP2()] # use copies, not originals!
center = line.getCenter()
for point in points:
dx, dy = point.x - center.x, point.y - center.y
point.x = center.x + dx * cosine + dy * sine
point.y = center.y + dy * cosine - dx * sine
return Line(*points)
def collinear(a, b, c):
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y) < 0
def distance(a, b):
return ((b.x - a.x) ** 2 + (b.y - a.y) ** 2) ** 0.5
points = []
while len(points) < NONCOLLINEAR_POINTS:
c = Point(randrange(WINDOW_SIZE), randrange(WINDOW_SIZE))
for a in range(len(points) - 1):
if distance(points[a], c) < CIRCLE_RADIUS*2:
c = None # circles are touching
break
for b in range(a + 1, len(points)):
if distance(points[b], c) < CIRCLE_RADIUS*2:
c = None
break
if collinear(points[a], points[b], c):
c = None
break
else: # no break
continue
break
if c is None:
continue
points.append(c)
win = GraphWin("Visualization", WINDOW_SIZE, WINDOW_SIZE)
circles = []
for point in points:
circle = Circle(point, CIRCLE_RADIUS)
circle.setFill('black')
circle.draw(win)
circles.append(circle)
origin = choice(circles)
origin.setFill('red')
center = origin.getCenter()
line = Line(Point(-WINDOW_SIZE, WINDOW_SIZE/2), Point(WINDOW_SIZE * 2, WINDOW_SIZE/2))
line_center = line.getCenter()
line.move(center.x - line_center.x, center.y - line_center.y)
line.draw(win)
angle = 0
while True:
angle += DELTA
line.undraw()
line = rotateLine(line, angle)
line.draw(win)
for circle in circles:
if circle == origin:
continue
center = circle.getCenter()
if collinear(line.p1, line.p2, center):
origin.setFill('black')
origin = circle
origin.setFill('red')
line_center = line.getCenter()
line.move(center.x - line_center.x, center.y - line_center.y)
break
从随机导入范围,选择
从数学输入罪恶,因为
从图形导入*
非共线_点=6
圆半径=4
窗户尺寸=500
增量=-0.0001#弧度
def旋转线(线,θ):
余弦,正弦=cos(θ),sin(θ)
points=[line.getP1(),line.getP2()]#使用副本,而不是原件!
center=line.getCenter()
对于点到点:
dx,dy=点.x-中心.x,点.y-中心.y
点x=中心x+dx*余弦+dy*正弦
点y=中心y+dy*余弦-dx*正弦
返回线(*点)
def共线(a、b、c):
返回(b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y)<0
def距离(a、b):
回报率((b.x-a.x)**2+(b.y-a.y)**2)**0.5
点数=[]
而len(点)<非共线点:
c=点(随机范围(窗口大小),随机范围(窗口大小))
对于范围内的(透镜(点)-1):
如果距离(点[a],c)<圆半径*2:
c=无#圆圈相互接触
打破
对于范围(a+1,len(点))内的b:
如果距离(点[b],c)<圆半径*2:
c=无
打破
如果共线(点[a],点[b],点c):
c=无
打破
否则:#不许休息
持续
打破
如果c为无:
持续
点。附加(c)
win=图形输入(“可视化”,窗口大小,窗口大小)
圆圈=[]
对于点到点:
圆=圆(点、圆和半径)
圆圈。设置填充(“黑色”)
圈。平局(赢)
圆。追加(圆)
原点=选择(圆)
origin.setFill('red'))
center=origin.getCenter()
直线=直线(点(-WINDOW_SIZE,WINDOW_SIZE/2),点(WINDOW_SIZE*2,WINDOW_SIZE/2))
line\u center=line.getCenter()
移动(center.x-line\u center.x,center.y-line\u center.y)
平局(赢)
角度=0
尽管如此:
角度+=增量
行。未绘制()
直线=旋转线(直线、角度)
平局(赢)
对于圆形中的圆形:
如果圆=原点:
持续
center=circle.getCenter()
如果共线(线p1,线p2,中心):
origin.setFill('黑色')
原点=圆
origin.setFill('red'))
line\u center=line.getCenter()
移动(center.x-line\u center.x,center.y-line\u center.y)
打破
真正的问题是试图随机生成非共线点!这部分代码需要在增加点数之前进行改进
以下是我尝试使用Zelle graphics将您的问题可视化。我的解决方案是使线条的大小为窗口的两倍,并且每次碰到一个点时,重新调整其中心:
from random import randrange, choice
from math import sin, cos
from graphics import *
NONCOLLINEAR_POINTS = 6
CIRCLE_RADIUS = 4
WINDOW_SIZE = 500
DELTA = -0.0001 # in radians
def rotateLine(line, theta):
cosine, sine = cos(theta), sin(theta)
points = [line.getP1(), line.getP2()] # use copies, not originals!
center = line.getCenter()
for point in points:
dx, dy = point.x - center.x, point.y - center.y
point.x = center.x + dx * cosine + dy * sine
point.y = center.y + dy * cosine - dx * sine
return Line(*points)
def collinear(a, b, c):
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y) < 0
def distance(a, b):
return ((b.x - a.x) ** 2 + (b.y - a.y) ** 2) ** 0.5
points = []
while len(points) < NONCOLLINEAR_POINTS:
c = Point(randrange(WINDOW_SIZE), randrange(WINDOW_SIZE))
for a in range(len(points) - 1):
if distance(points[a], c) < CIRCLE_RADIUS*2:
c = None # circles are touching
break
for b in range(a + 1, len(points)):
if distance(points[b], c) < CIRCLE_RADIUS*2:
c = None
break
if collinear(points[a], points[b], c):
c = None
break
else: # no break
continue
break
if c is None:
continue
points.append(c)
win = GraphWin("Visualization", WINDOW_SIZE, WINDOW_SIZE)
circles = []
for point in points:
circle = Circle(point, CIRCLE_RADIUS)
circle.setFill('black')
circle.draw(win)
circles.append(circle)
origin = choice(circles)
origin.setFill('red')
center = origin.getCenter()
line = Line(Point(-WINDOW_SIZE, WINDOW_SIZE/2), Point(WINDOW_SIZE * 2, WINDOW_SIZE/2))
line_center = line.getCenter()
line.move(center.x - line_center.x, center.y - line_center.y)
line.draw(win)
angle = 0
while True:
angle += DELTA
line.undraw()
line = rotateLine(line, angle)
line.draw(win)
for circle in circles:
if circle == origin:
continue
center = circle.getCenter()
if collinear(line.p1, line.p2, center):
origin.setFill('black')
origin = circle
origin.setFill('red')
line_center = line.getCenter()
line.move(center.x - line_center.x, center.y - line_center.y)
break
从随机导入范围,选择
从数学输入罪恶,因为
从图形导入*
非共线_点=6
圆半径=4
窗户尺寸=500
增量=-0.0001#弧度
def旋转线(线,θ):
余弦,正弦=cos(θ),sin(θ)
points=[line.getP1(),line.getP2()]#使用副本,而不是原件!
center=line.getCenter()
对于点到点:
dx,dy=点.x-中心.x,点.y-中心.y
点x=中心x+dx*余弦+dy*正弦
点y=中心y+dy*余弦-dx*正弦
返回线(*点)
def共线(a、b、c):
返回(b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y)<0
def距离(a、b):
回报率((b.x-a.x)**2+(b.y-a.y)**2)**0.5
点数=[]
而len(点)<非共线点:
c=点(随机范围(窗口大小),随机范围(窗口大小))
对于范围内的(透镜(点)-1):
如果距离(点[a],c)<圆半径*2:
c=无#圆圈相互接触
打破
对于范围(a+1,len(点))内的b:
如果距离(点[b],c)<圆半径*2:
c=无
打破
如果共线(点[a],点[b],点c):
c=无
打破
否则:#不许休息
持续