不同系的坐标变换

本文讨论了如何在Python中使用numpy进行坐标转换,并与JavaScript库如Math.js、Sylvester和gl-matrix进行对比,展示了在游戏或3D场景中的沙盒坐标转换过程和代码实现。
摘要由CSDN通过智能技术生成

沙盘坐标转换,
不同系转换功能改造,对比python 和js吧,
py就不说了 有numpy,

坐标系变换js库,
Math.js
https://mathjs.org/
Sylvester
http://sylvester.jcoglan.com/
gl-matrix
https://glmatrix.net/docs/v4/index.html
three.js
https://threejs.org/
测试 api对应情况js Sylvester python numpy

#!/usr/bin/env python
# coding=utf-8
import json
import time
import math
import numpy.matlib 
import numpy as np

# cfg_data={
#   "environment_width": 90.0,
#   "environment_height": 61.0,
#
#   "box_pixel_scale_size": [13,13],
#
#   "world2field_sand_box_direction": [1,-1],
#   "world2field_box_transfer_theta": 45,
#   "world2field_box_deviation": [-69.5,25.5],
#
#   "screen_select_field_corner": "A"
# }

class mtx():
    @classmethod
    def Rx(cls,r):
        return np.array([
        [1, 0, 0, 0],
        [0, np.cos(r), -np.sin(r), 0],
        [0, np.sin(r), np.cos(r),  0],

        [0, 0, 0, 1],
        ])
    @classmethod
    def Ry(cls,r):
        return np.array([
        [np.cos(r), 0,np.sin(r),  0],
        [0, 1, 0, 0],
        [-np.sin(r), 0,np.cos(r),  0],

        [0, 0, 0, 1],
        ])
    @classmethod
    def Rz(cls,r):
        return np.array([
        [np.cos(r), -np.sin(r), 0, 0],
        [np.sin(r), np.cos(r), 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1],
        ])
    @classmethod
    def T(cls,x,y,z):
        return np.array([
        [1, 0, 0, x],
        [0, 1, 0, y],
        [0, 0, 1, z],
        [0, 0, 0, 1]
        ])
    @classmethod
    def F(cls,fx=1,fy=1,fz=1):
        return np.array([
        [fx, 0, 0, 0],
        [0, fy, 0, 0],
        [0, 0, fz, 0],
        [0, 0, 0, 1]
        ])
    @classmethod
    def S(cls,sx,sy,sz):
        return np.array([
        [sx, 0, 0, 0],
        [0, sy, 0, 0],
        [0, 0, sz, 0],
        [0, 0, 0, 1]
        ])
    @classmethod
    def P(cls,x,y,z):
        return np.array([
        [x],
        [y],
        [z],
        [1]
        ])
class transData():
    def __init__(self,mat_px2m,mat_m2px,theta_px2m,theta_m2px,scale_px2m,scale_m2px):
        self.mat_px2m=mat_px2m
        self.mat_m2px=mat_m2px
        self.theta_px2m=theta_px2m
        self.theta_m2px=theta_m2px
        self.scale_px2m=scale_px2m
        self.scale_m2px=scale_m2px
class point():
    def __init__(self,x,y,z):
        self.x=x
        self.y=y
        self.z=z
class trans():
    def __init__(self):
        # 读取外部参数文件
        filename = "./config/env_params_config.json"
        with open(filename, "r") as f:
            cfg_data = json.load(f)
            f.close()
        self.trans_info=self.transinfo_field_to_world(cfg_data);


    def transinfo_field_to_world(self,jdata):
        w = float(jdata["environment_width"]) #// 90.0,
        h = float(jdata["environment_height"]) #// 61.0,
        d = 1000
        tx = float(jdata["world2field_box_deviation"][0])
        ty = float(jdata["world2field_box_deviation"][1])
        tz = 0
        ppmw = float(jdata["box_pixel_scale_size"][0])
        ppmh = float(jdata["box_pixel_scale_size"][1])
        ppmd = 1

        rx = 0
        ry = 0
        rz = float(jdata["world2field_box_transfer_theta"])*math.pi/ 180.0

        fx = jdata["world2field_sand_box_direction"][0]
        fy = jdata["world2field_sand_box_direction"][1]
        fz = 1
        # //翻转
        m = mtx.F(fx, fy, fz)
        # //放缩
        m2 = mtx.S(1.0 / ppmw, 1.0 / ppmh, 1.0 / ppmd)
        # //位移
        m3 = mtx.T(tx, ty, tz)
        # //旋转矩阵
        m4 = mtx.Rz(rz)
        tm = np.dot(m2, m)
        tm = np.dot(m4, tm)
        tm = np.dot(m3, tm)
        return  transData(
            tm,np.asarray(np.matrix(tm).I),
            -rz,rz,
            (1.0 / ppmw + 1.0 / ppmh) / 2,(ppmw + ppmh) / 2
        )

        # {
        #     "mat_px2m": tm,
        #     "mat_m2px": np.asarray(np.matrix(tm).I),  # inverse(),
        #     "theta_px2m": -rz,
        #     "theta_m2px": rz,
        #     "scale_px2m": (1.0 / ppmw + 1.0 / ppmh) / 2,
        #     "scale_m2px": (ppmw + ppmh) / 2
        # }


    def px2m_point(self,x,y,z):
        p=mtx.P(x,y,z)
        v=np.dot(self.trans_info.mat_px2m,p)
        return point(v[0][0],v[1][0],v[2][0])#{"x":v[0][0],"y":v[1][0],"z":v[2][0]}

    def m2px_point(self,x,y,z):
        p=mtx.P(x,y,z)
        v=np.dot(self.trans_info.mat_m2px,p)
        return point(v[0][0],v[1][0],v[2][0])#{"x":v[0][0],"y":v[1][0],"z":v[2][0]}

    def m2px_lenth(self,m):
        v=self.trans_info.scale_m2px*m
        return v

    def px2m_lenth(self,px):
        v=self.trans_info.scale_px2m*px
        return v

    def px2m_theta(self,a):
        v=self.trans_info.theta_px2m+a
        return v

    def m2px_theta(self,a):
        v=self.trans_info.theta_m2px+a
        return v


t=trans()
p= t.m2px_point(0,0,0)
p2=t.px2m_point(p.x,p.y,p.z)

print (p.x,p.y,p.z)
print  (p2.x,p2.y,p2.z)


if __name__ == "__main__":
    n=0
    while 1:
        print n
        n=n+1
        time.sleep(1)

对比js

/*
zzz 202403


cfg_data={
    "environment_width": 90.0,
    "environment_height": 61.0,
    "box_pixel_scale_size": [13,13],
    "world2field_sand_box_direction": [1,-1],
    "world2field_box_transfer_theta":45,//
    "world2field_box_deviation": [-69.5,25.5],
    "screen_select_field_corner": "A"
}


*/
var np={
    PI:3.14159265358,
    sin: function(r){return Math.sin(r);},
    cos: function(r){return Math.cos(r);},
    sindeg: function(r){return Math.sin(this.PI*r/180.0);},
    cosdeg: function(r){return Math.cos(this.PI*r/180.0);}
}
var mtx={
    Rx:function (r){
        return $M([
        [1, 0, 0, 0],
        [0, np.cos(r), -np.sin(r), 0],
        [0, np.sin(r), np.cos(r),  0],
        [0, 0, 0, 1],
        ])
    },
    Ry:function (r){
        return $M([
        [np.cos(r), 0,np.sin(r),  0],
        [0, 1, 0, 0],
        [-np.sin(r), 0,np.cos(r),  0],
        [0, 0, 0, 1],
        ])
    },
    Rz:function (r){
        return $M([
        [np.cos(r), -np.sin(r), 0, 0],
        [np.sin(r), np.cos(r), 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1],
        ])
    },
    T:function (x,y,z){
        return $M([
        [1, 0, 0, x],
        [0, 1, 0, y],
        [0, 0, 1, z],
        [0, 0, 0, 1]
        ])
    },
    F:function (fx=1,fy=1,fz=1){
        return $M([
        [fx, 0, 0, 0],
        [0, fy, 0, 0],
        [0, 0, fz, 0],
        [0, 0, 0, 1]
        ])
    },
    S:function (sx,sy,sz){
        return $M([
        [sx, 0, 0, 0],
        [0, sy, 0, 0],
        [0, 0, sz, 0],
        [0, 0, 0, 1]
        ])
    },
    P:function (x,y,z){
        return $M([
        [x],
        [y],
        [z],
        [1]
        ])

    }

}

transClass=function (cfg_data){
    this.transinfo_field_to_world=function (jdata){
        w=jdata["environment_width"] //90.0,
        h=jdata["environment_height"]//61.0,
        d=1000
        tx=jdata["world2field_box_deviation"][0]
        ty=jdata["world2field_box_deviation"][1]
        tz=0
        ppmw=jdata["box_pixel_scale_size"][0]
        ppmh=jdata["box_pixel_scale_size"][1]
        ppmd=1

        rx=0
        ry=0
        rz=jdata["world2field_box_transfer_theta"]/180*np.PI

        fx=jdata["world2field_sand_box_direction"][0]
        fy=jdata["world2field_sand_box_direction"][1]
        fz=1
        //翻转
        const m = mtx.F(fx,fy,fz); //F(1,1,1); //
        //放缩
        const m2 = mtx.S(1.0/ppmw ,1.0/ppmh ,1.0/ppmd );
        //位移
        const m4 = mtx.T(tx,ty,tz);
        //旋转矩阵
        const m3 = mtx.Rz(rz);
        //console.log ("m2---------");
        //console.log (m2);
        //console.log ("m3---------");
        //console.log (m3);
        //console.log ("m4---------");
        //console.log (m4);
        var tm=m2.x(m);
        tm=m3.x(tm);
        tm=m4.x(tm);


        return {
                    mat_px2m:tm,
                    mat_m2px:tm.inverse(),
                    theta_px2m:-rz,
                    theta_m2px:rz,
                    scale_px2m:(1.0/ppmw +1.0/ppmh)/2,
                    scale_m2px:(ppmw +ppmh)/2
                }
        //console.log ("m4 .m3 .m2 . m");
    }

    this.trans_info=this.transinfo_field_to_world(cfg_data);
    this.chk_min=function(v,m){
        return v<m?m:v
    }
    this.chk_max=function (v,m){
        return v>m?m:v
    }
    this.px2m_point=function(x,y,z){
        p=mtx.P(x,y,z);
        v=this.trans_info.mat_px2m.x(p).col(1);
        console.log ("px2m v");
        console.log (v);
        return {x:v.e(1),y:v.e(2),z:v.e(3)}

    }
    this.m2px_point=function(x,y,z){
        p=mtx.P(x,y,z)
        v=this.trans_info.mat_m2px.x(p).col(1);
        return {x:v.e(1),y:v.e(2),z:v.e(3)}
    }
    this.m2px_lenth=function(m){
        v=this.trans_info.scale_m2px*m
        return v
    }
    this.px2m_lenth=function(px){
        v=this.trans_info.scale_px2m*px
        return v
    }
    this.px2m_theta=function(a){
        v=this.trans_info.theta_px2m+a
        return v
    }
    this.m2px_theta=function(a){
        v=this.trans_info.theta_m2px+a
        return v
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>transClass</title>
</head>
<body>

    <script type="text/javascript" src="sylvester.js"></script>
    <script type="text/javascript" src="env_params_config.js"></script>
    <script type="text/javascript" src="zzz_trans_class.js"></script>

    <script>

//实例化转换对象
trans=new transClass(cfg_data);

//像素到米(点)
pm=trans.px2m_point( 0,0,0)
console.log (pm); 
//米到像素(点)
pp=trans.m2px_point( pm.x,pm.y,pm.z)
console.log (pp); 
//像素到米(长度)
lm=trans.px2m_lenth( 26)
console.log (lm); 
//米到像素(长度)
lpx=trans.m2px_lenth( lm)
console.log (lpx); 
//米到像素(弧度)
apx=trans.m2px_theta( 3.14)
console.log (apx); 
//像素到米(弧度)
am=trans.px2m_theta( apx)
console.log (am); 
//米到像素(点)
pp=trans.m2px_point( 0,0,0)
console.log (pp); 

    </script>


</body>
</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值