This is the discussion forum for Helix Toolkit.
For bugs and new features, use the issue tracker located at GitHub.
Also try the chat room!
0

Finding intersection point between a PipeVisual3D and ModelVisual3D

Nit29 9 years ago updated 9 years ago 1
Is there a way to find the intersection point of a pipevisual3d and a modelvisual3d element?
0
Under review

3D Surface with Pointcloud

Misunderstood 9 years ago updated 9 years ago 2
Hey,

thanks for that great toolkit! Really like to work with it. Actually i am searching for a way to calculate a 3D surface out of a pointcloud. How am i able to do that? I allready got the points in a list (
The result should be a rectangle with drillholes.

I appreciate any kind of help.
0

BoundingSphere ,RayIntersection implementation ...

Anonymous 10 years ago 0
This discussion was imported from CodePlex

RuiTheAlmeida wrote at 2012-11-29 11:48:

Hi Objo and everybody,

First of all I want to congratulate you for this great Helix 3D tookit


I had to use one of the methods of class BoundingSphere and as it was not implemented so I did it. Feel free to test and include the code I'm sending  here.

Best  Regards,

Rui

 

        public bool RayIntersection(Ray3D ray, out Point3D[] result)
        {
            result = null;
            bool inter = false;
            double h = this.center.X ;
            double j = this.center.Y;
            double k = this.center.Z;
            double ra = this.radius;
            double x1 = ray.Origin.X ;
            double y1 = ray.Origin.Y;
            double z1 = ray.Origin.Z;
            double a = x1 - ray.Origin.X * ray.Direction.X;
            double b = y1 - ray.Origin.Y * ray.Direction.Y;
            double c = z1 - ray.Origin.Z * ray.Direction.Z;
            //Quadratic solving
            double aQ = a * a + b * b + c * c;
            double bQ = 2 * a * (x1 - h) + 2 * b * (y1 - j) + 2 * c * (z1 - k);
            double cQ = x1 * x1 + y1 * y1 + z1 * z1 + h * h + k * k + j * j - 2 * (j * y1 + k * z1 + h * x1) - ra * ra;
            //Dscriminant
            double Q = bQ * bQ - 4 * aQ * cQ;
            if (Q >= 0)
            {
                double rx1 = (-bQ + Math.Sqrt(bQ * bQ - 4 * aQ * cQ)) / (2 * aQ); //First Root
                double rx2 = (-bQ - Math.Sqrt(bQ * bQ - 4 * aQ * cQ)) / (2 * aQ); //Second Root
                //first Intersection
                Point3D I1 = new Point3D(x1 + a * rx1,y1 + b * rx1 , z1 + c * rx1);
                //Second Intersection
                Point3D I2 = new Point3D(x1 + a * rx2, y1 + b * rx2, z1 + c * rx2);
                //ray inside sphere
                if ((ray.Origin - this.center).Length <= this.radius)
                {
                    result = new Point3D[1];
                    //Check if the vectors have the same direction
                    if (Vector3D.DotProduct(ray.Direction, I1 - ray.Origin) >= 0)
                    {
                        result[0] = I1;
                    }
                    else
                    {
                        result[0] = I2;
                    }
                }
                else
                {
                    result = new Point3D[2];
                    result[0] = I1;
                    result[1] = I2;
                }
                inter = true;
            }
            else
            {
                inter = false;
            }
            return inter;
        }


objo wrote at 2012-12-04 19:45:

thanks for the code! Did you make this yourself, or do you have a reference?

I created some unit tests for this code, but could not get my last case (no intersection) to work:

        [Test, Ignore]
        public void RayInterSection_NoIntersections()
        {
            var ray = new Ray3D(new Point3D(0.2, 0.3, 1), new Vector3D(1, 0.1, 0.1));
            var sphere = new BoundingSphere(new Point3D(0.2, 0.3, 0), 1.0);
            Point3D[] result;
            Assert.IsFalse(sphere.RayIntersection(ray, out result));
            Assert.AreEqual(sphere.Radius, sphere.Center.DistanceTo(result[0]), 1e-6, "Point is not on sphere.");
            Assert.AreEqual(0, ray.GetNearest(result[0]).DistanceTo(result[0]), 1e-6, "Point is not on ray.");
        }


RuiTheAlmeida wrote at 2012-12-07 05:12:

Hi objo,

I did the all code myself, and yes I have some references from Wikipedia and other common links that I will give.

I'm also finishing a detailed presentation with the all theoretical stuff, and I will post it all here.

 

Regards,

 

Rui



RuiTheAlmeida wrote at 2012-12-09 19:11:

Hi Objo,

I've made some improvements, and you can find the new code below. I'm also posting some test cases. (I've changed your "no intersections" case )

You can also find my detailed explanation and references here

thanks,

Rui

 

 public bool RayIntersection(Ray3D ray, out Point3D[] result)
        {
            result = new Point3D[2];
            result[0] = new Point3D(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity);
            result[1] = new Point3D(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity);
            bool inter = false;
            double h = this.center.X;
            double j = this.center.Y;
            double k = this.center.Z;
            double ra = this.radius;
            double x1 = ray.Origin.X;
            double y1 = ray.Origin.Y;
            double z1 = ray.Origin.Z;
            //[a,b,c] = Ray.direction
            double a = ray.Direction.X;
            double b = ray.Direction.Y;
            double c = ray.Direction.Z;
            //Quadratic solving
            double aQ = a * a + b * b + c * c;
            double bQ = 2 * a * (x1 - h) + 2 * b * (y1 - j) + 2 * c * (z1 - k);
            double cQ = x1 * x1 + y1 * y1 + z1 * z1 + h * h + k * k + j * j - 2 * (j * y1 + k * z1 + h * x1) - ra * ra;
            //Dscriminant 
            double Q = bQ * bQ - 4 * aQ * cQ;
            if (Q >= 0) //We have at least one possible Intersection
            {
                double rx1 = (-bQ + Math.Sqrt(bQ * bQ - 4 * aQ * cQ)) / (2 * aQ); //First Root
                double rx2 = (-bQ - Math.Sqrt(bQ * bQ - 4 * aQ * cQ)) / (2 * aQ); //Second Root
                //first Possible Intersection
                Point3D I1 = new Point3D(x1 + a * rx1, y1 + b * rx1, z1 + c * rx1);
                //Second Possible Intersection
                Point3D I2 = new Point3D(x1 + a * rx2, y1 + b * rx2, z1 + c * rx2);
                //Check if I1 is intersection by laying in the ray
                if (Vector3D.DotProduct(ray.Direction, I1 - ray.Origin) >= 0)
                {
                    result[0] = I1;
                    inter = true;
                }
                //Check if I2 is intersection by laying in the ray
                if (Vector3D.DotProduct(ray.Direction, I2 - ray.Origin) >= 0)
                {
                    result[1] = I2;
                    inter = true;
                }
            }
            return inter;
        }

 

TESTS:

        [Test]
        public void RayInterSection_HasIntersections()
        {
            var ray = new Ray3D(new Point3D(0.2, 0.3, 0), new Vector3D(1, 0, 0));
            var sphere = new BoundingSphere(new Point3D(0.2, 0.3, 0), 1.0);
            Point3D[] result;
            Assert.IsTrue(sphere.RayIntersection(ray, out result));
            Assert.AreEqual(sphere.Radius, sphere.Center.DistanceTo(result[0]), 1e-6, "Point is not on sphere.");
            Assert.AreEqual(0, ray.GetNearest(result[0]).DistanceTo(result[0]), 1e-6, "Point "+ result[0] +" is not on ray.");
        }

        [Test]
        public void RayInterSection_NoIntersections()
        {
            var ray = new Ray3D(new Point3D(0.2, 0.3, 1), new Vector3D(1, 0.1, 0.1));
            var sphere = new BoundingSphere(new Point3D(0.2, 0.3, 0), 1.0);
            Point3D[] result;
            Assert.IsFalse(sphere.RayIntersection(ray, out result));
            Assert.IsTrue( double.IsInfinity(sphere.Center.DistanceTo(result[0])), "There is a finite solution 1.");
            Assert.AreNotEqual(0, ray.GetNearest(result[0]).DistanceTo(result[0]), "Point 1 is on ray.");
            Assert.IsTrue(double.IsInfinity(sphere.Center.DistanceTo(result[1])), "There is a finite solution 2.");
            Assert.AreNotEqual(0, ray.GetNearest(result[0]).DistanceTo(result[1]), "Point 2 is on ray.");
        }

        [Test]
        public void RayInterSection_TwoIntersections()
        {
            var sphere = new BoundingSphere(new Point3D(0.2, 0.3, 0), 1.0);
            var ray = new Ray3D(new Point3D(12, 23, 32), sphere.Center - new Point3D(12, 23, 32)); // vector away and pointing to the center of sphere
            
            Point3D[] result;
            Assert.IsTrue(sphere.RayIntersection(ray, out result));
            Assert.AreEqual(sphere.Radius, sphere.Center.DistanceTo(result[0]), 1e-6, "Point 1 is not on sphere.");
            Assert.AreEqual(0, ray.GetNearest(result[0]).DistanceTo(result[0]), 1e-6, "Point 1" + result[0] + " is not on ray.");
            Assert.AreEqual(sphere.Radius, sphere.Center.DistanceTo(result[1]), 1e-6, "Point 2 is not on sphere.");
            Assert.AreEqual(0, ray.GetNearest(result[1]).DistanceTo(result[1]), 1e-6, "Point 2 " + result[0] + " is not on ray.");
        }
        [Test]
        public void RayInterSection_OnlyOneIntersection()
        {
            var sphere = new BoundingSphere(new Point3D(0.2, 0.3, 0), 1.0);
            var ray = new Ray3D(sphere.Center, new Vector3D(1, 0.1, 0.1)); // vector origin in the center of sphere pointing away
            Point3D[] result;
            Assert.IsTrue(sphere.RayIntersection(ray, out result), "No intersection");
            Assert.IsTrue(sphere.Center.DistanceTo(ray.Origin ) <= sphere.Radius,"Ray origin outside sphere");
            Assert.IsFalse( double.IsInfinity(sphere.Center.DistanceTo(result[0]))  && double.IsInfinity(sphere.Center.DistanceTo(result[1])), "No Intersections");
            Assert.IsFalse(!double.IsInfinity(sphere.Center.DistanceTo(result[0])) && !double.IsInfinity(sphere.Center.DistanceTo(result[1])), "Two Intersections");   
        }

        [Test]
        public void RayInterSection_TwoTangentIntersections()
        {
            var sphere = new BoundingSphere(new Point3D(0.2, 0.3, 0), 1.0);
            var ray = new Ray3D(new Point3D(sphere.Center.X + sphere.Radius, sphere.Center.Y + sphere.Radius, sphere.Center.Z + 50), new Point3D(sphere.Center.X + sphere.Radius, sphere.Center.Y, sphere.Center.Z) - new Point3D(sphere.Center.X + sphere.Radius, sphere.Center.Y + sphere.Radius, sphere.Center.Z + 50)); // ray tangent to sphere
            Point3D[] result;
            Assert.IsTrue(sphere.RayIntersection(ray, out result), "No intersection");
            Assert.IsTrue(!double.IsInfinity(sphere.Center.DistanceTo(result[0])) && !double.IsInfinity(sphere.Center.DistanceTo(result[1])), "Less then two Intersections");
            Assert.IsTrue(result[0]==result[1], "Solutions are not equal");
        }


objo wrote at 2012-12-13 23:08:

thanks for the unit tests. I have done some modifications and submitted the changes!

0

Image Material with PipeVisual3D

Anonymous 10 years ago 0
This discussion was imported from CodePlex

Mrme wrote at 2014-03-25 10:31:

Hi, so it seems I can add an image as Material for most Visual3Ds if not all, but not for the PipeVisual3D , I use the following code which works just fine with Cube,Ellipsoid,Rectangle Visual3Ds
 PipeVisual3D pi = new PipeVisual3D();
            Material m = MaterialHelper.CreateImageMaterial("E:\\2.jpg", 1, UriKind.Absolute);
            pi.Material = m;
            helix.Children.Add(pi);

objo wrote at 2014-04-29 10:48:


Mrme wrote at 2014-07-24 14:44:

I finally had the time the check the code, I found that the generateTextureCoordinates in the MeshBuilder class constructor was set to false. I checked the source code here on CodePlex and it seems to be fine. you may close the issue here
0

Changing camera type

Anonymous 10 years ago 0
This discussion was imported from CodePlex

ddklo wrote at 2011-03-21 19:10:

Hi.

When I change the camera from a projection camera to a orthographic camera by setting the Orthographic property (after Loaded) on the HelixView3D camera movement is no longer possible. Am I missing something or is this a bug?

 

Regards

Dagfin


ddklo wrote at 2011-04-11 15:10:

Hi.

This issue seemed to be that the Camera property on the CameraController wasn't updated. When I set this manual camera movement works fine. It would be great if this could be the default behavior when changing the Orthographic property, for instance in OnOrthographicChanged in the HelixView3D class.

Regards Dagfinn


objo wrote at 2011-04-12 11:58:

hi Dagfinn, I just changed the CameraController to allow the HelixView3D to change camera. Thanks for the bug report!

0

Earth Scale

Integratron 9 years ago 0

Hi, I'm trying to create an environment on the scale of earth, i.e. the main object is a map of earth and is 40,000,000 units wide, and I have actual scale buildings only 100 units long. It actually seems to work mostly ok but when I zoom in on the buildings, I get odd clipping effects that appear and disappear while I'm panning or orbiting around the buildings. Any ideas on how best to make this display reliably?

0

Tearing zoom or rotation of the shape.

Anonymous 10 years ago 0
This discussion was imported from CodePlex

DongMini wrote at 2012-08-22 10:02:

 

Tearing zoom or rotation of the shape.

Why is that?

 

 

 

Is there anyone able to help me?


objo wrote at 2012-08-24 09:47:

Sorry, I don't understand what you mean here. The figure is also missing.


DongMini wrote at 2012-08-24 11:00:

 

Zoom and Rotation, Capturer the shape of the screen is showing cracks

 

 Left Image

- HelixViewport3D                 windows screencapturer

 

Right Image

- Viewprt3DHelper.Export(HelixViewport3D.Viewport, "d:\sample.png", null);

  capturer image                     sample.png

 

 

 

Sample Image url = http://blog.naver.com/web_mini/50148576494


murray_b wrote at 2012-08-28 03:52:

I thought I would add that I get this problem as well.

It happens a lot for me when zooming into a screen of multiple meshes.

I am very interested to see if you can find a solution

 

 



votecoffee wrote at 2014-02-26 02:25:

You're awesome objo! That fixed it for me.
0

PanoramaCube3D - how to show a skybox

Anonymous 10 years ago 0
This discussion was imported from CodePlex

lightxx wrote at 2013-02-26 13:16:

I'm creating a simple game and want to use a PanoramaCube3D as a skybox for the background.

I know that there's a sample included in the source code but I just can't get it to work using my own skybox images. the problem is the cube always looks like - well - a cube, and there are thin black lines where the sides of the cube meet.

Has anyone ever used the PanoramaCube3D for skyboxing and could provide a sample source code? FYI, there are some free skyboxes over here http://www.3delyvisions.com/skf1.htm

balameeta wrote at 2013-03-25 08:54:

I have recently encountered the same problem as well, and finally solved it.

The solution is as follows:

In your XAML, add this to your HelixViewPort3D:
RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.EdgeMode="Aliased"
Your code should end up looking something like this:
        <ht:HelixViewport3D x:Name="viewPort"  CameraMode="FixedPosition" RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.EdgeMode="Aliased">
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <AmbientLight Color="White"/>
                </ModelVisual3D.Content>
            </ModelVisual3D>

            <ht:PanoramaCube3D Source="Models\GrandHotel\"  >
                
            </ht:PanoramaCube3D>
        </ht:HelixViewport3D>
That should fix the problem. The black lines will disappear completely. You MUST have both the BitmapScalingMode and the EdgeMode set for this to work.

All the best.


Amun

lightxx wrote at 2013-03-25 08:58:

wow. you just so much saved my day .... .i can't believe your awesomenes. thank you so much!!!

balameeta wrote at 2013-03-25 10:06:

No problem. I'm happy to have helped.

All the best for your project!


Amun
0

Gradient fill on 3D objects

Anonymous 10 years ago 0
This discussion was imported from CodePlex

SeanV12 wrote at 2013-06-06 22:46:

How do you go about doing a gradient fill on a tube? My attempts have been unsuccessful and only show the last listed color.
So if anyone can help, how would you give this tube a gradient?

TubeVisual3D tube1 = new TubeVisual3D();
tube1 .Path = new Point3DCollection();
tube1 .Path.Add(new Point3D(0, 0, 0));
tube1 .Path.Add(new Point3D(10, 10, 0));
tube1 .Diameter = 5;

Thanks for reading, and thank you for the toolkit.

objo wrote at 2013-06-07 12:10:

There should be a TextureCoordinates property on the TubeVisual3D. Set the texture coordinates for each point and use a gradient material!
See the StreamLines demo (but this demo uses the MeshBuilder, not the TubeVisual3D).

SeanV12 wrote at 2013-06-08 16:15:

Alright, got it! Thank you very much.

SeanV12 wrote at 2013-06-18 00:22:

Am I correct in understanding that since the TextureCoordinates property only tracks the X values, it's not possible for an object that moves up the Y axis only, with a static X value, to be painted with a gradient?

For reference, what I'm trying to do is to make certain points along a tube's path different colors.

objo wrote at 2013-06-18 22:05:

See MeshBuilder line 1927 where the texture coordinates are defined.
The x-value is set by the specified values (should be normalized 0..1), and the y value corresponds to the position around the tube.

SeanV12 wrote at 2013-06-19 20:37:

Thank you, I will look into this.
Your quick replies are much appreciated, by the way!
0

Can you provide 'snapping' for Manipulators ?

Anonymous 10 years ago 0
This discussion was imported from CodePlex

Aybe wrote at 2013-09-14 19:00:

Can you provide a 'snap to grid' feature for Manipulators in a future release ?

Thank you.

Best regards


Aybe wrote at 2013-09-25 16:37:

Awesome, thank you !