-
-
Notifications
You must be signed in to change notification settings - Fork 63
Document reflected wing meshing logic #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
73e926b
9db0c79
e81cf5c
f667a20
e847a7c
a48ac82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -157,6 +157,7 @@ def mesh_wing(wing: wing_mod.Wing) -> None: | |
| ] | ||
| ) | ||
|
|
||
| # Iterate through the Panels and populate their local position attributes. | ||
| Flpp_G_Cg = Fipp_G_Cg | ||
| Frpp_G_Cg = Fopp_G_Cg | ||
| Blpp_G_Cg = Bipp_G_Cg | ||
|
|
@@ -266,25 +267,45 @@ def mesh_wing(wing: wing_mod.Wing) -> None: | |
| ] | ||
| ) | ||
|
|
||
| # TODO: Understand how this block of code works. We're reflecting about a | ||
| # plane defined by a normal vector in geometry axes and a point in | ||
| # geometry axes relative to the CG. But that's okay I guess and we end | ||
| # up with reflected points in wing axes relative to the leading edge | ||
| # root point? Also then we perform an passive transformation to find | ||
| # them in geometry axes relative to the CG? Why do we even need to | ||
| # reflect them if we are staying in wing axes? If we take a reflected a | ||
| # non reflected Wing that are otherwise identical, they should have the | ||
| # same coordinates in their respective wing axes relative to their | ||
| # respective leading edge root points. So why is the active | ||
| # transformation necessary? | ||
| # DOCUMENT: Document the logic in this block of code. | ||
| # -------------------------------------------------------------------------- | ||
| # Mirroring this wing section across the airplane's plane of symmetry. | ||
| # | ||
| # Why an ACTIVE transformation is required here, and not | ||
| # just a passive change of reference frame: | ||
| # | ||
| # Expressed in their own local wing axes, relative to their own leading-edge | ||
| # root points, a wing and its mirror image DO have identical coordinates -- | ||
| # that is exactly what "mirror image" means, and it's why a symmetric wing | ||
| # only needs to be defined once with a `symmetric` flag. | ||
| # | ||
| # But the two wings do not exist in isolation; they must be placed together | ||
| # into one shared geometry frame relative to the airplane's CG so the solver | ||
| # can treat them as a single airframe. The mirrored wing's leading-edge root | ||
| # point and orientation (sweep, dihedral, incidence) are derived from the | ||
| # original wing's attributes. | ||
| # | ||
| # A reflection is an IMPROPER transformation (determinant -1) that flips | ||
| # handedness/chirality. A rotation or translation is a PROPER transformation | ||
| # (determinant +1) that preserves handedness. If we derived the mirrored wing's | ||
| # points using only a passive transformation, we would get a right-handed copy | ||
| # of the original wing just relocated -- meaning sweep, dihedral, twist, or | ||
| # camber would all carry the wrong geometric sign on the opposite side. | ||
| # Reflection is the only linear operation that genuinely inverts handedness | ||
| # to turn a right wing into a left wing. | ||
| # -------------------------------------------------------------------------- | ||
| assert symmetryPoint_G_Cg is not None | ||
| assert symmetryNormal_G is not None | ||
|
|
||
| # Step 1: Generate the active transformation reflection matrix based on the | ||
| # airplane's symmetry plane (defined in global geometry axes relative to CG). | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now We can make it consistent by re-expressing the plane in wing axes first (with the point relative to the leading edge root point), then building the reflection there, so the transformation and the vectors are in the same axis system. This needs (The two Optional follow-on: since the plane doesn't change between wing sections, these are section-invariant, so they can be hoisted above the With that hoisted, the per-section block drops the asserts and the |
||
| reflect_T_act = _transformations.generate_reflect_T( | ||
| plane_point_A_a=symmetryPoint_G_Cg, | ||
| plane_normal_A=symmetryNormal_G, | ||
| passive=False, | ||
| ) | ||
|
|
||
| # Step 2 (ACTIVE transformation): Mirror each local MCS point across the symmetry plane. | ||
| # This householder-like reflection explicitly flips the geometric handedness. | ||
| reflected_Fipp_Wn_Ler = _transformations.apply_T_to_vectors( | ||
| reflect_T_act, Fipp_Wn_Ler, is_position=True | ||
| ) | ||
|
|
@@ -297,6 +318,9 @@ def mesh_wing(wing: wing_mod.Wing) -> None: | |
| reflected_Bopp_Wn_Ler = _transformations.apply_T_to_vectors( | ||
| reflect_T_act, Bopp_Wn_Ler, is_position=True | ||
| ) | ||
|
|
||
| # Step 3 (PASSIVE transformation): Re-express the now-reflected points from local | ||
| # wing axes into the global geometry axes frame relative to the CG. | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "global geometry axes frame" should just be "global geometry axes" or even just "geometry axes". |
||
| reflected_Fipp_G_Cg = _transformations.apply_T_to_vectors( | ||
| T_pas_Wn_Ler_to_G_Cg, reflected_Fipp_Wn_Ler, is_position=True | ||
| ) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Say "one shared geometry axis system" instead of "one shared geometry frame." This is a nit pick, but to avoid confusion, Ptera Software tries to be very specific about the language used when referring to axes, points, and frames. Quoting from
docs/AXES_POINTS_AND_FRAMES.md: