Jump to content

Trig in 3D


chimera27

Recommended Posts

I'm trying to use trig to calculate the angles between the playe and an entity to change the players view angle to look at them. I'm normally pretty good at trig, but we haven't covered how to use it in 3D like this before. I gave it a shot anyway, and came up with this code:

 

 

player.rotationYaw = (float) (180 - Math.toDegrees(Math.atan((target.posX - player.posX)/ (target.posZ -player.posZ))));

player.rotationPitch = (float) (-Math.toDegrees(Math.atan((target.posY - player.posY)/ (target.posX - player.posX))));

 

 

The yaw code works half the time, and pitch works maybe one percent of the time and is glitchy as hell. The yaw code works when the player is looking one side of the entity, as soon as you cross into the other it flips and gets weird (presumubly something with the range of atan being -pi/2 - pi/2).

 

rotationPitch on the other hand almost works if you look at the entity from just the right direction, as you strafe around it left/right it moves further away from the point it's supposed to exponentally.

One thing I noticed was that at least vertically, looking down increases degrees and up decreases it ???

 

Anyone know what I should do?/Where i'm messing up?

 

(also on a side note if anyone knows how to/if I can increase the range on minecraft.getMinecraft().objectMouseOver that would be awesome :P)

Creator of Metroid Cubed! Power Suits, Beams, Hypermode and more!

width=174 height=100http://i.imgur.com/ghgWmA3.jpg[/img]

Link to comment
Share on other sites

Those seem to work quite a bit differently, and are quite complex and hard to follow... The fact that this code works sometimes makes me think i'm on the right track

 

Edit: Managed to get pitch to work with this code:

double d0 = player.posX - target.posX;
				            double d1 = player.posY - target.posY;
				            double d2 = player.posZ - target.posZ;
				            double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2);
				            float f = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
				            float f1 = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI));
				            System.out.println("Pitchy thing: " + f1);
							// player.rotationPitch = f1;
							player.rotationYaw = f + 180;

 

Pitch is still changing exactly the same as a graph of tan(x) as you circle the entity though.....

Creator of Metroid Cubed! Power Suits, Beams, Hypermode and more!

width=174 height=100http://i.imgur.com/ghgWmA3.jpg[/img]

Link to comment
Share on other sites

I'm trying to use trig to calculate the angles between the playe and an entity to change the players view angle to look at them. I'm normally pretty good at trig, but we haven't covered how to use it in 3D like this before. I gave it a shot anyway, and came up with this code:

 

 

player.rotationYaw = (float) (180 - Math.toDegrees(Math.atan((target.posX - player.posX)/ (target.posZ -player.posZ))));

player.rotationPitch = (float) (-Math.toDegrees(Math.atan((target.posY - player.posY)/ (target.posX - player.posX))));

 

 

The yaw code works half the time, and pitch works maybe one percent of the time and is glitchy as hell. The yaw code works when the player is looking one side of the entity, as soon as you cross into the other it flips and gets weird (presumubly something with the range of atan being -pi/2 - pi/2).

 

rotationPitch on the other hand almost works if you look at the entity from just the right direction, as you strafe around it left/right it moves further away from the point it's supposed to exponentally.

One thing I noticed was that at least vertically, looking down increases degrees and up decreases it ???

 

Anyone know what I should do?/Where i'm messing up?

 

(also on a side note if anyone knows how to/if I can increase the range on minecraft.getMinecraft().objectMouseOver that would be awesome :P)

 

Hi

 

I would suggest you use atan2 instead of atan, that will give you the proper angle for all combinations of deltax and deltaz (except 0,0) , unlike atan where it only gives half the unit circle and causes division by 0 errors if deltaz is zero.

 

Pitch is wrong because  you need to use atan2 with the vertical distance to the entity divided by the horizontal distance.  You've got the right idea, the vertical is deltay but the horizontal is not just x, it's the sqrt of (deltaz^2 + deltax^2).  If you draw the right-angle triangles in 3D - first the "yaw" triangle with deltax and deltaz, and then the "pitch" triangle with the hypotenuse of the "yaw" triangle and the delta y, you can see why.  Hard to explain without a diagram...

 

-TGG

Link to comment
Share on other sites

PS

 

re getMouseOver

 

This is the code from 1.6.4 that updates objectMouseOver.  You can copy this code, call rayTrace with a longer distance (d0) and do what you want with the result.

    public void getMouseOver(float par1)
    {
        if (this.mc.renderViewEntity != null)
        {
            if (this.mc.theWorld != null)
            {
                this.mc.pointedEntityLiving = null;
                double d0 = (double)this.mc.playerController.getBlockReachDistance();
                this.mc.objectMouseOver = this.mc.renderViewEntity.rayTrace(d0, par1);
                double d1 = d0;
                Vec3 vec3 = this.mc.renderViewEntity.getPosition(par1);

 

Alternatively, if you want to change the vanilla block reach distance, you might be able to use ASM to fiddle with PlayerControllerMP.getBlockReachDistance

 

-TGG

 

 

Link to comment
Share on other sites

Hmm, this seems to be working for blocks, but is ignoring entities (the entity hit is always returning null) It might have something to do with me not using it correctly, since I can't check the partial tick time from this class I just used render tick time which I thought might work in this case, but even if I put a static number there it doesn't change anything so I don't know how much it's really doing :/

(I did modify it to just return mc.renderViewEntity.rayTrace(d0, par1) because a movingobjectposition is much more useful then a vec3, and I removed the this.mc.pointedEntityLiving = null; because I would assumed it wouldn't do much here, but the fact it does work for blocks is puzzling...)

Creator of Metroid Cubed! Power Suits, Beams, Hypermode and more!

width=174 height=100http://i.imgur.com/ghgWmA3.jpg[/img]

Link to comment
Share on other sites

Hi

 

That's because rayTrace only looks for block collision.  The vanilla code in getMouseOver then goes on to see whether the ray hits any entities before it hits the block.

 

-TGG

 

Reproduced here for your convenience:  :-)

 

 

    public void getMouseOver(float par1)
    {
        if (this.mc.renderViewEntity != null)
        {
            if (this.mc.theWorld != null)
            {
                this.mc.pointedEntityLiving = null;
                double d0 = (double)this.mc.playerController.getBlockReachDistance();
                this.mc.objectMouseOver = this.mc.renderViewEntity.rayTrace(d0, par1);
                double d1 = d0;
                Vec3 vec3 = this.mc.renderViewEntity.getPosition(par1);

                if (this.mc.playerController.extendedReach())
                {
                    d0 = 6.0D;
                    d1 = 6.0D;
                }
                else
                {
                    if (d0 > 3.0D)
                    {
                        d1 = 3.0D;
                    }

                    d0 = d1;
                }

                if (this.mc.objectMouseOver != null)
                {
                    d1 = this.mc.objectMouseOver.hitVec.distanceTo(vec3);
                }

                Vec3 vec31 = this.mc.renderViewEntity.getLook(par1);
                Vec3 vec32 = vec3.addVector(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0);
                this.pointedEntity = null;
                float f1 = 1.0F;
                List list = this.mc.theWorld.getEntitiesWithinAABBExcludingEntity(this.mc.renderViewEntity, this.mc.renderViewEntity.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0).expand((double)f1, (double)f1, (double)f1));
                double d2 = d1;

                      for (int i = 0; i < list.size(); ++i)
                      {
                        Entity entity = (Entity)list.get(i);

                        if (entity.canBeCollidedWith())
                        {
                          float f2 = entity.getCollisionBorderSize();
                          AxisAlignedBB axisalignedbb = entity.boundingBox.expand((double)f2, (double)f2, (double)f2);
                          MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32);

                        if (axisalignedbb.isVecInside(vec3))
                        {
                            if (0.0D < d2 || d2 == 0.0D)
                            {
                                this.pointedEntity = entity;
                                d2 = 0.0D;
                            }
                        }
                        else if (movingobjectposition != null)
                        {
                            double d3 = vec3.distanceTo(movingobjectposition.hitVec);

                            if (d3 < d2 || d2 == 0.0D)
                            {
                                if (entity == this.mc.renderViewEntity.ridingEntity && !entity.canRiderInteract())
                                {
                                    if (d2 == 0.0D)
                                    {
                                        this.pointedEntity = entity;
                                    }
                                }
                                else
                                {
                                    this.pointedEntity = entity;
                                    d2 = d3;
                                }
                            }
                        }
                    }
                }

                if (this.pointedEntity != null && (d2 < d1 || this.mc.objectMouseOver == null))
                {
                    this.mc.objectMouseOver = new MovingObjectPosition(this.pointedEntity);

                    if (this.pointedEntity instanceof EntityLivingBase)
                    {
                        this.mc.pointedEntityLiving = (EntityLivingBase)this.pointedEntity;
                    }
                }
            }
        }
    }

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.