I draw two spheres in 3d WPF which has points like Point3D(0,0,0) and Point3D(-1.0,1.0,2.0) with the radius is 0.10
Now i want to draw a Cylinder joining these spheres, the only thing i have for this is radius 0.02. I want to know how to calculate the 3d point, height, direction etc for this cylinder.
I tried by finding the midpoint btw sphere points, it's placing the cylinder in the middle of those two spheres but not in the right direction. I want to rotate the cylinder in the right angle. I used Vector3D.angleBetween(v1,v2) to find the angle it's giving me "NaN". I put the code which i am using in below.
Vector3D v1 = new Vector3D(0, 0, 0);
Vector3D v2 = new Vector3D(1.0, -1.0, 2.0);
Vector3D center = v1+ v2/2;
Vector3D axis = Vector3D.CrossProduct(v1, v2);
double angle = Vector3D.AngleBetween(v1, v2);
AxisAngleRotation3D axisAngle = new AxisAngleRotation3D(axis, angle);
RotateTransform3D myRotateTransform = new RotateTransform3D(axisAngle, center);
center.X = myRotateTransform.CenterX;
center.Y = myRotateTransform.CenterY;
center.Z = myRotateTransform.CenterZ;
[EDIT]
First of all thank you so much for the response. I am having some issues with this code it's working good with your example. but with my points It's not drawing the cylinder btw the two circle points in a right direction and also not until the end point (it's only connecting to second point) One more thing, if the mid point of the Z-axis is (midpoint.Z = 0), it not even drawing the cylinder.
I am just wondering, is it because of the way i am drawing my circle. Please take a look
public ModelVisual3D CreateSphere(Point3D center, double radius, int u, int v, Color color)
{
Model3DGroup spear = new Model3DGroup();
if (u < 2 || v < 2)
return null;
Point3D[,] pts = new Point3D[u, v];
for (int i = 0; i < u; i++)
{
for (int j = 0; j < v; j++)
{
pts[i, j] = GetPosition(radius,
i * 180 / (u - 1), j * 360 / (v - 1));
pts[i, j] += (Vector3D)center;
}
}
Point3D[] p = new Point3D[4];
for (int i = 0; i < u - 1; i++)
{
for (int j = 0; j < v - 1; j++)
{
p[0] = pts[i, j];
p[1] = pts[i + 1, j];
p[2] = pts[i + 1, j + 1];
p[3] = pts[i, j + 1];
spear.Children.Add(CreateTriangleModel(p[0], p[1], p[2], color));
spear.Children.Add(CreateTriangleModel(p[2], p[3], p[0], color));
}
}
ModelVisual3D model = new ModelVisual3D();
model.Content = spear;
return model;
}
private Point3D GetPosition(double radius, double theta, double phi)
{
Point3D pt = new Point3D();
double snt = Math.Sin(theta * Math.PI / 180);
double cnt = Math.Cos(theta * Math.PI / 180);
double snp = Math.Sin(phi * Math.PI / 180);
double cnp = Math.Cos(phi * Math.PI / 180);
pt.X = radius * snt * cnp;
pt.Y = radius * cnt;
pt.Z = -radius * snt * snp;
return pt;
}
public Model3DGroup CreateTriangleFace(Point3D p0, Point3D p1, Point3D p2, Color color)
{
MeshGeometry3D mesh = new MeshGeometry3D();
mesh.Positions.Add(p0);
mesh.Positions.Add(p1);
mesh.Positions.Add(p2);
mesh.TriangleIndices.Add(0);
mesh.TriangleIndices.Add(1);
mesh.TriangleIndices.Add(2);
Vector3D normal = VectorHelper.CalcNormal(p0, p1, p2);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
Material material = new DiffuseMaterial(new SolidColorBrush(color));
GeometryModel3D model = new GeometryModel3D(mesh, material);
Model3DGroup group = new Model3DGroup();
group.Children.Add(model);
return group;
}
private class VectorHelper
{
public static Vector3D CalcNormal(Point3D p0, Point3D p1, Point3D p2)
{
Vector3D v0 = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
Vector3D v1 = new Vector3D( p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z);
return Vector3D.CrossProduct(v0, v1);
}
}
almost same as your code>
my sample point are :
p1 = Point3D(0,0,0)
p2= Point3D(-1.0, 1.0, 2.0)
p3= Point3D(-1.0, 1.0, 2.0)
p4 =Point3D(1.0, -1.0, 2.0)
i want to draw cylinders btw p1 to p2 ,p1 to p3, p1 to p4 p2 to p3 , p2 to p4
Please Let me know if you need any more clarification, I have to get this out. Thanks for all your time.
I don't know whether this will be of use to you, but you commented on some similar code I recently posted, asking for assistance - so I thought I'd convert that code into two objects, connected by a cylinder spinning around in 3D space - the Init() method takes two points, creates 10x10x10 cubes at the points and then connects them with a cylinder.
I think this is roughly what your trying to achieve, though I admit that my example is a little contrived, (you can only change the Z axis on each of the two points in!!!), but hopefully you'll get something from it!
Sorry the code is a bit of a mess but I've compiled it from a number of my classes to get it into one easy cut and paste-able lump!
Anyway, hope this helps ...
Heres the XAML ... this just sets up the ViewPort and light source ...
... and heres the code behind ...
heres some more code - i think i've found a solution for you ...
Again, its a cobbled together example you'll have to refine.
Please note that the transform code has changed dramatically, i'm only just getting to grips with WPF 3D myself and i've realised I was doing quite a few things wrong. I was recreating the Transform3DGroup each time instead of just changing the angle of the Transform that was already applied.
Have a look at the code and note the altTransform group - what i'm doing is adding an extra transfomation to this alt group. I've then used the altTransform on a cylinder and sphere that would otherwise be in same position as one of the other cylinders and spheres. I've marked this cylinder green so that you can see which one it is.
My suggestion to you is that you create all your spheres and cylinders on the same axis and then transform them to your desired location.
I've also changed the sphere and cylinder sizes to what you requested in an earlier comment.
Have a look at the code and see what you think?
Cheers,
Andy
and heres the code behind ...
I've integrated your sphere code with my example and it works fine - the cylinder connects both spheres.
Heres the code ...
Cheers, Andy
ViewPort as before ...
... and heres the code behind ...
}