PDA

View Full Version : Create an arc between two points

hotshotiguana
03-22-2012, 09:11 AM
I have two x, z points - for example ([1.722, .46], [3.94, .026]) - and I am trying to draw an arc (or a great (or small) circle) between the two points. I also have calculated 50 control x, z points between the points if this is beneficial to the solution.

Currently, I am using viz.LINE_STRIP to create about 50 line segments between the two points and it doesn't look at all.

Thanks,
Chris

farshizzo
03-22-2012, 10:11 AM
What exactly is wrong with your current solution? Is the arc not smooth enough? If so, you will just need to create more control points.

hotshotiguana
03-22-2012, 10:44 AM
I am not calculating the y-values correctly. When drawn, it looks like a staircase between the two points.

farshizzo
03-22-2012, 10:56 AM
Can you post some sample code?

hotshotiguana
03-22-2012, 11:28 AM
So I transferred some Matlab code into Python and then did a 3D plot, see below code.

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

def get_sphere_line(center, pt_1, pt_2):
"""
Get the coordinates to craft an arc
"""
x0, y0, z0 = center
x1, y1, z1 = pt_1
x2, y2, z2 = pt_2
v1 = [x1 - x0, y1 - y0, z1 - z0] # Vector from center to 1st point
r = np.linalg.norm(v1) # The radius
v2 = [x2 - x0, y2 - y0, z2 - z0] # Vector from center to 2nd point
v3 = np.cross(np.cross(v1, v2), v1) # v3 lies in plane of v1 & v2 and is orthog. to v1
v3 = r*v3/np.linalg.norm(v3) # Make v3 of length r
# Let t range through the inner angle between v1 and v2
t = np.linspace(0, np.arctan2(np.linalg.norm(np.cross(v1, v2)), np.dot(v1, v2)), num=100)[:, np.newaxis].T
v = np.array(v1)[:, np.newaxis]*np.cos(t) + np.array(v3)[:, np.newaxis]*np.sin(t) # v traces great circle path, relative to center
xs, ys, zs = v[0, :] + x0, v[1, :] + y0, v[2, :] + z0
return xs, ys, zs
xs, ys, zs = get_sphere_line([2.85, 0.001, 0.238], [1.722, .001, .46], [3.94, 0.001, 0.026])
fig = plt.figure()
ax.plot(xs, ys, zs)
plt.show()

The below code is how I am trying to implement it in Vizard, but it isn't working properly.

vs = get_sphere_line([2.85, 0.001, 0.238], [1.722, .001, .46], [3.94, .001, 0.026])
viz.startLayer(viz.LINE_STRIP)
viz.lineWidth(5)
viz.vertexColor(viz.YELLOW)
for v in vs:
viz.vertex([v[0], v[1], v[2]])
viz.endLayer()

hotshotiguana
03-22-2012, 12:07 PM
I found the problem, here is my solution in Vizard:
xs, ys, zs = get_sphere_line([2.85, -1., 0.238], [1.722, .001, .46],
[3.94, .001, 0.026])
viz.startLayer(viz.LINE_STRIP)
viz.lineWidth(5)
viz.pointSize(5)
viz.vertexColor(viz.YELLOW)
for pos in zip(xs, ys, zs):
viz.vertex([pos[0], pos[1], pos[2]])
points = viz.endLayer()