Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I got help from Kuba on a previous post regarding this issue I'm having but after integrating that solution into my code, the problem changed and I am left with something I don't know much about (even after some research) so here I am again. Here is the link to my first post. The edit I added is what is shown below, it was suggested that I just ask the question in a new post though.

What I would like to happen is that when the black dot crosses the curve, the label changes from "vapor" to "liquid" and vice versa and that label should not change when the point moves around the curve. Right now Kuba's solution works, but only if the mouse is NOT depressed (meaning the point will not move). I tried using AutoAction->True but it slowed down my notebook quite a bit.

Below is a very simplified version of the notebook I am working with that has Kuba's solution integrated into it.

Manipulate[
 DynamicModule[{col = False, acc = 0, p = {420, Log[6]}}, 
  EventHandler[
   Show[Quiet@
      LogPlot[Log[T], {T, 273.16, 647.096}, PlotStyle -> Thick] /. 
     l_Line :> 
      EventHandler[
       l, {"MouseEntered" :> 
         If[acc === 
           0, (col = col /. {True -> False, False -> True})]}], 
    Frame -> True, PlotRange -> {{273.16, 700}, {Log[5.6], Log[7]}}, 
    Epilog -> 
     Inset[Graphics[
       Text[Style[Dynamic@If[col == True, "liquid", "vapor"], 18], 
        Scaled[{0.400, 0.1}]]]]], {"MouseDown" :> (acc = 1; 
      MousePosition[Dynamic@p]), 
    "MouseDragged" :> (MousePosition[Dynamic@p]), 
    "MouseUp" :> (acc = 0; MousePosition[Dynamic@p])}, 
   PassEventsDown -> True]], {{p, {420, Log[5.75]}}, Locator, 
  Appearance -> Graphics[{Disk[]}, ImageSize -> 12]}]

enter image description here

I am trying to make a Demonstration that shows the behavior of water on a pressure vs. temperature diagram so I need to show that there is only a phase change from vapor to liquid/liquid to vapor if the phase boundary is crossed.

It's important that Manipulate remains a part of this code.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

You just need to put in conditions that test whether the point crosses the curve. You'll need to keep track of the previous position. You'll also need to decide what constitutes a crossing. The simplest is that it changes sides (as indicated by the y coordinate) when the x coordinates of the point and the previous point are within the plot's domain (for x). Another possibility is to determine whether the line segment between the point and the previous point crosses the graph. It is not very hard to program; however, it is more complicated and it is not really necessary to be that exact in a mouse-driven demonstration.

Manipulate[
 Show[
  LogPlot[Log[T], {T, 273.16, 647.096}, PlotStyle -> Thick],
  Frame -> True, PlotRange -> {{273.16, 700}, {Log[5.6], Log[7]}},
  Epilog -> {Dynamic[
     If[273.16 <= p[[1]] <= 647.096 && 273.16 <= lastp[[1]] <= 647.096 &&
         (Log@p[[1]] > Exp@p[[2]] && Log@lastp[[1]] <= Exp@lastp[[2]] || 
          Log@p[[1]] < Exp@p[[2]] && Log@lastp[[1]] >= Exp@lastp[[2]]),
      col = ! col];
     lastp = p;
     Text[Style[If[col == True, "liquid", "vapor"], 18], p, {-1, 0}]]}
  ],
 {{p, {420., Log[5.75]}}, Locator, 
  Appearance -> Graphics[{Disk[]}, ImageSize -> 12]},
 {{lastp, {420, Log[5.75]}}, None}, {{col, True}, None},
 TrackedSymbols :> {p}]
share|improve this answer

Perhaps I'm missing something, but can't this problem be solved without the event handling?

Manipulate[
 LogPlot[Log[T], {T, 273.16, 647.096}, PlotStyle -> Thick,
  Epilog -> 
   Inset[Style[Text[If[Exp@Last@l > Log[First@l], "Vapor", "Liquid"]],
      16, Bold], l, Scaled[{-.5, 1}]]], {{l, {450, Log[5.6]}}, 
  Locator}]

enter image description here

I'll edit to include graphical improvements if necessary.

share|improve this answer
    
I'm sure it can. I was really unsuccessful with everything I came up with and someone suggested EventHandler. This works how I would like it to with one exception. If the Locator moves around the curve the label (vapor/liquid) should not change. –  baumannr Jul 28 at 15:29
    
If I understand correctly, you want the If statement to be Piecewise where the label would be set to something special if the locator is place on the curve? –  bobthechemist Jul 28 at 15:33
    
I'm not sure I follow. What you made demonstrates part of the behavior I want to show (passing through the curve changes the label) but If I move around the curve (without crossing it) then the label won't change. In this case it does. I am trying to demonstrate the behavior of water by either crossing a phase boundary or circumnavigating the critical point. –  baumannr Jul 28 at 16:02
    
Are you saying that the dragging the locator close to the line results in the label jumping between Vapor and Liquid? The small white dot in the center of the locator is the position checked for the label; if it is below (or on) the line it will read liquid and above the line it will read vapor. –  bobthechemist Jul 28 at 16:08
    
This shows the behavior I am looking for (unfortunately the code did not work for what I want to do). If the Locator moves through the curve, the color of the Disk changes. If the Locator moves around the curve, the color of the Disk remains unchanged. –  baumannr Jul 28 at 16:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.