游戏地图坐标与客户端坐标转换模型

 

 

 class Mapping
    {
        public float Kx;
        public float Ky;
        public float ScaleX;
        public float ScaleY;
        public Mapping()
        {
            this.Kx = -1f * 2 / 3;
            this.Ky = 1;
            this.ScaleX = 0.5f;
            this.ScaleY = 0.5f;
        }
        //求两直线交点
        public static PointF GetLinkPoint(float k1,float b1,float k2,float b2)
        {
            if (k1 == k2) return new PointF(-1, -1);
            PointF rst = new PointF();
            rst.X = (b2 - b1) / (k1 - k2);
            rst.Y = k1 * rst.X + b1;
            return rst;
        }
        //求两点间距离
        public static float GetDis(PointF pt1,PointF pt2)
        {
            return (float)Math.Sqrt((pt1.X - pt2.X) * (pt1.X - pt2.X) + (pt1.Y - pt2.Y) * (pt1.Y - pt2.Y));
        }
        //屏幕 2 客户端
        public PointF ScreenToClient(Point ptCient, Point ptScreen, Point pt)
        {
            PointF rst = new PointF();
            float k1, k2, b1, b2;
            k1 = this.Kx;
            k2 = this.Ky;
            b1 = pt.Y - k1 * pt.X;
            b2 = ptScreen.Y - k2 * ptScreen.X;
            PointF lp = GetLinkPoint(k1, b1, k2, b2);
            float disX = GetDis(lp, pt) * this.ScaleX;
            float disY = GetDis(lp, ptScreen) * this.ScaleY;
            float Bx,By;
            Bx = ptScreen.Y - ptScreen.X * Kx;//法线1
            By = ptScreen.Y - ptScreen.X * Ky;//法线2
            int t = WhichSide(Kx, Bx, lp);
            int Vy = (t == 0) ? 1 : -1;
            t = WhichSide(Ky, By, lp);
            int Vx = (t == 0) ? 1 : -1;
            rst.X = ptCient.X + disX * Vx;
            rst.Y = ptCient.Y + disY * Vy;
            return rst;
        }
        //客户端 2 屏幕
        public PointF ClientToScreen(Point ptCient, Point ptScreen, Point pt)
        {
            PointF rst = new PointF();
            float disY, disX;
            disY = Math.Abs((ptCient.Y - pt.Y) / this.ScaleY);
            disX = Math.Abs((ptCient.X - pt.X) / this.ScaleX);
            //求中间点-Y坐标变动
            float bZ, by;
            bZ = ptScreen.Y - ptScreen.X * Kx;//法线1
            by = ptScreen.Y - ptScreen.X * Ky;//法线2
            List<PointF> ls = GetPointByDis(Ky, by, ptScreen, disY);
            int v = (ptCient.Y - pt.Y) > 0 ? 1 : 0;
            int t = WhichSide(Kx, bZ, ls[0]);
            PointF ptTemp = (t == v) ? ls[0] : ls[1];
            //求目标点-X坐标变动
            float bx;
            bx = ptTemp.Y - ptTemp.X * Kx;
            ls = GetPointByDis(Kx, bx, ptTemp, disX);
            v = (ptCient.X - pt.X) > 0 ? 1 : 0;
            t = WhichSide(Ky, by, ls[0]);
            rst = (t == v) ? ls[0] : ls[1];
            return rst;
        }
        //求直线上和某点距离为dis的点坐标
        public static List<PointF> GetPointByDis(float k, float b, PointF ptO, float dis)
        {
            PointF pt1 = new PointF();
            PointF pt2 = new PointF();
            float temp, tp;
            temp = (dis * dis - ptO.X * ptO.X - (b - ptO.Y) * (b - ptO.Y)) / (k * k + 1);
            tp = (2 * k * (b - ptO.Y) - 2 * ptO.X) / (k * k + 1);
            temp = (float)Math.Sqrt(temp + (tp / 2) * (tp / 2));
            pt1.X = (temp - tp / 2);
            pt2.X = (-temp - tp / 2);
            pt1.Y = (k * (temp - tp / 2) + b);
            pt2.Y = (k * (-temp - tp / 2) + b);
            List<PointF> ls = new List<PointF>();
            ls.Add(pt1);
            ls.Add(pt2);
            return ls;
        }
        //判断点处于斜线哪边
        private int WhichSide(float k, float b, PointF pt)
        {
            double temp;
            temp = (pt.Y - b) / (1.0 * k) - pt.X;
            return (temp > 0) ? 1 : 0;
        }
       
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值