こちらの続きです。
Fusion360APIのVecter3Dの外積を確認1 - C#ATIA
もう一つ違う方法で確認する事にしました。
適当なボディをクリックすると慣性モーメントを利用して、
重心やら軸やらを取得して、そこからマトリックスを作成し
可視化しました。
# Fusion360API Python script import traceback import adsk.fusion import adsk.core def run(context): ui: adsk.core.UserInterface = None try: app: adsk.core.Application = adsk.core.Application.get() ui = app.userInterface des: adsk.fusion.Design = app.activeProduct root: adsk.fusion.Component = des.rootComponent msg: str = 'Select' selFiltter: str = 'Bodies' sel: adsk.core.Selection = selectEnt(msg, selFiltter) if not sel: return # BRepBody body: adsk.fusion.BRepBody = sel.entity # Principal cog Axes physicalProp: adsk.fusion.PhysicalProperties = body.getPhysicalProperties() cog: adsk.core.Point3D = physicalProp.centerOfMass _, xAxis, yAxis, zAxis = physicalProp.getPrincipalAxes() mat1: adsk.core.Matrix3D = initMatrix3D_fromXZ(xAxis, zAxis, cog) dumpMatrix(root, mat1, 'mat1') mat2: adsk.core.Matrix3D = adsk.core.Matrix3D.create() mat2.setWithCoordinateSystem(cog, xAxis, yAxis, zAxis) dumpMatrix(root, mat2, 'mat2') except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) # 長さ X10Cm Y15Cm Z20Cm def dumpMatrix( comp: adsk.fusion.Component, mat: adsk.core.Matrix3D, name: str = ''): skt: adsk.fusion.Sketch = comp.sketches.add(comp.xYConstructionPlane) if name != '': skt.name = name pnt, vx, vy, vz = mat.getAsCoordinateSystem() vy.scaleBy(1.5) vz.scaleBy(2) for v in [vx, vy, vz]: p = pnt.copy() p.translateBy(v) skt.sketchCurves.sketchLines.addByTwoPoints( pnt, p ) def initMatrix3D_fromXZ( vecX: adsk.core.Vector3D, vecZ: adsk.core.Vector3D, cog: adsk.core.Point3D = None) -> adsk.core.Matrix3D: vecY: adsk.core.Vector3D = vecZ.crossProduct(vecX) vecX = vecZ.crossProduct(vecY) vecX.normalize() vecY.normalize() vecZ.normalize() if not cog: cog = adsk.core.Point3D.create(0, 0, 0) mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() mat.setWithCoordinateSystem( cog, vecX, vecY, vecZ ) return mat def selectEnt( msg: str, filtterStr: str) -> adsk.core.Selection: try: app = adsk.core.Application.get() ui = app.userInterface sel = ui.selectEntity(msg, filtterStr) return sel except: return None
こちらを実行すると、
mat1側は僕が作った関数から作ったマトリックスで
mat2側は慣性モーメントから素直に作ったマトリックスです。
mat1側が左手系です。・・・犯人は僕です。
仕方が無いので、関数を修正しました。
def initMatrix3D_fromXZ( vecX: adsk.core.Vector3D, vecZ: adsk.core.Vector3D, cog: adsk.core.Point3D = None) -> adsk.core.Matrix3D: vecY: adsk.core.Vector3D = vecZ.crossProduct(vecX) vecX = vecZ.crossProduct(vecY) if vecX.crossProduct(vecY).dotProduct(vecZ) < 0: vecX.scaleBy(-1) vecX.normalize() vecY.normalize() vecZ.normalize() if not cog: cog = adsk.core.Point3D.create(0, 0, 0) mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create() mat.setWithCoordinateSystem( cog, vecX, vecY, vecZ ) return mat
内積を利用して、1軸(X軸)だけ逆にしました。
恐らくこれでOKでしょう。
本題に戻れそう。