Tricky Geometry...

Blitz3D Forums/Blitz3D Programming/Tricky Geometry...

_PJ_(Posted 2003) [#1]
This is much harder than it first seemed.

I have a triangle in 3D space made by 3 objects placed at various coords. The triangle isn't aligned to any axes, so if you can imagine it stands at an angle.

I am trying to find the coordinates of a position in the centre of this triangle. However, I have only the corners' coords to work from ( and they're not nice numbers!) The point I am looking for is equidistant from each corner.


Any maths genises out there that cold help me out?

I have a formla for bisecting the edges, and drawing Normal tangents to the midpoints. Where these Normals intersect is the middle of the triangle, but I need to elevate this to the angle of the triangle itself.


coords are:

-3.1x,-19.2y,14.9z
21.2x,-8.9y,15.6z
-1.1x,-12.4y,39.4z


Jeppe Nielsen(Posted 2003) [#2]
How about averging your three coordinates?:

x = (x1 + x2 + x3) / 3
y = (y1 + y2 + y3) / 3
z = (z1 + z2 + z3) / 3

->

x = ( -3.1 - 19.2 + 14.9 ) / 3
y = ( 21.2 - 8.9 + 15.6 ) / 3
z = ( -1.1 - 12.4 + 39.4 ) / 3

Not sure it will work, though..


Floyd(Posted 2003) [#3]
That's the center of mass, which I would consider the 'center' of the triangle.

Note that it will usually not be equidistant from the three vertices.


_PJ_(Posted 2003) [#4]
I cannot see why it doesn't, although plotting the points on an orthographic graph shows that they are not correct. Interesting, and thanks ;)


Ross C(Posted 2003) [#5]
take the distance between any two points in the triangle and find the midpoint(call that x). then find the midpoint between the x and the other point in the triangle. that should give you the midpoint of the triangle. :)

(and i agree with floyd. the centre is only equidistant if it is an equilateral or isosceles triangle)

_________________
``==--..,..--==``

imagine that being a triangle. the centre is not equidistant

example for finding centre of triangle
ax=0
ay=0
az=0

bx=10
by=0
bz=0

cx=5
cy=10
cz=0



temp_mid_point_x=ax-((ax-bx)/2)
temp_mid_point_y=ay-((ay-by)/2)
temp_mid_point_z=az-((az-bz)/2)

actual_mid_point_x=temp_mid_point_x-((temp_mid_point_x-cx)/2)
actual_mid_point_y=temp_mid_point_y-((temp_mid_point_y-cy)/2)
actual_mid_point_z=temp_mid_point_z-((temp_mid_point_z-cz)/2)

Print "midpoint of triangle ("+actual_mid_p troint_x+","+actual_mid_point_y+","+actual_mid_point_z+")"



_PJ_(Posted 2003) [#6]
It is simple enough to find the midpoint per axis between point A and B, but point C must be considered too. Although it is a 2D triangle, it is in 3D space, and therefore all 3 dimnensions need to be considered. This is what makes it difficult.


_PJ_(Posted 2003) [#7]
Graphics3D 1024,768,16,2
SetBuffer BackBuffer()

AmbientLight 255,200,200

light=CreateLight(2)

cam=CreateCamera()
CameraViewport cam,0,0,1024,768

A=CreateCube()
EntityColor A,255,200,0

B=CreateCube()
EntityColor B,50,50,200

C=CreateCube()
EntityColor C,0,255,0

PositionEntity A,-3.1,-19.2,14.9
PositionEntity B,21.2,-8.9,15.6
PositionEntity C,-1.1,-12.4,39.4

sphere=CreateSphere(50)
EntityParent light,sphere

PositionEntity cam,-60,50,50
PointEntity cam,sphere

temp_mid_point_x=EntityX#(A)-((EntityX#(A)-(EntityX#(B))/2) )
temp_mid_point_y=EntityY#(A)-((EntityY#(A)-(EntityY#(B))/2) )
temp_mid_point_z=EntityZ#(A)-((EntityZ#(A)-(EntityZ#(B))/2) )

actual_mid_point_x=temp_mid_point_x-((temp_mid_point_x-EntityX#(C))/2) 
actual_mid_point_y=temp_mid_point_y-((temp_mid_point_y-EntityY#(C))/2) 
actual_mid_point_z=temp_mid_point_z-((temp_mid_point_z-EntityZ#(C))/2) 
x#=actual_mid_point_x
y#=actual_mid_point_y
z#=actual_mid_point_z
;"midpoint of triangle ("+actual_mid_p troint_x+","+actual_mid_point_y+","+actual_mid_point_z+")" 
PositionEntity sphere,x#,y#,z#

UpdateWorld

RenderWorld

A_dist#=EntityDistance#(sphere,A)

B_dist#=EntityDistance#(sphere,B)

C_dist#=EntityDistance#(sphere,C)

Text 500,0,x#+","+y#+","+z#+","

Text 500,20,A_dist#
Text 500,50,B_dist#
Text 500,80,C_dist#

Flip





I am actually looking for the equidistant point bewteen all 3 corners...

Hehe told ya it was tricky :)


Floyd(Posted 2003) [#8]
As you pointed out at the beginning this easy enough in principle.
But the details of the calculation are fairly gruesome.

If you want another approach, consider the circle determined by the three points.
The center of this circle is equidistant from them.

Here's a description of the solution: circle from three points.

Oops, just realized that is for 2d, i.e. no z.

That's what I get for trying to help without making any real effort.
Still, it's handy to know about Paul Bourke's site. Lots of neat stuff there.


Ross C(Posted 2003) [#9]
that would lie outside the triangle, in most triangles.my code finds the centre of a 3d triangle. least it should, i'll be back :)


_PJ_(Posted 2003) [#10]
Maybe a sphere that touches all three points?
but that may just overcomplicate matters...


Floyd(Posted 2003) [#11]
Even though the points are in 3d space they still determine a circle.
The center of that circle is the desired point.

In general this point may not be anywhere near the triangle.

Imagine a very large circle. Any three points on the circle are
equidistant from the center, as are all points on the circle.

If the three points are widely scattered around the circle then the center of the
circle will be near the 'middle' of the triangle.

But if the three points are clustered together then you have a small triangle.
The center of the circle is far away from the triangle.


Ross C(Posted 2003) [#12]
i know how to do it. triangle ABC. find the midpoint on line AB. find the midpoint on either line BC or AC. then find the point where them line meet. that is the mathimatical centre.


sswift(Posted 2003) [#13]
If you wnat a point that is equidistant from all three points in a triangle, then all you have to do is solve a series of equations:

D = SQR((X1-X4)^2 + (Y1-Y4)^2 + (Z1-Z4)^2)
D = SQR((X2-X4)^2 + (Y2-Y4)^2 + (Z2-Z4)^2)
D = SQR((X3-X4)^2 + (Y3-Y4)^2 + (Z3-Z4)^2)

1, 2, and 3 are the points of the triangle. 4 is the centerpoint.

Those equations calculate the distance between each corner point and the center point. We don't know the center point, but we do know that the distance is the same for all. D is the distance, and it is found in all three equations.

As we don't actually need to find the distance, we can simplify the equations somewhat right off the bat:

D = (X1-X4)^2 + (Y1-Y4)^2 + (Z1-Z4)^2
D = (X2-X4)^2 + (Y2-Y4)^2 + (Z2-Z4)^2
D = (X3-X4)^2 + (Y3-Y4)^2 + (Z3-Z4)^2

So now we're looking for D^2 for each set of points.

Unfortunately, I don't know how to proceed from here. Unlike myself and many folks here, the folks on #math on IRC are rude, elitist, and unhelpful and refused to answer my "too-easy for them" questions about how to simplify equations when you have stuff that is squared in it. So I don't know how to extract X4 Y4 and Z4 from the parentheses so I can get them on the other side of the equation.

What I did get out of them though is that sqr((x-z)^2) is not (x-z), it is |x-z|. So that cuts off one avenue I was considering for solving it.


sswift(Posted 2003) [#14]
Btw, here is a reference on Mathworld about this sort of thing:
http://mathworld.wolfram.com/Circumcenter.html


Ross C(Posted 2003) [#15]
sswift, am i right in assuming that to find the centre of the triangle you need to find two midpoints thenfind where in 3d space they intersect?


sswift(Posted 2003) [#16]
"sswift, am i right in assuming that to find the centre of the triangle you need to find two midpoints thenfind where in 3d space they intersect?"


I don't know, and you are not being very specifc. If you check out that mathword site there's LOTS of different "centers" for triangles which you can find.

Which you actually need depends on what you want to use it for.

You can find one center by drawing lines from the center of each side perpendicular to the side and dtermining where they intersect. You can find another "center" by finding the circumcenter. Then there's the center of mass which you can get just by averaging the locations of the points.

So you need to be more specific waht you want to do with it.


_PJ_(Posted 2003) [#17]
Well I projected the coords onto a graph orthographically, so I had 3 triangles one each as seen from PLAN, SIDE and FACE projection.

I found the midpoint of each, which gave me 2 coords each. either XY,YZ or XZ

Basically, I obtained a value for X Y and Z anyhow
and fed them into my program above, but althogh I am confident abot it being the centre of mass, it is again, not equidistant :(

Thanks for that link, Sswift - very good stuff, only I don't have the angles to work with...


Ross C(Posted 2003) [#18]
the centre using the perdendicular sides is more what i'm needing, sorry to hijack the thread malice :)

the program above doesn't really give you the exact centre of the triangle, it's a wee bit off but it's still pretty close. i looked into it and it's pretty deep the stuff for finding where two 3d lines intersect :S


big10p(Posted 2003) [#19]
Well, I'm officially bad a maths but I recently needed to add a vertex to the centre of all tris in a mesh in order to do per-tri rotations. This is the code I came up with, where:

x0,y0,z0 = vert 0 coords.
x1,y1,z1 = vert 1 coords.
x2,y2,z2 = vert 2 coords.

; Calculate and add a lone 'centre of tri'
; vertex (needed for per-tri rotations).
tx# = x1 + ((x2-x1)/2)
ty# = y1 + ((y2-y1)/2)
tz# = z1 + ((z2-z1)/2)
cvx# = tx - ((tx-x0)/3)
cvy# = ty - ((ty-y0)/3)
cvz# = tz - ((tz-z0)/3)
AddVertex(d_surf,cvx,cvy,cvz)


It seemed to do the job. Appologies if this is no good (i.e. crap) or is a method you've already discussed - like I say, I'm not a maths person. ;)


Jeppe Nielsen(Posted 2003) [#20]
Hello, my first reply was not what you were after, but now I think I have got it:

Try this piece of code :-)

;Circumcenter by Jeppe Nielsen 2003

; Find a triangleīs circumcenter;
; a center that is equally away from all of itīs vertices

Global circumcenterx#,circumcentery#,circumcenterz#


Graphics3D 800,600,16,2
HidePointer


SeedRnd MilliSecs()


pivot=CreatePivot()
cam=CreateCamera(pivot)

PositionEntity cam,0,0,-10

Dim entity(4)

findcircumcenter(Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4))



Repeat

If KeyHit(57)

findcircumcenter(Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4),Rnd(-4,4))

EndIf


TurnEntity pivot,MouseYSpeed()/2,-MouseXSpeed()/2,0
MoveMouse 400,300

If KeyDown(200) Then MoveEntity cam,0,0,.1
If KeyDown(208) Then MoveEntity cam,0,0,-.1

RenderWorld()




Color 255,255,0
Rect 10,50,20,20
Color 0,0,255
Rect 10,80,20,20

Color 255,255,255
Text 10,10,"Mouse to rotate view"
Text 10,30,"Space to create a new triangle"
Text 40,50,"Circumcenter"
Text 40,80,"Circumsphere"

Flip

Until KeyDown(1)
End



Function findcircumcenter(x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#)

For n=0 To 4
	If entity(n)<>0

		FreeEntity entity(n)

	EndIf
Next


dx1#=(x2#-x1#)
dy1#=(y2#-y1#)
dz1#=(z2#-z1#)

dx2#=(x3#-x1#)
dy2#=(y3#-y1#)
dz2#=(z3#-z1#)

dx3#=(x3#-x2#)
dy3#=(y3#-y2#)
dz3#=(z3#-z2#)


entity(0)=CreateCylinder(3,0)
PositionMesh entity(0),0,1,0
PositionEntity entity(0),x1#,y1#,z1#
l#=Sqr(dx1*dx1+dy1*dy1+dz1*dz1)/2.0
ScaleEntity entity(0),0.01,l#,0.01
AlignToVector entity(0),dx1,dy1,dz1,2

entity(1)=CreateCylinder(3,0)
PositionMesh entity(1),0,1,0
PositionEntity entity(1),x1#,y1#,z1#
l#=Sqr(dx2*dx2+dy2*dy2+dz2*dz2)/2.0
ScaleEntity entity(1),0.01,l#,0.01
AlignToVector entity(1),dx2,dy2,dz2,2

entity(2)=CreateCylinder(3,0)
PositionMesh entity(2),0,1,0
PositionEntity entity(2),x2#,y2#,z2#
l#=Sqr(dx3*dx3+dy3*dy3+dz3*dz3)/2.0
ScaleEntity entity(2),0.01,l#,0.01
AlignToVector entity(2),dx3,dy3,dz3,2

For n=0 To 2
EntityFX entity(n),1
Next

; Start math part :-)


dx1#=(x2#-x1#)
dy1#=(y2#-y1#)
dz1#=(z2#-z1#)

dx2#=(x3#-x1#)
dy2#=(y3#-y1#)
dz2#=(z3#-z1#)

tnx# = dy1 * dz2 - dy2 * dz1
tny# = dz1 * dx2 - dz2 * dx1
tnz# = dx1 * dy2 - dx2 * dy1


sx1#=(x1#+x3#)/2.0
sy1#=(y1#+y3#)/2.0
sz1#=(z1#+z3#)/2.0

dx1#=(sx1#-x1#)
dy1#=(sy1#-y1#)
dz1#=(sz1#-z1#)

dx2#=tnx#
dy2#=tny#
dz2#=tnz#

nx# = dy1 * dz2 - dy2 * dz1
ny# = dz1 * dx2 - dz2 * dx1
nz# = dx1 * dy2 - dx2 * dy1

sx2#=sx1#+nx#
sy2#=sy1#+ny#
sz2#=sz1#+nz#

sx3#=(x1#+x2#)/2.0
sy3#=(y1#+y2#)/2.0
sz3#=(z1#+z2#)/2.0

dx1#=(sx3#-x1#)
dy1#=(sy3#-y1#)
dz1#=(sz3#-z1#)

dx2#=tnx#
dy2#=tny#
dz2#=tnz#

nx# = dy1 * dz2 - dy2 * dz1
ny# = dz1 * dx2 - dz2 * dx1
nz# = dx1 * dy2 - dx2 * dy1

sx4#=sx3#+nx#
sy4#=sy3#+ny#
sz4#=sz3#+nz#


ax#=sx2#-sx1#
ay#=sy2#-sy1#
az#=sz2#-sz1#

bx#=sx4#-sx3#
by#=sy4#-sy3#
bz#=sz4#-sz3#

cx#=sx3#-sx1#
cy#=sy3#-sy1#
cz#=sz3#-sz1#

qx1# = cy * bz - by * cz
qy1# = cz * bx - bz * cx
qz1# = cx * by - bx * cy

qx2# = ay * bz - by * az
qy2# = az * bx - bz * ax
qz2# = ax * by - bx * ay

dot#=qx1*qx2+qy1*qy2+qz1*qz2

le#=Sqr(qx2*qx2+qy2*qy2+qz2*qz2)

si#=dot#/(le#*le#)

circumcenterx#=sx1#+ax#*si#
circumcentery#=sy1#+ay#*si#
circumcenterz#=sz1#+az#*si#

; End math part :-)


entity(3)=CreateSphere(16)

PositionEntity entity(3),circumcenterx#,circumcentery#,circumcenterz#
ScaleEntity entity(3),0.05,0.05,0.05
EntityColor entity(3),255,255,0
EntityFX entity(3),1



dx#=circumcenterx#-x1#
dy#=circumcentery#-y1#
dz#=circumcenterz#-z1#

rad#=Sqr(dx*dx+dy*dy+dz*dz)

entity(4)=CreateSphere(24)
PositionEntity entity(4),circumcenterx#,circumcentery#,circumcenterz#
ScaleEntity entity(4),rad,rad,rad
EntityAlpha entity(4),0.75
EntityColor entity(4),0,0,255

EntityOrder entity(4),1

End Function


Hope you can use it :)


Jeppe Nielsen(Posted 2003) [#21]
Did you solve your problem ?


Ross C(Posted 2003) [#22]
the thing i can see tho that the Circumcenter is not always inside the triangle unless it has two or three similar angles. it's a toughy tho, u think it would be easy to find the centre of a tri :S


_PJ_(Posted 2003) [#23]
Well, I was trying this to help a friend out ( I didnt think it would be this hard!) and I found the coords that gave a close enough equidistant point, although I cannot prove this point mathematically, my friend is currently on holiday and I think the coords I obtained were acceptable, So thanks for all your help ;)


Jeppe Nielsen(Posted 2003) [#24]
With your coords from your first post, I have found the equidistant point for the three vertices, using my program above. They are as follows:

x: 7.92265
y: -12.0732
z: 25.2974

Run this piece of code to see that the three distances are equal:
;triangle coords
;-3.1x,-19.2y,14.9z 
;21.2x,-8.9y,15.6z 
;-1.1x,-12.4y,39.4z 

;circumcenter coords
x#=7.92265
y#=-12.0732
z#=25.2974

dx#=(-3.1-x)
dy#=(-19.2-y)
dz#=(14.9-z)

dist1#=Sqr(dx*dx+dy*dy+dz*dz)

dx#=(21.2-x)
dy#=(-8.9-y)
dz#=(15.6-z)

dist2#=Sqr(dx*dx+dy*dy+dz*dz)

dx#=(-1.1-x)
dy#=(-12.4-y)
dz#=(39.4-z)

dist3#=Sqr(dx*dx+dy*dy+dz*dz)

Print dist1
Print dist2
Print dist3

;all distances are equal

MouseWait



_PJ_(Posted 2003) [#25]
Thanks lots, Jeppe!

My original coords that I felt happy with, (here substituted into your code)

;triangle coords
;-3.1x,-19.2y,14.9z 
;21.2x,-8.9y,15.6z 
;-1.1x,-12.4y,39.4z 

;circumcenter coords

x#=5.0 
y#=-5.1 
z#=23.6 
dx#=(-3.1-x)
dy#=(-19.2-y)
dz#=(14.9-z)

dist1#=Sqr(dx*dx+dy*dy+dz*dz)

dx#=(21.2-x)
dy#=(-8.9-y)
dz#=(15.6-z)

dist2#=Sqr(dx*dx+dy*dy+dz*dz)

dx#=(-1.1-x)
dy#=(-12.4-y)
dz#=(39.4-z)

dist3#=Sqr(dx*dx+dy*dy+dz*dz)

Print dist1
Print dist2
Print dist3



give a reasonable 18.45 - ish!

But thanks, your coords are much more accurate, and it is strange that the coordinates are so different, yet they work the same in both my code and yours, so must be right :)

Thanks once again!