Skip to content
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

Complex/number plane axes tips & ticks #3624

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

lambdadotjoburg
Copy link

@lambdadotjoburg lambdadotjoburg commented Feb 16, 2024

Overview: What does this pull request change?

This commit updates the behavior of NumberPlane and ComplexPlane Mobjects axes tips, by defining a new attribute include_tips (note* plural) inside the axis_config argument for displaying the leftmost & rightmost tips without distorting/stretching the ticks along the axes.

Note the updated code files number_line.py & arc.py may have some code redundancies

Motivation and Explanation: Why and how do your changes improve the library?

Links to added or changed documentation pages

Further Information and Comments

Works for ComplexPlane, NumberPlane & NumberLine.
No need to define such behavior for Axes, because the ticks are not distorted when including leftmost tip using other "rudimentary" methods

The attribute include_tips = True is simple to use.
Avoid using include_tips=True in conjunction with include_tip (use one or the other) since this will create a double arrow-head on one of the sides of an axis

Below is an illustration of the output using a ComplexPlane Mobject that distorts the ticks along the x- and y-axes. See the code below, with certain parts that can be uncommented to achieve the desired effect:

Distorted

Below is an illustration of the output using a ComplexPlane Mobject with the added attribute include_tips showing that the axes ticks are aligned with the NumberPlane grid (lines parallel to the axes)

ComplexPlaneExample_ManimCE_v0 18 0

Here's the code snippet that produces this output:

`

  class ComplexPlaneExample(Scene):

      def construct(self):  

          xrange = [-2,5]
          yrange = [-5,2]          

          plane = ComplexPlane(  
              x_range=xrange,
              y_range=yrange,       
                 
              axis_config={                    
                  # "include_numbers": True,
                  "tip_width": 0.15,
                  "tip_height": 0.15,
                  "include_ticks": True,
                  # "tick_size": 0,                    
                  # "include_numbers": True,
                  # "include_tip": True, # Add a tip to x-axis and y-axis
                  "include_tips": True, # This is the newly defined atrribute
             }              

         ).add_coordinates()

         self.add(plane)
      
         d1 = Dot(plane.n2p(2 + 1j), color=YELLOW)
         d2 = Dot(plane.n2p(-3 - 2j), color=YELLOW)
      
         label1 = MathTex("2+i").next_to(d1, UR, 0.1)
         label2 = MathTex("-3-2i").next_to(d2, UR, 0.1)

         # y_axis = plane.get_axes()[1]
         # y_axis.add_tip(at_start=True, tip_width=0.15, tip_length=0.15)

         # x_axis = plane.get_axes()[0]
         # x_axis.add_tip(at_start=True, tip_width=0.15, tip_length=0.15)
      
         self.add(
             d1,
             label1,
             d2,
             label2,
         )

`

Here's a screenshot of a way to manipulate Axes Mobjects left/right tips which does not work exactly the same for NumberPlane and ComplexPlane Mobjects, which is the motive for this commit:

AxesTipsDiscord

In the above case, the leftmost tip shape, width and height does not inherit from the rightmost tip, but can easily be manipulated using code below, by toggling some of the comments:

However, this functionality applies only to Axes Mobjects, not NumberPlane and ComplexPlane, thus, the proposed change is very relevant and can hopefully be merged into existing manim CE master

`

        class AxesTips(Scene):

             def construct(self):

                 axes = Axes(

                     x_range=[-2,5],
                     y_range=[-5,2],            

                    axis_config={
                         "include_numbers": True,
                         "tip_width": 0.15,
                         "tip_height": 0.15,
                         "include_ticks": True,
                         "tick_size": 0.1,
                         "include_numbers": True,
                         # "include_tip": True, # Add a tip to end of  x-axis and end of y-axis
                         "include_tips": True,
                   },

               )

            # # Add a tip to start of x-axis
            # axes[0].add_tip(at_start=True, tip_width=0.15, tip_length=0.15)
            # # Add a tip to start of y-axis
            # axes[1].add_tip(at_start=True, tip_width=0.15, tip_length=0.15)

           # x_axis_ticks = axes[0].get_tick_marks()
           # print(x_axis_ticks)

          # x_axis_leftmost_tick = axes[0].get_tick_marks()[0]
          # print(x_axis_leftmost_tick)

          # x_axis_ticks -=  x_axis_leftmost_tick
       
          # y_axis_ticks = axes[1].get_tick_marks()
          # print(y_axis_ticks)

         # y_axis_leftmost_tick = axes[1].get_tick_marks()[0]
         # print(y_axis_leftmost_tick)

         # y_axis_ticks -=  y_axis_leftmost_tick
    
    
         # Add Axes object to Scene Object        
         self.add(axes)

`

Reviewer Checklist

  • The PR title is descriptive enough for the changelog, and the PR is labeled correctly
  • If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
  • If applicable: newly added functions and classes are tested

lambdadotjoburg and others added 3 commits February 16, 2024 15:42
Add attribute `inlcude_tips` (note* plural), initialize variable `self.include_tips = include_tips` add a check `if self.include_tips` and perform appropriate logic which invokes the function `add_tip_opposite_end` on self while preserving the parameters (tip_shape, tip_height, tip_width) of the original/right-most tip as well as the stroke and finaly setting `x_max` and `x_min` based on `self.include_tip` or `self.include_tips`
Define a new function `add_tip_opposite_end` to allow the user to specify the `include_tips` attribute in the NumberLine __inint__() method.
@MrDiver
Copy link
Collaborator

MrDiver commented Apr 1, 2024

It seems to me more like patching on top of a problem which sits on NumberLine itself.
I am not quite sure if this behavior is an error in itself.
Imagine the testcase that you create a coordinate system with tips, the elements displayed inside that coordinate system are now not lining up with the ticks of the NumberLine.

Therefore, i think that there is some discussion needed if we want to change the default behavior in this case because adding another parameter to "fix" the scaling seems like a very confusing solution for the future, especially with the naming.

Maybe rethinking how the tips work might be a good idea here.

@MrDiver MrDiver added pr:bugfix Bug fix for use in PRs solving a specific issue:bug needs discussion Things which needs to be discussed before implemented. labels Apr 1, 2024
@lambdadotjoburg
Copy link
Author

lambdadotjoburg commented Apr 1, 2024

@MrDiver

I don't think it's necessary to change the default behavior, but I believe manim is designed with the goal in mind to be flexible, easy-to-use and easy-to-understand.

You are entirely correct that a deeper problem persists with the NumberLine MObject in that the elements are shifted/scaled ever-so-slightly "off grid" (can't figure out exactly to what degree)

But this is most likely the exact cause of the distortion-issue, i.e. the NumberLine with a tip included on either end scales the new grouped MObjects length ever-so-slightly which causes this misalignment with "grid" MObjects (Axes, NumberPlane, ComplexPlane, ...)

To fix this issue, may be ten times more challenging than the proposed changes. I suspect that excluding the length of the arrow tip on the grouped NumberLine MObjects, should give back the default behavior, but I am not entirely sure where would we start with that,

So I believe this "patchy" solution isn't all that bad, from manim users' perspective, although changes may break it in the future - until we can come up with an improved mechanism to deal with the underlying NumberLine-distortion issue.

@behackl
Copy link
Member

behackl commented Apr 24, 2024

Instead of a separate keyword argument, I feel a modification of include_tip to take either just a bool (which keeps the current behavior), or a tuple (bool, bool) which can be used to toggle the tips at either end of a NumberLine might be a better solution (in particular because it avoids the possibility of an option clash here).

What do you think about that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs discussion Things which needs to be discussed before implemented. pr:bugfix Bug fix for use in PRs solving a specific issue:bug
Projects
Status: 🆕 New
Development

Successfully merging this pull request may close these issues.

None yet

3 participants