I have gotten as far as making a set of rays, but I need to connect them. Any help? My code is as follows
from math import *
from graphics import *
i = 1
segments = 15
lastPoint = Point(100,0)
print("Begin")
win = GraphWin("Trigonometry", 1500, 1500)
while i<=segments:
angle =i*pi/segments
y = int(sin(angle)*100)
x = int(cos(angle)*100)
i = i+1
p = Point(x,y)
l = Line(p, lastPoint)
l.draw(win)
print(p.x, p.y)
print("End")
OP code draws only "rays" because, while point p lays on the circle, lastPoint doesn't change between iterations.
We have to update the value of lastPoint to literally the last point calculated in order to draw the arc as a series of consecutive segments.
Here is a modified code, with further explanations as asked by OP in his comment:
from math import *
from graphics import *
# Function to calculate the integer coordinates of a Point on a circle
# given the center (c, a Point), the radius (r) and the angle (a, radians)
def point_on_circle( c, r, a ) :
return Point( int(round(c.x + r*cos(a))), int(round(c.y + r*sin(a))) )
# Define the graphical output window, I'll set the coordinates system so
# that the origin is the bottom left corner of the windows, y axis is going
# upwards and 1 unit corresponds to 1 pixel
win = GraphWin("Trigonometry", 800, 600)
win.setCoords(0,0,800,600)
# Arc data. Angles are in degrees (more user friendly, but later will be
# transformed in radians for calculations), 0 is East, positive values
# are counterclockwise. A value of 360 for angle_range_deg gives a complete
# circle (polygon).
angle_start_deg = 0
angle_range_deg = 90
center = Point(10,10)
radius = 200
segments = 16
angle_start = radians(angle_start_deg)
angle_step = radians(angle_range_deg) / segments
# Initialize lastPoint with the position corresponding to angle_start
# (or i = 0). Try different values of all the previous variables
lastPoint = point_on_circle(center, radius, angle_start)
print("Begin")
i = 1
while i <= segments :
# update the angle to calculate a new point on the circle
angle = angle_start + i * angle_step
p = point_on_circle(center, radius, angle)
# draw a line between the last two points
l = Line(p, lastPoint)
l.draw(win)
print(p.x, p.y)
# update the variables to move on to the next segment which share an edge
# (the last point) with the previous segment
i = i + 1
lastPoint = p
print("End")
Related
I wanna convert this shape to triangles mesh using shapely in order to be used later as a 3d surface in unity3d, but the result seems is not good, because the triangles mesh cover areas outside this shape.
def get_complex_shape(nb_points = 10):
nb_shifts = 2
nb_lines = 0
shift_parameter = 2
r = 1
xy = get_points(0, 0, r, nb_points)
xy = np.array(xy)
shifts_indices = np.random.randint(0, nb_points ,nb_shifts) # choose random points
if(nb_shifts > 0):
xy[shifts_indices] = get_shifted_points(shifts_indices, nb_points, r + shift_parameter, 0, 0)
xy = np.append(xy, [xy[0]], axis = 0) # close the circle
x = xy[:,0]
y = xy[:,1]
if(nb_lines < 1): # normal circles
tck, u = interpolate.splprep([x, y], s=0)
unew = np.arange(0, 1.01, 0.01) # from 0 to 1.01 with step 0.01 [the number of points]
out = interpolate.splev(unew, tck) # a circle of 101 points
out = np.array(out).T
else: # lines and curves
out = new_add_random_lines(xy, nb_lines)
return out
enter code here
data = get_complex_shape(8)
points = MultiPoint(data)
union_points = cascaded_union(points)
triangles = triangulate(union_points)
This link is for the picture:
the blue picture is the polygon that I want to convert it to mesh of triangles, the right picture is the mesh of triangles which cover more than the inner area of the polygon. How could I cover just the inner area of the polygon?
My aim is to make the image1 move along the ring from its current position upto 180 degree. I have been trying to do different things but nothing seem to work. My final aim is to move both the images along the ring in different directions and finally merge them to and make them disappear.I keep getting the error above.Can you please help? Also can you tell how I can go about this problem?
from visual import *
import numpy as np
x = 3
y = 0
z = 0
i = pi/3
c = 0.120239 # A.U/minute
r = 1
for theta in arange(0, 2*pi, 0.1): #range of theta values; 0 to
xunit = r * sin(theta)*cos(i) +x
yunit = r * sin(theta)*sin(i) +y
zunit = r*cos(theta) +z
ring = curve( color = color.white ) #creates a curve
for theta in arange(0, 2*pi, 0.01):
ring.append( pos=(sin(theta)*cos(i) +x,sin(theta)*sin(i) +y,cos(theta) +z) )
image1=sphere(pos=(2.5,-0.866,0),radius=0.02, color=color.yellow)
image2=sphere(pos=(2.5,-0.866,0),radius=0.02, color=color.yellow)
earth=sphere(pos=(-3,0,-0.4),color=color.yellow, radius =0.3,material=materials.earth) #creates the observer
d_c_p = pow((x-xunit)**2 + (y-yunit)**2 + (z-zunit)**2,0.5) #calculates the distance between the center and points on ring
d_n_p = abs(yunit + 0.4998112152755791) #calculates the distance to the nearest point
t1 = ( d_c_p+d_n_p)/c
t0=d_c_p/c
t=t1-t0 #calculates the time it takes from one point to another
theta = []
t = []
dtheta = np.diff(theta) #calculates the difference in theta
dt = np.diff(t) #calculates the difference in t
speed = r*dtheta/dt #hence this calculates the speed
deltat = 0.005
t2=0
while True:
rate(5)
image2.pos = image2.pos + speed*deltat #increments the position of the image1
t2 = t2 + deltat
Your problem is that image2.pos is a vector (that's the "3" in the error message) but speed*deltat is a scalar (that's the "0" in the error message). You can't add a vector and a scalar. Instead of a scalar "speed" you need a vector velocity. There seem to be some errors in indentation in the program you posted, so there is some possibility I've misinterpreted what you're trying to do.
For VPython questions it's better to post to the VPython forum, where there are many more VPython users who will see your question than if you post to stackoverflow:
https://groups.google.com/forum/?fromgroups&hl=en#!forum/vpython-users
I want to make a program which plots a Sierpinsky triangle (of any modulo). In order to do it I've used TkInter. The program generates the fractal by moving a point randomly, always keeping it in the sides. After repeating the process many times, the fractal appears.
However, there's a problem. I don't know how to plot points on a canvas in TkInter. The rest of the program is OK, but I had to "cheat" in order to plot the points by drawing small lines instead of points. It works more or less, but it doesn't have as much resolution as it could have.
Is there a function to plot points on a canvas, or another tool to do it (using Python)? Ideas for improving the rest of the program are also welcome.
Thanks. Here's what I have:
from tkinter import *
import random
import math
def plotpoint(x, y):
global canvas
point = canvas.create_line(x-1, y-1, x+1, y+1, fill = "#000000")
x = 0 #Initial coordinates
y = 0
#x and y will always be in the interval [0, 1]
mod = int(input("What is the modulo of the Sierpinsky triangle that you want to generate? "))
points = int(input("How many points do you want the triangle to have? "))
tkengine = Tk() #Window in which the triangle will be generated
window = Frame(tkengine)
window.pack()
canvas = Canvas(window, height = 700, width = 808, bg = "#FFFFFF") #The dimensions of the canvas make the triangle look equilateral
canvas.pack()
for t in range(points):
#Procedure for placing the points
while True:
#First, randomly choose one of the mod(mod+1)/2 triangles of the first step. a and b are two vectors which point to the chosen triangle. a goes one triangle to the right and b one up-right. The algorithm gives the same probability to every triangle, although it's not efficient.
a = random.randint(0,mod-1)
b = random.randint(0,mod-1)
if a + b < mod:
break
#The previous point is dilated towards the origin of coordinates so that the big triangle of step 0 becomes the small one at the bottom-left of step one (divide by modulus). Then the vectors are added in order to move the point to the same place in another triangle.
x = x / mod + a / mod + b / 2 / mod
y = y / mod + b / mod
#Coordinates [0,1] converted to pixels, for plotting in the canvas.
X = math.floor(x * 808)
Y = math.floor((1-y) * 700)
plotpoint(X, Y)
tkengine.mainloop()
If you are wanting to plot pixels, a canvas is probably the wrong choice. You can create a PhotoImage and modify individual pixels. It's a little slow if you plot each individual pixel, but you can get dramatic speedups if you only call the put method once for each row of the image.
Here's a complete example:
from tkinter import *
import random
import math
def plotpoint(x, y):
global the_image
the_image.put(('#000000',), to=(x,y))
x = 0
y = 0
mod = 3
points = 100000
tkengine = Tk() #Window in which the triangle will be generated
window = Frame(tkengine)
window.pack()
the_image = PhotoImage(width=809, height=700)
label = Label(window, image=the_image, borderwidth=2, relief="raised")
label.pack(fill="both", expand=True)
for t in range(points):
while True:
a = random.randint(0,mod-1)
b = random.randint(0,mod-1)
if a + b < mod:
break
x = x / mod + a / mod + b / 2 / mod
y = y / mod + b / mod
X = math.floor(x * 808)
Y = math.floor((1-y) * 700)
plotpoint(X, Y)
tkengine.mainloop()
You can use canvas.create_oval with the same coordinates for the two corners of the bounding box:
from tkinter import *
import random
import math
def plotpoint(x, y):
global canvas
# point = canvas.create_line(x-1, y-1, x+1, y+1, fill = "#000000")
point = canvas.create_oval(x, y, x, y, fill="#000000", outline="#000000")
x = 0 #Initial coordinates
y = 0
#x and y will always be in the interval [0, 1]
mod = int(input("What is the modulo of the Sierpinsky triangle that you want to generate? "))
points = int(input("How many points do you want the triangle to have? "))
tkengine = Tk() #Window in which the triangle will be generated
window = Frame(tkengine)
window.pack()
canvas = Canvas(window, height = 700, width = 808, bg = "#FFFFFF") #The dimensions of the canvas make the triangle look equilateral
canvas.pack()
for t in range(points):
#Procedure for placing the points
while True:
#First, randomly choose one of the mod(mod+1)/2 triangles of the first step. a and b are two vectors which point to the chosen triangle. a goes one triangle to the right and b one up-right. The algorithm gives the same probability to every triangle, although it's not efficient.
a = random.randint(0,mod-1)
b = random.randint(0,mod-1)
if a + b < mod:
break
#The previous point is dilated towards the origin of coordinates so that the big triangle of step 0 becomes the small one at the bottom-left of step one (divide by modulus). Then the vectors are added in order to move the point to the same place in another triangle.
x = x / mod + a / mod + b / 2 / mod
y = y / mod + b / mod
#Coordinates [0,1] converted to pixels, for plotting in the canvas.
X = math.floor(x * 808)
Y = math.floor((1-y) * 700)
plotpoint(X, Y)
tkengine.mainloop()
with a depth of 3 and 100,000 points, this gives:
Finally found a solution: if a 1x1 point is to be placed in pixel (x,y), a command which does it exactly is:
point = canvas.create_line(x, y, x+1, y+1, fill = "colour")
The oval is a good idea for 2x2 points.
Something remarkable about the original program is that it uses a lot of RAM if every point is treated as a separate object.
Hey guys so I have a question. I would like to draw a circle in python pixel by pixel but I can't seem to get it.
It was a question we talked about in my programming class today and my teacher said it was possible by using the distance formula to find the distance between the center of the window and the points on the outside of the circle and then just telling the program to fill it in if it fits that case.
So this is not homework, purely for my own curiosity. I have been working on it for hours and I feel like I am close but definitely missing a key element.
My goal is to put a red circle in the middle of the window, which has a width and height between 300 and 400.
I said that the center point is = to (w/2, h/2) and I want to fill in every point that is a fixed distance away from that.
I chose (100, 50) as a random point that would be on the circle and then set the variable distance = to the distance formula using those previous two points.
The two for-loops are there to iterate over every pixel in the window. I was able to create a box right where I want my circle... But I can't seem to get anything close to a circle to appear
here is my code, I named my function Japanese flag as it seemed appropriate:
import cImage
import math
def japanese_flag(w, h):
newimg = EmptyImage(w, h)
distance = int(math.sqrt((50 - h / 2) ** 2 + (100 - w / 2) ** 2))
for col in range(w):
for row in range(h):
if h/2 - distance < row < (h/2 + distance) and w / 2 - distance < col < (w / 2 + distance):
newpixel = Pixel(255, 0, 0) # this denotes the color red
newimg.setPixel(col, row, newpixel)
return newimg
def show_one_flag(func_name):
import random
width = random.randint(300, 400)
height = random.randint(200, 300)
win = ImageWin(str(func_name),width,height)
newimg = func_name(width, height)
newimg.draw(win)
show_one_flag(japanese_flag)
Use squared radius for simpler comparison
SqDist = (50 - h / 2) ** 2 + (100 - w / 2) ** 2
To draw only circumference, compare with some tolerance level
Eps = 1
...
if (Math.Abs((h/2 - row) ** 2 + (w/2 - col) ** 2 - SqDist) < Eps)
draw pixel
To draw filled circle:
if ((h/2 - row) ** 2 + (w/2 - col) ** 2 < SqDist)
draw pixel
I have three coordinates (lat,lon) on a sphere. If you would rotate the whole sphere from coord1 to coord2, where will coord3 now be located?
I've been trying this out in Python using Great Circle (http://www.koders.com/python/fid0A930D7924AE856342437CA1F5A9A3EC0CAEACE2.aspx?s=coastline) but I create strange results as the newly calculated points all group together at the equator. That must have something to do with the azimuth calculation I assume?
Does anyone maybe know how to calculate this correctly?
Thanks in advance!
EDIT
I found the following: http://www.uwgb.edu/dutchs/mathalgo/sphere0.htm
I guess I now need to calculate the rotation axis and the rotation angle from the two points in cartesian coords (and 0,0,0)? I guess this must be very simple, something to do with defining a plane and determining the normal line? Does someone maybe know where I can find the needed equations?
EDIT 2
Coord1 and coord2 make a great circle. Is there an easy way to find the location of the great circle normal axis on the sphere?
EDIT 3
Looks like I was able to solve it ;)
http://articles.adsabs.harvard.edu//full/1953Metic...1...39L/0000039.000.html did the trick.
Ok I don't know the exactly formula, I believe it would be a simple matrix multiplication but here's how you can figure out without it.
Transform coordinates so that the poles of the rotation are at 90,0 and -90,0 respectively and so that the line along your rotation from coord1 to coord2 is then on the "equator" (this should be simply delta lat, delta long)
then the rotation is just change in longitude and you can apply the same delta long to any coord3, then simply transform back to the original coordinates (via negative delta lat and negative delta long)
1 & 2 are pretty much what your matrix would do - if you can figure out the matrices for each step, you can just multiply them and get the final matrix
Using Visual Python I think I now have solved it:
# Rotation first described for geo purposes: http://www.uwgb.edu/dutchs/mathalgo/sphere0.htm
# http://stackoverflow.com/questions/6802577/python-rotation-of-3d-vector
# http://vpython.org/
from visual import *
from math import *
import sys
def ll2cart(lon,lat):
# http://rbrundritt.wordpress.com/2008/10/14/conversion-between-spherical-and-cartesian-coordinates-systems/
x = cos(lat) * cos(lon)
y = cos(lat) * sin(lon)
z = sin(lat)
return x,y,z
def cart2ll(x,y,z):
# http://rbrundritt.wordpress.com/2008/10/14/conversion-between-spherical-and-cartesian-coordinates-systems/
r = sqrt((x**2) + (y**2) + (z**2))
lat = asin(z/r)
lon = atan2(y, x)
return lon, lat
def distance(lon1, lat1, lon2, lat2):
# http://code.activestate.com/recipes/576779-calculating-distance-between-two-geographic-points/
# http://en.wikipedia.org/wiki/Haversine_formula
dlat = lat2 - lat1
dlon = lon2 - lon1
q = sin(dlat/2)**2 + (cos(lat1) * cos(lat2) * (sin(dlon/2)**2))
return 2 * atan2(sqrt(q), sqrt(1-q))
if len(sys.argv) == 1:
sys.exit()
else:
csv = sys.argv[1]
# Points A and B defining the rotation:
LonA = radians(float(sys.argv[2]))
LatA = radians(float(sys.argv[3]))
LonB = radians(float(sys.argv[4]))
LatB = radians(float(sys.argv[5]))
# A and B are both vectors
# The crossproduct AxB is the rotation pole vector P:
Ax, Ay, Az = ll2cart(LonA, LatA)
Bx, By, Bz = ll2cart(LonB, LatB)
A = vector(Ax,Ay,Az)
B = vector(Bx,By,Bz)
P = cross(A,B)
Px,Py,Pz = P
LonP, LatP = cart2ll(Px,Py,Pz)
# The Rotation Angle in radians:
# http://code.activestate.com/recipes/576779-calculating-distance-between-two-geographic-points/
# http://en.wikipedia.org/wiki/Haversine_formula
RotAngle = distance(LonA,LatA,LonB,LatB)
f = open(csv,"r")
o = open(csv[:-4] + "_translated.csv","w")
o.write(f.readline())
for line in f:
(lon, lat) = line.strip().split(",")
# Point C which will be translated:
LonC = radians(float(lon))
LatC = radians(float(lat))
# Point C in Cartesian coordinates:
Cx,Cy,Cz = ll2cart(LonC,LatC)
C = vector(Cx,Cy,Cz)
# C rotated to D:
D = rotate(C,RotAngle,P)
Dx,Dy,Dz = D
LonD,LatD = cart2ll(Dx,Dy,Dz)
o.write(str(degrees(LonD)) + "," + str(degrees(LatD)) + "\n")