M3G内坐标系作用范围的混淆

M3G坐标系的混淆
mesh.translate(0.0f, 0.0f, 5.0f);
transform.postTranslate(0.0f, 0.0f, 5.0f);
mesh.setTransform(transform)
有什么区别?
答案:第一个是以mesh的父坐标系为基准,沿着父坐标系的Z轴平移
而第二个是以物体局部坐标系的Z轴移动,如果这个局部的Z轴经过了旋转,那就会沿着新的局部Z轴进行平移。
 
附M3G其它一些translate和rotate的规则说明:
---------------------------------------------------------------------------------------
Transformable:
postRotate(float angle, float ax, float ay, float az)
translate(float tx, float ty, float tz)
 
Transform:
postRotate(float angle, float ax, float ay, float az)
postTranslate(float tx, float ty, float tz)
 
mesh.postRotate(3.0f, 1.0f, 0.0f, 0.0f);
When rotation is made directly on the transformable object the rotation will be made around the origo of the local co-ordinate system(局部坐标系的原点).
 
transform.postRotate(3.0f, 1.0f, 0.0f, 0.0f);
mesh.setTransform(transform);

When the rotation is made using the transform class the object will rotate around its center(物体中心:取决于建模是规定的中心点,不一定是局部坐标系的原点).
 
mesh.translate(0.0f, 0.0f, 5.0f);
When the object is moved using methods in the transformable class the object is moved in the co-ordinate system of the parent node(父节点坐标系).
 
transform.postTranslate(0.0f, 0.0f, 5.0f);
mesh.setTransform(transform)

When the object is moved using the transform class the object is moved in the local co-ordinate system(局部坐标系).
----------------------------updated 2007-01-18--------------------------------
比如,我的
Camera cam;
Group camGroup;
在loadCamera时,
cam.translate(0.0f, 5.0f, 10.0f);
camGroup.addChild(cam);
world.addChild(camGroup);
那么在对相机进行旋转时,就需要操作camGroup,如果操作cam,则会导致translate的叠加效应
在平移时
如果camGroup.translate,则会导致camGroup在它父结点坐标系,也就是world的轴方向进行平移
如果要在相机局部坐标系下进行平移,则需要
cam.translate
 
import numpy as np import pandas as pd # 设置Matplotlib后端为Agg import matplotlib matplotlib.use('Agg') # 添加这行代码 import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.feature as cfeature # plt.ion() # 注释掉这行,因为使用Agg后端时不需要交互模式 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 # 统一调整字体格式 plt.rcParams plt.rcParams['font.family'] = 'Times New Roman' plt.rcParams['font.weight'] = 'heavy' # *****************month average AOD***************** input_dir = r'F:\000PythonProject\data\3yuepinjun\data' output_dir = r'F:\000PythonProject\data\3yuepinjun' input_dir1 = r'F:\000PythonProject\data\3yuepinjun' input_file_AGRI = [input_dir + '/AGRI_M3.A202309.06111.csv', input_dir + '/AGRI_M3.A202310.06111.csv', input_dir + '/AGRI_M3.A202311.06111.csv', input_dir + '/AGRI_M3.A202312.06111.csv'] input_file_MOD = [input_dir + '/MYD08_M3.A202309.0611.csv', input_dir + '/MYD08_M3.A202310.0611.csv', input_dir + '/MYD08_M3.A202311.0611.csv', input_dir + '/MYD08_M3.A202312.0611.csv'] input_file_OCA = [input_dir + '/OCA_M3.A202309.06111.csv', input_dir + '/OCA_M3.A202310.06111.csv', input_dir + '/OCA_M3.A202311.06111.csv', input_dir + '/OCA_M3.A202312.06111.csv'] output_file = [output_dir + '/MonthAverage_AGRI_MODIS_OCA_M3AOD550_09.png', output_dir + '/MonthAverage_AGRI_MODIS_OCA_M3AOD550_10.png', output_dir + '/MonthAverage_AGRI_MODIS_OCA_M3AOD550_11.png', output_dir + '/MonthAverage_AGRI_MODIS_OCA_M3AOD550_12.png'] month = ['Sep 2023', 'Oct 2023', 'Nov 2023', 'Dec 2023'] sign_MOD = ['a-1', 'a-2', 'a-3', 'a-4'] sign_MER = ['b-1', 'b-2', 'b-3', 'b-4'] sign_OCA = ['c-1', 'c-2', 'c-3', 'c-4'] LON_file = input_dir1 + '/lon.csv' LAT_file = input_dir1 + '/lat.csv' data = pd.read_csv(LON_file, header=None) lon = data.values data = pd.read_csv(LAT_file, header=None) lat = data.values def map_month_average(input_file, fig, location, sensor_name, sign, month, lon, lat): # read AOD data = pd.read_csv(input_file, header=None) data = data.values AODQA550 = data * 0.001 AODQA550[AODQA550 < 0] = np.nan LON, LAT = np.meshgrid(lon[:], lat[:]) #lat[::-1] # 翻转纬度,使其从 -90 到 90 # map proj = ccrs.PlateCarree(central_longitude=180) leftlon, rightlon, lowerlat, upperlat = (40, 220, -75, 75) extent = [leftlon, rightlon, lowerlat, upperlat] fig1 = fig.add_axes(location, projection=proj) # [左,下,宽度,高度] # 绘制地图 fig1.set_extent(extent, crs=ccrs.PlateCarree()) # 海岸线,50m精度 fig1.add_feature(cfeature.COASTLINE.with_scale('50m'), lw=0.7) #线宽0.7 fig1.add_feature(cfeature.OCEAN, color='aliceblue') fig1.add_feature(cfeature.LAND, color='aliceblue') # 添加网格 fig1.gridlines(linestyle='--', xlocs=np.arange(40, 220, 30)) con = plt.contourf(LON, LAT, AODQA550, np.arange(0, 1.01, 0.001), cmap='jet', vmin=0, vmax=1) print(con) font = {'family': 'Times New Roman', 'weight': 'heavy', 'size': 14} plt.title('Average_Ocean_AOD', font, loc='center') plt.title(sensor_name, font, loc='left') plt.title(month, font, loc='right') plt.text(0.02, 0.9, sign, fontsize=30, style='normal', transform=plt.gca().transAxes) for i in range(4): # figsize=(a, b),figsize用来设置图形的大小,a为图形的宽, b为图形的高 fig = plt.figure(figsize=(20, 15)) location = [0.09, 0.2, 0.4, 0.3] sensor_name = 'MODIS DT' map_month_average(input_file_MOD[i], fig, location, sensor_name, sign_MOD[i], month[i], lon, lat) location = [0.39, 0.2, 0.4, 0.3] sensor_name = 'AGRI DT' map_month_average(input_file_AGRI[i], fig, location, sensor_name, sign_MER[i], month[i], lon, lat) location = [0.69, 0.2, 0.4, 0.3] sensor_name = 'OCA' map_month_average(input_file_OCA[i], fig, location, sensor_name, sign_OCA[i], month[i], lon, lat) if (i == 3): rect = [0.295, 0.175, 0.6, 0.015] # colorbar 左 下 宽 高 cbar_ax = fig.add_axes(rect) cb = plt.colorbar(cax=cbar_ax, orientation="horizontal") cb.ax.tick_params(direction='in') cb.ax.tick_params(labelsize=15) # 设置色标刻度字体大小。 cb.set_ticks([0.0, 0.2, 0.4, 0.6, 0.8, 1.0]) plt.savefig(output_file[i], bbox_inches='tight', dpi=300) plt.close(fig) # 保存后关闭图形,释放内存 # plt.show() # 注释掉这行,因为使用Agg后端时不需要显示图形。修改后的完整代码给我,纬度范围-75到75,20度一个间隔,经度范围40到220,30度一个间隔
07-07
# -*- coding: utf-8 -*- """ Python 河流—流域—通量计算(仅从流向开始重算) 已知:dem_filled.tif(填洼后的 DEM)和 dir.tif(流向栅格) 下一步:汇流累积、流域提取、加权累积和通量计算 """ import os import rasterio import numpy as np from pysheds.grid import Grid import geopandas as gpd import warnings warnings.filterwarnings('ignore', category=UserWarning) # 忽略PySheds的警告 # —— 配置 —— # OUT_DIR = r"D:\JW\BaiduSyncdisk\数据\SZML\全国站点逐日气象数据\气候数据GIS" # 正确示例:使用 rasterio 读取实际数据 with rasterio.open(r"D:\JW\BaiduSyncdisk\数据\SZML\全国站点逐日气象数据\气候数据GIS\dir.tif") as src: flow_dir_tif = src.read(1) # 读取第一个波段 print(type(flow_dir_tif)) # <class 'numpy.ndarray'> # 降雨栅格路径(或插值后栅格) RAIN_PATH = r"C:\Users\ASUS\AppData\Local\Temp\processing_JnOHDT\6f39273e4b524aa5b6480838ce7c80f0\OUTPUT.tif" # 河网和海岸线矢量 RIVER_SHP = r"D:\JW\BaiduSyncdisk\数据\SZML\全国站点逐日气象数据\气候数据GIS\River.shp" COAST_SHP = r"D:\JW\ArcGIS\liu_10m_coastline\10m.shp" def main(): # 确保流域DEM文件存在 dem_filled = os.path.join(OUT_DIR, "dem_filled.tif") if not os.path.exists(dem_filled): raise FileNotFoundError(f"DEM文件不存在: {dem_filled}") # —— 1. 初始化 Grid 并读取流向 —— # grid = Grid() grid.read_raster(flow_dir_tif, data_name='dir') # 正确访问数据的方式:使用view()方法 fdir = grid.view('dir') # 返回Raster对象 print(f"流向数据加载成功,尺寸: {fdir.shape}") # —— 2. 汇流累积 —— # print("开始计算累积汇流量...") grid.accumulation(data='dir', out_name='acc') acc = grid.view('acc') # 获取累积量数据 acc_tif = os.path.join(OUT_DIR, "flow_accumulation.tif") grid.to_raster(acc_tif, data='acc') print(f"汇流累积完成: {acc_tif}, 最大值: {np.max(acc)}") # —— 3. 提取出口点 & 流域 —— # rivers = gpd.read_file(RIVER_SHP).to_crs("EPSG:4326") coast = gpd.read_file(COAST_SHP).to_crs("EPSG:4326") # 确保坐标系统一致 if rivers.crs != coast.crs: print("警告: 河流和海岸线坐标系统不一致,强制转换为WGS84") rivers = rivers.to_crs("EPSG:4326") coast = coast.to_crs("EPSG:4326") intsct = gpd.overlay(rivers, coast, how='intersection') if intsct.empty: # 尝试使用缓冲区寻找交点 print("未找到精确交点,尝试使用缓冲区方法...") buffered_coast = coast.buffer(0.01) # 1公里缓冲区 intsct = gpd.overlay(rivers, buffered_coast, how='intersection') if intsct.empty: raise RuntimeError("未找到河—海交点,请检查数据。") outlet_pt = intsct.geometry.iloc[0] x0, y0 = outlet_pt.x, outlet_pt.y print(f"出口坐标: ({x0:.6f}, {y0:.6f})") # 提取流域 grid.read_raster(dem_filled, data_name='dem') grid.catchment(x=x0, y=y0, data='dir', out_name='catch') catch = grid.view('catch') basin_tif = os.path.join(OUT_DIR, "basin.tif") grid.to_raster(basin_tif, data='catch') print(f"流域提取完成: {basin_tif}, 流域面积: {np.sum(catch)} 像素") # —— 4. 加权累积(体积) —— # with rasterio.open(RAIN_PATH) as src: rain = src.read(1) transform = src.transform crs = src.crs # 验证降雨数据与流向数据尺寸是否匹配 if rain.shape != fdir.shape: print(f"警告: 降雨数据尺寸({rain.shape})与流向数据({fdir.shape})不匹配") # 尝试调整尺寸 - 简单裁剪到流向数据尺寸 min_rows = min(rain.shape[0], fdir.shape[0]) min_cols = min(rain.shape[1], fdir.shape[1]) rain = rain[:min_rows, :min_cols] print(f"裁剪降雨数据到尺寸: {rain.shape}") # 像元面积 (m²) pix_area = abs(transform.a * transform.e) Cr = 0.5 # 径流系数 # 体积 Vi = rain(mm)*1e-3(m/mm)*pix_area runoff_vol = rain * Cr * 1e-3 * pix_area print("开始加权累积体积...") grid.accumulation(data='dir', out_name='flow_acc_vol', weights=runoff_vol) flow_acc_vol = grid.view('flow_acc_vol') flow_acc_tif = os.path.join(OUT_DIR, "flow_acc_volume.tif") grid.to_raster(flow_acc_tif, data='flow_acc_vol') print(f"加权累积完成: {flow_acc_tif}, 最大值: {np.max(flow_acc_vol):.2f} m³") # —— 5. 采样出口点通量 —— # # 获取出口点的像素坐标 row, col = grid.raster_to_pixel(x0, y0, data='flow_acc_vol') row, col = int(row), int(col) # 转换为整数索引 # 验证坐标是否在有效范围内 if 0 <= row < flow_acc_vol.shape[0] and 0 <= col < flow_acc_vol.shape[1]: V_total = flow_acc_vol[row, col] Q_m3s = V_total / 86400.0 print(f"出口累积体积 V = {V_total:.2f} m³, 日平均通量 Q = {Q_m3s:.3f} m³/s") else: print(f"警告: 出口点({row}, {col})超出栅格范围({flow_acc_vol.shape})") # 寻找最近的有效点 row = max(0, min(row, flow_acc_vol.shape[0] - 1)) col = max(0, min(col, flow_acc_vol.shape[1] - 1)) V_total = flow_acc_vol[row, col] Q_m3s = V_total / 86400.0 print(f"使用最近点({row}, {col}): V = {V_total:.2f} m³, Q = {Q_m3s:.3f} m³/s") if __name__ == '__main__': main()
最新发布
07-19
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值