• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Maths] Pyramid Equotation

Status
Not open for further replies.
Level 16
Joined
Oct 12, 2008
Messages
1,570
Hello people,,

I am in need of an equotation for a pyramid. There are a few parameters that i have got, and some conditions.

I need a pyramid with 4 sides, all with the same dimensions.
I got 3 coordinates, X,Y and Z. And i got a range.

Now i need a pyramid that has 4 points that all have a distance of <RANGE> to point (X,Y,Z). That means that all 6 ribs of the pyramid have the same length.

The pyramid must look like this. It actually has alot in common with the CH4 molecule.
Piramid.jpg

The equotation i need is one to calculate the coordinates (all 3) of the 4 hook-points of the pyramid.

I hope some math genius will come by and tell me =)

Thanks

-Yixx,,-
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
Well,, i kinda got like a 'facing' of the pyramid. Lets keep that one at 0 for now, then i just need the equotations to calculate the other points.

the upper point is easy, just xcenter,ycenter,zcenter+Range

But the others?
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
The center point and the upper point are fixed,, that actually ruins the concept of a randomly spinning (in all axes') pyramid, but i'll just figure something out,,

So: the center and the upper point are fixed,, and then?
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Not entirely sure if the axes are set correctly since I am used to normal axes (where z is depth, not height), but it shouldn't be too hard to fix if it isn't correct.

Anyway, there are probably a million syntax errors since I didn't use Jass in who knows how long and I don't have any warcraft related programs, but I think this should do the job if fixed.

Basically just create a Pyramid instance with a Vector3 resembling the center, a real being the length (distance of each point from the center), and a real being the angle of the rotation from the center to the four corners.
The angle would probably be best at -45 degrees (give it as radians to the function).

JASS:
library LibPyramid

struct Vector3
    public real x
    public real y
    public real z
    
    public method create takes real x,real y,real z returns nothing
        this = Vector3.allocate()
        set .x = x
        set .y = y
        set .z = z
    endmethod
    
    public method operator= takes Vector3  sV returns nothing
        set .x = sV.x
        set .y = sV.y
        set .z = sV.z
    endmethod

    private method squaredLength takes nothing returns real
        return ((.x*.x)+(.y*.y)+(.z*.z))
    endmethod
    
    private method normalize takes nothing returns nothing
        local real length = squaredLength;
        
        if length > 1 then
            set length = SquareRoot(length)
            
            set .x = .x / length
            set .y = .y / length
            set .z = .z / length
        endif
    endmethod
    
    // not suggested for use (which is why I set it to private)
    // use rotateNormalized instead (see below)
    private method rotate takes real Radians,real AxisX,real AxisY,real AxisZ returns Vector3
        
        local Vector3 ret = Vector3.create()
        
        local real fCos = Cos(Radians)
        local real fSin = Sin(Radians)
        local real fOneMinusCos = 1.0-fCos
        local real fX2 = AxisX*AxisX;
        local real fY2 = AxisY*AxisY;
        local real fZ2 = AxisZ *AxisZ ;
        local real fXYM = AxisX*AxisY*fOneMinusCos;
        local real fXZM = AxisX*AxisZ *fOneMinusCos;
        local real fYZM = AxisY*AxisZ *fOneMinusCos;
        local real fXSin = AxisX*fSin;
        local real fYSin = AxisY*fSin;
        local real fZSin = AxisZ *fSin;
    
        local real m00 = fX2*fOneMinusCos+fCos;
        local real m01 = fXYM-fZSin;
        local real m02 = fXZM+fYSin;
        local real m10 = fXYM+fZSin;
        local real m11 = fY2*fOneMinusCos+fCos;
        local real m12 = fYZM-fXSin;
        local real m20 = fXZM-fYSin;
        local real m21 = fYZM+fXSin;
        local real m22 = fZ2*fOneMinusCos+fCos;

        set ret.x = (.x*m00)+(.y*m10)+(.z*m20)
        set ret.y = (.x*m01)+(.y*m11)+(.z*m21)
        set ret.z = (.x*m02)+(.y*m12)+(.z*m22)
        
        return ret
    endmethod
    
    public method rotateNormalized takes real Radians,real AxisX,real AxisY,real AxisZ returns Vector3
        Axis.normalize()
        .rotate(Radians,Axis)
    endmethod
endstruct

struct Pyramid
    public Vector3 Center
    public Vector3 Top
    public Vector3 A
    public Vector3 B
    public Vector3 C
    public real Length
    public real Angle
    
    public method create takes Vector3 Center,real Length,real Angle returns nothing
        local Vector3 Unit = Vector3.create(1,0,0)
        
        set .Center = Vector3.create(Center.x,Center.y,Center.z)
        set .Top = Vector3.create(Center.x,Center.y,Center.z + Length)
        
        set Unit = Unit.rotateNormalized(Angle,1,0,0)
        
        set Unit = Unit.rotateNormalized(120*bj_DEGTORAD,0,0,1)
        set .A = Vector3.create(Unit .x * Length,Unit .y * Length,Unit .z * Length)
        
        set Unit =  Unit.rotateNormalized(120*bj_DEGTORAD,0,0,1)
        set .B = Vector3.create(Unit .x * Length,Unit .y * Length,Unit .z * Length)
        
        set Unit =  Unit.rotateNormalized(120*bj_DEGTORAD,0,0,1)
        set .C = Vector3.create(Unit .x * Length,Unit .y * Length,Unit .z * Length)
        
        set .Length = Length
        set .Angle = Angle
    endmethod
    
endstruct

endlibrary
 
Last edited:
Level 14
Joined
Nov 18, 2007
Messages
816
Alright, lets assume you the point M given. Point A is straight above point M, so A(x|y|z+r).

Because were talking about a regular tetraeder, the length of each edge of the tetraeder (a) is sqrt(2/3)*2*range.
Edit: wtf am i talking. Its the length of the edges of a cube surrounding the tetraeder so that each edge of the tetraeder is a planar diagonal.

The second Point B is at 0 degrees, so B( x+((a/2)*Cos(0) | y+((a/2)*Sin(0)) | z-(r/2) ).

The third and fourth point are at 2*Pi/3 and 4*Pi/3.
 
Last edited:
Level 16
Joined
Oct 12, 2008
Messages
1,570
Ok im back.
So lets say the 'facing' of the pyramid is 0. And one point is always on the pyramids facing.
then one point would be P(x+Range*Cos(0) | y + Range*Sin(0) | z - Range*Sin(109.5-90) )

Why the 109.5? That is the exact angle in a CH4 from each H atom to an other H atom. Now the the -90 is for a reason i cannot explain very well in english but i hope you understand.

Now every of the next points will be:
P2(x+Range*Cos(120) | x + Range*Sin(120) | z+Range*Sin(109.5-90) )
P3(x+Range*Cos(240) | x + Range*Sin(240) | z+Range*Sin(109.5-90) )
120 + facing, but facing = 0
240 + facing, but facing = 0

That is when the upper point is fixed, now how do i do those point when the upper is non-fixed?

BTW: Those vectors might be usefull!
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
Ok i got a few new things:
JASS:
struct DATA
    real x
    real y
    real z
    real Range
    real zRoll
    real xyRoll // = facing
endstruct
Now it seems to me that this will be the 5 points:

Center ( x | y | z )
Upper ( x + (Range*Sin(zRoll)) * Cos(xyRoll) | y + (Range*Sin(zRoll)) * Sin(xyRoll) | z + Range*Cos(zRoll) )
Lower1 ( x + (Range * Cos(19.5))*Cos(000+xyRoll) | x + (Range * Cos(19.5))*Sin(000+xyRoll) | z - Range* Sin(19.5) )
Lower2 ( x + (Range * Cos(19.5))*Cos(120+xyRoll) | x + (Range * Cos(19.5))*Sin(120+xyRoll) | z - Range* Sin(19.5) )
Lower3 ( x + (Range * Cos(19.5))*Cos(240+xyRoll) | x + (Range * Cos(19.5))*Sin(240+xyRoll) | z - Range* Sin(19.5) )


Please tell me if i am wrong or not =\

EDIT:
Current Code:

It works, forgot to convert to radians ^^,,
JASS:
library Pyramid initializer Init 
    globals
        constant integer C =0
        constant integer U =1
        constant integer L1=2
        constant integer L2=3
        constant integer L3=4
        constant real Cos195 = Cos(19.5*bj_DEGTORAD)
        constant real Sin195 = Sin(19.5*bj_DEGTORAD)
    endglobals
 
 
    struct DATA
        real array x [5]
        real array y [5]
        real array z [5]
        lightning array L [5]
        real xyRoll
        real zRoll
        real Range
 
        static method create takes real x, real y, real z returns DATA
            local DATA dat = DATA.allocate()
            local real L
            local real S
            local integer i = 0
            set dat.xyRoll = 0
            set dat.zRoll = 0
            set dat.Range = 500
            set dat.x[C] = x
            set dat.y[C] = y
            set dat.z[C] = z
            set L = dat.Range*Sin(dat.zRoll)
            set dat.x[U] = x + L * Cos(dat.xyRoll)
            set dat.y[U] = y + L * Sin(dat.xyRoll)
            set dat.z[U] = z + dat.Range * Cos(dat.zRoll)
            set L = dat.Range * Cos195
            loop
                exitwhen i > 2
                set dat.x[i+2] = x + L * Cos(120*i + dat.xyRoll)
                set dat.y[i+2] = y + L * Sin(120*i + dat.xyRoll)
                set dat.z[i+2] = z - dat.Range * Sin195
                set i = i + 1
            endloop
            set dat.L[0] = AddLightningEx("CLPB",false,dat.x[U],dat.y[U],dat.z[U],dat.x[L1],dat.y[L1],dat.z[L1])
            set dat.L[1] = AddLightningEx("CLPB",false,dat.x[U],dat.y[U],dat.z[U],dat.x[L2],dat.y[L2],dat.z[L2])
            set dat.L[2] = AddLightningEx("CLPB",false,dat.x[U],dat.y[U],dat.z[U],dat.x[L3],dat.y[L3],dat.z[L3])
            set dat.L[0] = AddLightningEx("CLPB",false,dat.x[L1],dat.y[L1],dat.z[L1],dat.x[L2],dat.y[L2],dat.z[L2])
            set dat.L[0] = AddLightningEx("CLPB",false,dat.x[L1],dat.y[L1],dat.z[L1],dat.x[L3],dat.y[L3],dat.z[L3])
            set dat.L[0] = AddLightningEx("CLPB",false,dat.x[L2],dat.y[L2],dat.z[L2],dat.x[L3],dat.y[L3],dat.z[L3])
            return dat
        endmethod
    endstruct
    private function Start takes nothing returns nothing
        call DATA.create(0,0,300)
    endfunction
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterTimerEvent(t,1,false)
        call TriggerAddAction(t,function Start)
    endfunction
endlibrary

But it is not working as it should
 

Attachments

  • Pyramid.jpg
    Pyramid.jpg
    69.6 KB · Views: 206
Last edited:
Status
Not open for further replies.
Top