Нужна помощь в написании приложения "центростремительная сила" для урока физики - PullRequest
1 голос
/ 21 марта 2020

Я довольно плохо знаком с Ршины. Я уверен, что моя проблема рассматривается в различной документации, но я не нахожу ее.

Центростремительная сила (физика) зависит от массы, скорости и радиуса. Я хочу, чтобы студенты играли со всеми тремя, чтобы увидеть, что происходит с силой. Я использую ползунки для переменных.

Но я также хочу, чтобы они исследовали связь между скоростью и радиусом, когда сила фиксирована. Для этого я использую флажок и пытаюсь определить, был ли перемещен ползунок радиуса (в этом случае обновите ползунок скорости так, чтобы сила была фиксированной) или был перемещен ползунок скорости (в этом случае обновите ползунок радиуса, сохранив принудительное исправление).

Это вызвало некоторое нежелательное поведение - перемещение одного ползунка действительно обновляет другой ползунок, но они продолжают обновляться и в конечном итоге оказываются полностью левыми или полностью правыми.

Я думаю, что при перемещении всех трех ползунков я хочу, чтобы вывод силы был реактивным, но когда флажок установлен, я не хочу, чтобы вывод силы был реактивным. Я хочу исправить это.

Я мог бы использовать некоторую помощь или подсказки. Вот мой код:

library(shiny)

# Define UI for application that explores centripetal acceleration
update_svg <- function(radius, velocity) {
    svg <- paste(readLines("images/centripetal-animated.svg"), collapse = "\n")

    # transformations ...
    scale <- round(radius/40, 4)

    dt <- round(2*pi*radius/velocity, 2)
    dy <- round(-36*velocity/62.83/scale, 4)
    a <- velocity^2/radius
    dx <- round(-52.92*a/100/scale, 4)
    x0 <- 148.166664 + dx

    cx <- round((scale - 1)*95.25, 2)
    cy <- round((scale - 1)*100.54166, 2)


    svg <- sub("\\{scale\\}", scale, svg)
    svg <- sub("\\{DY\\}", dy, svg)
    svg <- sub("\\{X0\\}", x0, svg)
    svg <- sub("\\{DX\\}", -dx, svg)
    svg <- sub("\\{DT\\}", dt, svg)
    svg <- sub("\\{CX\\}", -cx, svg)
    svg <- sub("\\{CY\\}", -cy, svg)

    con <- paste0(tempfile("svg"), ".svg")
    writeLines(svg, con)

    con
}

ui <- fluidPage(

    # Application title
    titlePanel("Physics"),

    # Tabset panel
    tabsetPanel(
        tabPanel("Centripetal Acceleration",
            # Sidebar with a slider input for number of bins 
            sidebarLayout(
                sidebarPanel(
                    sliderInput("mass",
                                "Mass (kg):",
                                min = 0,
                                max = 10,
                                value = 5),
                    sliderInput("radius",
                                "Radius (m):",
                                min = 0,
                                max = 60,
                                value = 30),
                    sliderInput("velocity",
                                "Tangential Velocity (m/s):",
                                min = 0,
                                max = 60,
                                value = 30),
                    textOutput("angular"),
                    textOutput("acceleration"),
                    list(textInput("force", "Force (N):", 150), checkboxInput("freeze", "Fix mass & force"))
                ),

                # Show a plot of the generated distribution
                mainPanel(
                    imageOutput("svg")
                )
            )
        )
    )

)

# Define server logic 
server <- function(input, output, session) {
    # if force is fixed, observe change in radius and adjust
    # velocity to maintain fixed acceleration and force.
    observeEvent(input$radius,  {
        if (input$freeze == 1) {
            updateSliderInput(session = session, inputId = "velocity",
                              value = sqrt(as.numeric(input$force)*input$radius/input$mass))
        }
    })

    # if force is fixed, observe change in velocity and
    # adjust radius to maintain fixed acceleration and force.
    observeEvent(input$velocity,  {
        if (input$freeze == 1) {
            updateSliderInput(session = session, inputId = "radius",
                              value = input$mass*input$velocity^2/as.numeric(input$force))
        }
    })

    observe({
        angular <- input$velocity/input$radius
        acceleration <- input$radius*angular^2
        force <- input$mass*acceleration

        output$angular <- renderText(paste0("Angular Velocity: ", signif(angular, 2), " (rad/s)"))
        output$acceleration <- renderText(paste0("Acceleration: ", signif(acceleration, 2), " (m/s^2)"))
        updateTextInput(session ,"force", value = signif(force, 2))

        output$svg <- renderImage(list(src = update_svg(input$radius, input$velocity)))
    })
}

# Run the application 
shinyApp(ui = ui, server = server)
...