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

Add a sine wave tool to the graphtool. #1157

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from

Conversation

drgrice1
Copy link
Member

@drgrice1 drgrice1 commented Dec 6, 2024

The tool can be added by setting availableTools => [ 'SineWaveTool' ] in the ->with call when creating a GraphTool object. Of course other tools can be added in the list as well. The tool works by plotting three points. The first point determines the phase shift (or x translation) and y translation. The second point determines the amplitude. Note that point can only be moved horizontally, and is forced to always stay on the same horizontal line as the first point. The third point determines the amplitude. That point can only be moved vertically, and is forced to stay at the peak of the first crest of the sine wave. So if (x1, y1) is the first point, x2 the x-coordinate of the second point, and y3 the y-coordinate of the third point, then the function is f(x) = y3 * sin(2 * pi / x2 * (x - x1)) + y1.

An example problem is attached: GraphSineWavePi.pg.txt

There are several new GraphTool options added to make it so that the axis labels can be multiples of pi. They are scaleX, scaleY, scaleSymbolX, and scaleSymbolY. The "scale" options are the scale of the ticks on the x and y axes. That is the distance between two successive ticks on the axis (including both major and minor ticks). The "scaleSymbol" options are the scale symbols for the ticks on the x and y axes. The labels on the axis will be shown as multiples of this symbol.

These options can be used in combination to show tick labels at multiples of pi by using the settings scaleX => pi->value and scaleSymbolX => '\pi'.

The coordinate hints in the lower right corner have also been updated to use these options if set.

Also make the axis tick labels be shown according to the coordinateHintsType settings. This reworks the coordinate hints code considerably. The JSXGraph formatLabelText method of the default axes ticks is overriden so that tick labels can be formatted according to our coordinateHintsType settings. Note that there is a JSXGraph tick label toFraction option that is similar and is used in the default formatLabelText method, but it always uses mixed numbers. Furthermore, the scaleSymbol is included in what is typeset by MathJax (the default method does not do this). This looks better and also means that instead of needing to use the unicode symbol for pi, the LaTeX \pi command can be used instead. Note that MathJax actually supports the unicode symbol and typesets it the same as \pi. So if the coordinateHintsType setting is 'mixed' then both the coordinate hints shown in the lower right corner of the graph (or upper left for number lines) and the labels on the axes will be shown as mixed numbers, and if the setting is 'fraction' then both will be displayed as improper fractions, and with the default 'decimal' setting both will be decimals. Note that the useMathJax: true and display: 'html' settings are now set for the axes tick labels so that fractions are displayed typeset by MathJax. Note that this is stated for the coordinateHintsType setting, but really applies to the coordinateHintsTypeX and coordinateHintsTypeY settings as well for per coordinate and axis behavior.

Now the coordinateHintsType settings are perhaps not appropriately named since they apply to more than just the coordinate hints, and also apply to axis labels. But I don't feel like adding another setting for this and consistency between the hint coordinates and axis labels is better.

The JSXGraph generateLabelText method of the axes ticks is also overridden so that zero is also typeset using MathJax. The default JSXGraph method never does this even if the other labels are typeset using MathJax and gives an inconsistent appearance in that case.

Add a way for a graph object to add to the help. A graph object can only add to the help when it is selected. The help is also updated when focus moves within the object to different defining points. So the graph object can give a different message depending on which point is focused. The sine wave tool uses this to let the user know restrictions on how the focused point can move.

There is a general and minor change to some other graph objects. The "down", "up", and "drag" handlers are no longer attached to static graph object points. For most objects this doesn't matter because the points are hidden. So the points can't be clicked on or dragged in any case. However, for the "fill" graph object the paint bucket icon is still visible for static fill objects, and then clicking on the icon you see the mouse cursor disappear. The icon still can't be dragged because it is fixed, but the cursor disappearing sort of indicates that the icon has been grabbed for a drag which is somewhat counter intuitive when you can't actually do so. These handlers aren't needed for static objects in any case.

Note that JSXGraph is updated to the latest version.

@drgrice1 drgrice1 force-pushed the graphtool-sine-wave branch 2 times, most recently from 2d8005b to 13e3cb3 Compare December 11, 2024 12:56
@Alex-Jordan
Copy link
Contributor

This will be a nice addition to the graph tool. In testing with the sample problem, I found some issues. Some feel like some sort of jxsgraph quirk.

Something strange happens with the sample problem when you try to use one of the points on the left or right edge of the grid. You can move the mouse to select a point there, and the coordinate hints will indicate you are there at the edge. For example, at (8π, something). But it won't be showing a highlighted dot there. It will show a highlighted dot at (15/2 π, something instead).

If I plot the first point somewhere, as I move the mouse around, the coordinate hints show where my mouse actually is, instead of showing the coordinates of the second (or third) point I am trying to pin down. Can this be made to show the coordinates of the restricted second dot you are trying to select? (And then for the third dot too, which is restricted vertically?)

If I select the first dot at say (0,0), and then move the mouse to (0,0), a second dot remains visible at (1/2 π,0). But clicking, nothing happens. It is maybe confusing to see that dot at (1/2 π,0) and think you are at a place where you can hammer in the second point, but it won't let you.

Perhaps related to things already mentioned. If I select the first dot at (15/2 π, 0), then move the mouse to (8π, 0), the sine wave that I see has a long period of 12π instead of the period π/2 I would expect. Then when I click to hammer that in, it switches to a wave with period π/2.

@drgrice1
Copy link
Member Author

Something strange happens with the sample problem when you try to use one of the points on the left or right edge of the grid. You can move the mouse to select a point there, and the coordinate hints will indicate you are there at the edge. For example, at (8π, something). But it won't be showing a highlighted dot there. It will show a highlighted dot at (15/2 π, something instead).

This is something that I noticed recently as well. This is not how it used to work, and I think that something has changed with JSXGraph that is causing this. It used to be the case that you could place points on the edge, and it would all work intuitively. I messed with it a little bit to see if I could fix it, but ended up putting that off for now. Note that this happens with all of the tools and not just the new sine wave tool, and seems to not happen with certain board dimensions. For instance if the bBox is set to [-10, 10, 10, -10] with the defaults for all of the other options, then it works fine.

If I plot the first point somewhere, as I move the mouse around, the coordinate hints show where my mouse actually is, instead of showing the coordinates of the second (or third) point I am trying to pin down. Can this be made to show the coordinates of the restricted second dot you are trying to select? (And then for the third dot too, which is restricted vertically?)

I missed this. It should show the coordinates of the highlight point, but for some reason that isn't working right. I will look into it. This is actually something I have fought with quite a bit over the years. JSXGraph keeps changing something that messes with this.

If I select the first dot at say (0,0), and then move the mouse to (0,0), a second dot remains visible at (1/2 π,0). But clicking, nothing happens. It is maybe confusing to see that dot at (1/2 π,0) and think you are at a place where you can hammer in the second point, but it won't let you.

I will see if there is anything that can be done about this. This works the same way that the other tools do, in that it doesn't allow the second point to be placed where the first is, and it is tricky to deal with when the mouse cursor is out of place. This seems to be made worse by the previous issue you mentioned and that fact that the coordinates shown are incorrect. They shouldn't show (0,0) ever while graphing the second point if that is where the first point is.

Perhaps related to things already mentioned. If I select the first dot at (15/2 π, 0), then move the mouse to (8π, 0), the sine wave that I see has a long period of 12π instead of the period π/2 I would expect. Then when I click to hammer that in, it switches to a wave with period π/2.

This seems to really be something to do with the first issue you mentioned. If that issue is fixed, then this one will most likely be resolved also.

@Alex-Jordan
Copy link
Contributor

Alex-Jordan commented Dec 12, 2024 via email

@drgrice1
Copy link
Member Author

That isn't really something that can be done.

@Alex-Jordan
Copy link
Contributor

Alex-Jordan commented Dec 12, 2024 via email

@drgrice1
Copy link
Member Author

I mean that it isn't something that JSXGraph supports.

@drgrice1
Copy link
Member Author

I mean, you can't just change the bounding box. That would mess things up visually, and many other things in the code as well.

@drgrice1
Copy link
Member Author

The second and third issues you listed are now fixed.

The coordinate hints show the coordinates of the point being graphed. That was easy. I just forgot to return true from the updateHighlights method to tell the general graphtool down handler not to also set the coordinates.

The other I implemented a better way than just refusing to plot a point when a click occurs when the coordinates are in an invalid location. It just plots the point where it is shown in that case instead. This needs to be done for all of the tools though, and not just the new sine wave tool.

@drgrice1 drgrice1 force-pushed the graphtool-sine-wave branch from bb35b3e to 8dfd032 Compare December 12, 2024 02:59
@drgrice1
Copy link
Member Author

So the issue seems to be a precision issue with the bounding box, snap size, and scaleX settings in the problem. If you instead set $pi = Round(pi->value, 6) in the PG problem, then you can move the point to the edge of the board.

@drgrice1
Copy link
Member Author

Although that doesn't explain the issue with a bounding box of [-11, 11, 11, -11] and default settings for everything else. For some reason with that you can move to the left and top edge of the board, but not to the right or bottom edge. This is something that did work before.

@drgrice1
Copy link
Member Author

Well, at some point before. Not sure when it starting not working.

@Alex-Jordan
Copy link
Contributor

There is a line in parserGraphTool.pl that is part of converting the perl struction to JSON:

boundingBox => $self->{bBox},

I am suggesting replace that line with:

boundingBox => $self->getBoundingBox,

and add the subroutine:

sub getBoundingBox {
       my $self = shift;
       my ($xmin, $ymax, $xmax, $ymin) = @{$self->{bBox}};
       my $snapSizeX = $self->{snapSizeX};
       my $snapSizeY = $self->{snapSizeY};
       $xmin -= 0.1*$snapSizeX;
       $xmax += 0.1*$snapSizeX;
       $ymin -= 0.1*$snapSizeY;
       $ymax += 0.1*$snapSizeY;
       return [$xmin, $ymax, $xmax, $ymin];
}

The author's bBox is still in $self and is used for other things. But as I reviewed where it is used, I did not see an issue where this would cause harm. It's just intervening to make the jsxgraph "boundinBox" something slightly different than the author's bBox. Everything jsxgraph will use that for is now based on the altered "boundinBox".

@drgrice1
Copy link
Member Author

Actually, your idea about adjusting the bounding box may work. If you add JXG.Math.eps to the ranges on each end, it doesn't mess things up visually, and it seems to fix the issue. Note that JXG.Math.eps is defined to be 0.000001. I don't think using a multiple of the snap size would be a good idea though. JSXGraph considers anything smaller than JXG.Math.eps to be zero.

As I am typing this I see your last comment. It isn't a good idea to do this in the Perl portion of the code. It should be done in the JavaScript, and not use something so large as 0.1.

@drgrice1
Copy link
Member Author

This is a quick fix for now. I will look into it more. I am still not satisfied with enlarging the bounding box in this way. It could have other bad consequences.

@Alex-Jordan
Copy link
Contributor

I pulled and those two issues are resolved as described. I like that solution to the issue where the mouse is over an illegal point.

Now I am seeing a new issue (maybe it was there before but I missed it). When I load the sample problem, I see:
Screenshot 2024-12-11 at 7 59 52 PM

Note the position of the "2π" label is off. As soon as I click a tool, the labels shift and now I see the labels placed well:
Screenshot 2024-12-11 at 7 59 59 PM

@drgrice1
Copy link
Member Author

Do you have MathJax accessibility activated by chance? I had the same issue when I had that activated. The problem went away when I disabled MathJax accessibility. I don't know how to fix that.

@drgrice1
Copy link
Member Author

By the way, MathJax seems to have a bug with the accessibility settings. Once you activate them, you can not deactivate them. When you click on the checked "Activate" item in the MathJax menu, there are console log errors and it is not unchecked. The only way I have found to deactivate them is to go into the developer tools and delete the key that MathJax sets in local storage for this.

@Alex-Jordan
Copy link
Contributor

Yes, that is it. If I turn off MathJax accessibility and reload the problem, the labeling is not off. Did you only see this with the new feature using multiples of pi as axis labels? In other words, is there a way to see this issue on develop right now? I could post an issue and ping Davide if he has insight about it.

@drgrice1
Copy link
Member Author

It is only an issue with using MathJax for the axis labels. It won't happen with the develop branch since it doesn't use MathJax for the axis labels.

@drgrice1
Copy link
Member Author

Note the issue with MathJax and its menu and not being able to disable accessibility is not related to JSXGraph or the graphtool at all though.

@Alex-Jordan
Copy link
Contributor

OK, I had some trouble turning it off like you say. But I eventually got it off, and I didn't have to resort to going into the console. I can't repeat what I did though...

@drgrice1
Copy link
Member Author

The menu issue seems to be specific to Firefox. I just tried it in Chrome and didn't have the issue.

@Alex-Jordan
Copy link
Contributor

I'm not having the same trouble turning off accessibility in a regular problem. Only (for now) in the problem editor. Could it be something about that endpoint or the iframe?

@drgrice1
Copy link
Member Author

Although in Chrome when I activate accessibility the rendered MathJax element that I clicked on to open the menu disappears.

I am doing this testing in a problem in a set. Not sure if things are different in an iframe on the problem editor page.

@Alex-Jordan
Copy link
Contributor

OK, well there is a separate mystery to pursue. I'll leave it out of this thread, sorry for the clutter.

@drgrice1
Copy link
Member Author

For the label positioning, if it is an issue, then we can switch back and not use MathJax for the labes. Then the unicode pi symbol would have to be used instead, and you have to add that either by using ~~ and the control code or cutting and pasting the unicode pi into the code.

@drgrice1
Copy link
Member Author

The unicode pi doesn't look as nice as the MathJax pi though.

@Alex-Jordan
Copy link
Contributor

I think we should leave it as you made it, and separately pursue what the issue is with MathJax, perhaps with help from Davide.

@drgrice1
Copy link
Member Author

drgrice1 commented Dec 12, 2024

Okay. Good. I remembered the other issue with not using MathJax. Then fractions would be displayed as 15/2 or you need to switch back to decimals and get 7.5. So with pi you get either 15/2π or 7.5pi instead of $\frac{15}{2}\pi$.

@Alex-Jordan
Copy link
Contributor

It's more than just π. Now you will be able to make an axis with, for example \sqrt{2}, 2\sqrt{2}, ... And other things not possible with unicode.

@drgrice1
Copy link
Member Author

True. MathJax with the scaleSymbol settings do offer many more possibilities for nicely displaying a much wider variety of labels.

@drgrice1
Copy link
Member Author

I updated the existing graph tools with the changes made for the sine wave tool.

So now all of the tools switch to using the highlight point coordinates instead of refusing to plot a point. This is a massive improvement for the quadratic and cubic plotting tools. The issue you saw with the click not doing anything is really easy to make happen with those tools. With the quadratic tool if you plot three points on three consecutive vertical lines, then while graphing the fourth point anytime that you are in between the vertical lines of the previously graphed points you could click all you wanted to and nothing would happen. I have known about this issue for a while, and should have though of this solution sooner.

Also, don't compare floating point numbers with ==. That is always troublesome.

@drgrice1 drgrice1 force-pushed the graphtool-sine-wave branch 2 times, most recently from 15a7446 to d9d2de8 Compare December 13, 2024 00:14
@drgrice1
Copy link
Member Author

I fixed the issue with the label positions being incorrect when MathJax accessibility is enabled. The key was to update the JXSGraph board after MathJax typesetting is completed.

@drgrice1 drgrice1 force-pushed the graphtool-sine-wave branch from a74b243 to 0130afa Compare December 17, 2024 12:47
The tool can be added by setting `availableTools => [ 'SineWaveTool' ]`
in the `->with` call when creating a `GraphTool` object. Of course other
tools can be added in the list as well.  The tool works by plotting
three points.  The first point determines the phase shift (or x
translation) and y translation.  The second point determines the
amplitude.  Note that point can only be moved horizontally, and is
forced to always stay on the same horizontal line as the first point.
The third point determines the amplitude. That point can only be moved
vertically, and is forced to stay at the peak of the first crest of the
sine wave.  So if `(x1, y1)` is the first point, `x2` the x-coordinate
of the second point, and `y3` the y-coordinate of the third point, then
the function is `f(x) = y3 * sin(2 * pi / x2 * (x - x1)) + y1`.

There are several new GraphTool options added to make it so that the
axis labels can be multiples of `pi`.  They are `scaleX`, `scaleY`,
`scaleSymbolX`, and `scaleSymbolY`.  The "scale" options are the scale
of the ticks on the x and y axes. That is the distance between two
successive ticks on the axis (including both major and minor ticks).
The "scaleSymbol" options are the scale symbols for the ticks on the x
and y axes. The labels on the axis will be shown as multiples of this
symbol.

These options can be used in combination to show tick labels at
multiples of pi by using the settings `scaleX => pi->value` and
`scaleSymbolX => "~~x{03C0}"`.  Note that value of `scaleSymbolX` is the
unicode pi symbol, and that `~~` is the PG escape character (normally a
backslash in Perl).

The coordinate hints in the lower right corner have also been updated to
use these options if set.

There is a general and minor change to some other graph objects.  The
"down", "up", and "drag" handlers are no longer attached to static graph
object points. For most objects this doesn't matter because the points
are hidden. So the points can't be clicked on or dragged in any case.
However, for the "fill" graph object the paint bucket icon is still
visible for static fill objects, and then clicking on the icon you see
the mouse cursor disappear.  The icon still can't be dragged because it
is fixed, but the cursor disappearing sort of indicates that the icon
has been grabbed for a drag which is somewhat counter intuitive when you
can't actually do so. These handlers aren't needed for static objects in
any case.
…intsType` settings.

This reworks the coordinate hints code considerably.  The JSXGraph
`formatLabelText` method of the default axes ticks is overriden so that
tick labels can be formatted according to our `coordinateHintsType`
settings.  Note that there is a JSXGraph tick label `toFraction` option
that is similar and is used in the default `formatLabelText` method, but
it always uses mixed numbers. Furthermore, the `scaleSymbol` is included
in what is typeset by MathJax (the default method does not do this).
This looks better and also means that instead of needing to use the
unicode symbol for pi, the LaTeX `\pi` command can be used instead. Note
that MathJax actually supports the unicode symbol and typesets it the
same as `\pi`.

So if the `coordinateHintsType` setting is 'mixed' then both the
coordinate hints shown in the lower right corner of the graph (or upper
left for number lines) and the labels on the axes will be shown as mixed
numbers, and if the setting is 'fraction' then both will be displayed as
improper fractions, and with the default 'decimal' setting both will be
decimals.

Note that the `useMathJax: true` and `display: 'html'` settings are now
set for the axes tick labels so that fractions are displayed typeset by
MathJax.

Note that this is stated above for the `coordinateHintsType` setting,
but really applies to the `coordinateHintsTypeX` and
`coordinateHintsTypeY` settings as well for per coordinate and axis
behavior.

Also note that now the `coordinateHintsType` settings are perhaps not
appropriately named since they apply to more than just the coordinate
hints, and also apply to axis labels. But I don't feel like adding
another setting for this and consistency between the hint coordinates
and axis labels is better.

The JSXGraph `generateLabelText` method of the axes ticks is also
overridden so that zero is also typeset using MathJax.  The default
JSXGraph method never does this even if the other labels are typeset
using MathJax and gives an inconsistent appearance in that case.
A graph object can only add to the help when it is selected.

The help is also updated when focus moves within the object to different
defining points.  So the graph object can give a different message
depending on which point is focused.  The sine wave tool uses this to
let the user know restrictions on how the focused point can move.
Return true from the sineWaveTool updateHighlights method so that the
general graphtool move handler doesn't overrided the coordinates set in
the updateHighlights method.

During the sine wave tool graphing phases instead of refusing to plot a
point when a down event occurs and the cursor is in an invalid location,
just plot the point where the highlight point currently is. Refusing to
plot the point can be confusing because the highlight point looks like
it is where the user wants it to be, and yet the click does nothing.
This technique needs to be implemented for all of the tools. It is
better than the previous method since it is more intuitive for the user.
…ve tool.

For all of the graph tools switch to using the highlight point
coordinates when a click occurs at an invalid location on the board for
the next phase.  Still refuse to create a point if a click or touch
occurs off the board.  This doesn't really happen for a click, but does
for a touch on a touch screen device.  In that case, the touch off the
board should be ignored.

Don't use `==` for comparison of floating point numbers.
…tions.

When MathJax accessibility is enabled the tick label positions are off.
Updating the board after the labels are typeset fixes this.
@drgrice1 drgrice1 force-pushed the graphtool-sine-wave branch from 0130afa to 88d2ff9 Compare December 18, 2024 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants