שתף באמצעות


How to calculate a point on a plane based on a plane from 3 points.

Question

Saturday, August 22, 2015 2:35 PM | 1 vote

I need to calc the z coordinate of a point (x,y) on a plane through 3 points (x1,y1,z1)... (x3,y3,z3)

I see many ways to derive the equation of the plane from the 3 points by solving simulatious equations using the 3 points. Now I need to code that in VB.net so that from the 3 points I get the equation of the plane and then I can sub my point(x,y) into the equation to get z at that point.

Does anyone have a vb.net code sample for solving this in any way?

Thanks,

Tom

All replies (11)

Saturday, August 22, 2015 3:18 PM ✅Answered | 3 votes

If I have correctly understood the methodology, I think you can use the following class

Imports System.Windows.Forms.DataVisualization.Charting

Public Class Plane
    Private abc As Point3D, d As Single

    Sub New(p1 As Point3D, p2 As Point3D, p3 As Point3D)
        'Create 2 vectors by subtracting p3 from p1 and p2
        Dim v1 As Point3D = New Point3D(p1.X - p3.X, p1.Y - p3.Y, p1.Z - p3.Z)
        Dim v2 As Point3D = New Point3D(p2.X - p3.X, p2.Y - p3.Y, p2.Z - p3.Z)

        'Create cross product from the 2 vectors
        abc = New Point3D(v1.Y * v2.Z - v1.Z * v2.Y, v1.Z * v2.X - v1.X * v2.Z, v1.X * v2.Y - v1.Y * v2.X)

        'find d in the equation aX + bY + cZ = d
        d = abc.X * p3.X + abc.Y * p3.Y + abc.Z * p3.Z
    End Sub

    Function GetZValue(x As Single, y As Single) As Single
        Return (d - abc.X * x - abc.Y * y) / abc.Z
    End Function
End Class

Note that, for convenience, I used the Point3D class which requires a reference to System.Windows.Forms.DataVisualization.

You can create an instance of the Plane class by passing three Point3D objects to the constructor. Then you can get the Z value for any (X, Y) value by calling the GetZValue function.


Saturday, August 22, 2015 3:03 PM | 1 vote

I don't really understand the question.

Points, lines, and planes

La vida loca


Saturday, August 22, 2015 3:11 PM

I don't really understand the question.

Points, lines, and planes

La vida loca

Hi Monkey!

Well you can see in your link that you can get the equation of a plane from 3 points doing this:

The standard equation of a plane in 3 space is

Ax + By + Cz + D = 0

The normal to the plane is the vector (A,B,C).

Given three points in space (x1,y1,z1), (x2,y2,z2), (x3,y3,z3) the equation of the plane through these points is given by the following determinants.

Expanding the above gives
** A = y1 (z2 - z3) + y2 (z3 - z1) + y3 (z1 - z2)**
** B = z1 (x2 - x3) + z2 (x3 - x1) + z3 (x1 - x2)**
** C = x1 (y2 - y3) + x2 (y3 - y1) + x3 (y1 - y2)**
** - D = x1 (y2 z3 - y3 z2) + x2 (y3 z1 - y1 z3) + x3 (y1 z2 - y2 z1)**

And then if you have the equation in this form (Ax + By + Cz + D = 0) you isolate z and given another point (x,y) solve to the z coordinate on the plane for that point.

Having A, B, C solved out like in the last paragraph is a big help I can prob do that now. I was just tired of re-inventing the wheel so was hoping someone might already have a working vb.net code routine for it.


Saturday, August 22, 2015 3:22 PM

If I have correctly understood the methodology, I think you can use the following

Private abc As Point3D, d As Single

Sub GetEquation(p1 As Point3D, p2 As Point3D, p3 As Point3D)
    'Create 2 vectors by subtracting p3 from p1 and p2
    Dim v1 As Point3D = New Point3D(p1.X - p3.X, p1.Y - p3.Y, p1.Z - p3.Z)
    Dim v2 As Point3D = New Point3D(p2.X - p3.X, p2.Y - p3.Y, p2.Z - p3.Z)

    'Create cross product from the 2 vectors
    abc = New Point3D(v1.Y * v2.Z - v1.Z * v2.Y, v1.Z * v2.X - v1.X * v2.Z, v1.X * v2.Y - v1.Y * v2.X)

    'find d in the equation aX + bY + cZ = d
    d = abc.X * p3.X + abc.Y * p3.Y + abc.Z * p3.Z
End Sub

Function GetZValue(x As Single, y As Single) As Single
    Return (d - abc.X * x - abc.Y * y) / abc.Z
End Function

You can call the GetEquation method one time with the three points, then you can call GetZValue multiple times to get the Z value for a point at (X, Y) on the plane.

Note that for convenience I used the Point3D class which needs a reference to System.Windows.Forms.DataVisualization. To avoid having to fully qualify references to Point3D, I also added

Imports System.Windows.Forms.DataVisualization.Charting

Blackwood,

That's what I am talking about. Give me some time to try it out today...

I am not up on my vb.net vector math but this is a good one to practice on.


Saturday, August 22, 2015 3:40 PM | 1 vote

Note that I edited my answer to put the code in a class. I thought it was possible you might need to work with more than one plane.


Saturday, August 22, 2015 4:58 PM | 2 votes

Note that I edited my answer to put the code in a class. I thought it was possible you might need to work with more than one plane.

Ok got it working. I had to make my own point3d as it appears chart.visualizations is .net 4 and I am using 3.5. What I use it for at the moment is locating the base of my trees on the 3d surface mesh made of triangles. I dont know if you can see it in this image. And here is the code.

    Structure point3d
        Public x As Single
        Public y As Single
        Public z As Single
    End Structure   Public Function GetPointOnPlaneZ(p1 As point3d, p2 As point3d, p3 As point3d, x As Single, y As Single) As Single
        'call with 3 points p1, p2, p3 that form plane and another point (x,y)
        'returns Z for point (x,y) on plane from 3 points

        Dim v1, v2, abc As point3d

        'Create 2 vectors by subtracting p3 from p1 and p2
        v1.x = p1.x - p3.x
        v1.y = p1.y - p3.y
        v1.z = p1.z - p3.z

        v2.x = p2.x - p3.x
        v2.y = p2.y - p3.y
        v2.z = p2.z - p3.z

        'Create cross product from the 2 vectors
        abc.x = v1.y * v2.z - v1.z * v2.y
        abc.y = v1.z * v2.x - v1.x * v2.z
        abc.z = v1.x * v2.y - v1.y * v2.x

        'find d in the equation aX + bY + cZ = d
        Dim d As Single = abc.x * p3.x + abc.y * p3.y + abc.z * p3.z

        'calc z coordinate for point (x,y)
        GetPointOnPlaneZ = (d - abc.x * x - abc.y * y) / abc.z

    End Function

Saturday, August 22, 2015 11:35 PM

@ Tom,

 Pretty cool !!!  It looks like the 3D trees for Cadrail are coming along pretty good.  Now all you need to do is use the system time to calculate the shadows on the ground from the trees.  haha,  just joking.  Looking good Tom !!    8)

If you say it can`t be done then i`ll try it


Saturday, August 22, 2015 11:59 PM

@ Tom,

 Pretty cool !!!  It looks like the 3D trees for Cadrail are coming along pretty good.  Now all you need to do is use the system time to calculate the shadows on the ground from the trees.  haha,  just joking.  Looking good Tom !!    8)

If you say it can`t be done then i`ll try it

Thanks Razerz.

Sure is nice having you all to answer questions on this forum!


Sunday, August 23, 2015 9:46 AM

Hi,

Tommy and Blackwood,

I think you should normalize the normal vector: |n| = 1 (unit normal vector)

[The vector returned by the cross-product should have the length of 1]

https://en.wikipedia.org/wiki/Hesse_normal_form

Regards,

  Thorsten


Sunday, August 23, 2015 1:25 PM | 1 vote

Hi,

Tommy and Blackwood,

I think you should normalize the normal vector: |n| = 1 (unit normal vector)

[The vector returned by the cross-product should have the length of 1]

https://en.wikipedia.org/wiki/Hesse_normal_form

Regards,

  Thorsten

Thorsten,

It seems to work fine the way it is, without normalizing?

I normalized using this code seems to work. But it seems to work without it?

    Public Function GetPointOnPlaneZ(p1 As point3d, p2 As point3d, p3 As point3d, x As Single, y As Single) As Single
        'call with 3 points p1, p2, p3 that form plane and another point (x,y)
        'returns Z for point (x,y) on plane from 3 points

        Dim v1, v2, abc As point3d

        'Create 2 vectors by subtracting p3 from p1 and p2
        v1.x = p1.x - p3.x
        v1.y = p1.y - p3.y
        v1.z = p1.z - p3.z

        v2.x = p2.x - p3.x
        v2.y = p2.y - p3.y
        v2.z = p2.z - p3.z

        'Create cross product from the 2 vectors
        abc.x = v1.y * v2.z - v1.z * v2.y
        abc.y = v1.z * v2.x - v1.x * v2.z
        abc.z = v1.x * v2.y - v1.y * v2.x


        'normalize abc
        Dim k As Single = Math.Sqrt((abc.x ^ 2) + (abc.y ^ 2) + (abc.z ^ 2))
        abc.x /= k
        abc.y /= k
        abc.z /= k

        'find d in the equation aX + bY + cZ = d
        Dim d As Single = abc.x * p3.x + abc.y * p3.y + abc.z * p3.z

        'calc z coordinate for point (x,y)
        GetPointOnPlaneZ = (d - abc.x * x - abc.y * y) / abc.z

    End Function

Sunday, August 23, 2015 6:36 PM

Thorsten,

It seems to work fine the way it is, without normalizing?

Hi,

maybe the cross-product of the direction vectors is close to 1 (as length), just a guess.

[How long are the two direction vectors you get from subtracting one point from the others? And how large is the [sin of the] inner angle]

Regards,

  Thorsten