Команда NaN, задача «Пробивний електрон»

Доповідь команди NaN (Київський природничо-науковий ліцей №145) по задачі №4 «Пробивний електрон» (CETO-2019):

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import java.io.*;
import javax.imageio.ImageIO;

public class Task4 
{
    /** PSEUDO-INPUT    */
    static double HORIZONTAL_POS_OFFSET = 0.5;
    static double VERTICAL_POS_OFFSET = 1.0;
    static double DEFAULT_SPEED = 1.0e+8;
    static double DEFAULT_ANGLE = 1.5;
    static double DEFAULT_CURRENT = 1.0e-12;
    static int DEFAULT_N = 40;
    static int DEFAULT_M = 40;

    /** PHYSICS     */
    static double dt = 1e-7;
    static double ELECTRON_MASS = 9.10938215e-31;
    static double ELECTRON_CHARGE = -1.602176487e-19;
    static double EPSILLON_ZERO = 8.854187817e-12;
    //static double ELECTRON_MASS = 1.0;
    //static double ELECTRON_CHARGE = -1.0;
    //static double EPSILLON_ZERO = 1.0;
    static double PIXEL_LENGTH = 3.163058078e-22;//(double)Task4.WIRES_INTERVAL;

    /** VISUAL      */
    static int VERTICAL_OFFSET = 20;
    static int HORIZONTAL_OFFSET = 20;
    static int WIRES_INTERVAL = 15;
    static int LEFT_OFFSET = 200;
    static int RIGHT_OFFSET = 200;
    static int TOP_OFFSET = 200;
    static int BOTTOM_OFFSET = 200;
    static int WIRE_RADIUS = 5;
    static int ELECTRON_RADIUS = 10;

    /** GABA        */
    static int SCREEN_RESOLUTION_WIDTH = 1920;
    static int SCREEN_RESOLUTION_HEIGHT = 1080;
    static int REPITIONS_PER_PART = 100000;
    static int UPDATE_FREQUENCY = 10;
    //static int UPDATE_FREQUENCY = (int)(1.0e+22/PIXEL_LENGTH);
    static LaunchFrame ui;

    /** MASSIVE     */
    static double MAX_SPEED = 100.0;
    static double MIN_SPEED = 0.0;
    static int SPEED_RESOLUTION = 100;
    static double MAX_ANGLE = Math.PI;
    static double MIN_ANGLE = 0.0;
    static int ANGLE_RESOLUTION = 100;
    public static void main (String[] args)
    {
        ui = new LaunchFrame();
    }   
}
class LaunchFrame extends JFrame
{
    JTextField fieldSpeed;
    JTextField fieldAngle;
    JTextField fieldN;
    JTextField fieldM;
    JTextField fieldI;

    JTextField fieldDT;
    JTextField fieldMinSpeed;
    JTextField fieldMaxSpeed;
    JTextField fieldResoSpeed;
    JLabel areaLog;
    public LaunchFrame ()
    {
        setTitle("Task4");
        this.setSize(300, 15*18+200);
        this.setResizable(false);
        this.setLayout(null);

        JLabel labelN = new JLabel("M:", SwingConstants.CENTER);
        this.add(labelN);
        labelN.setBounds(10, 15, 30, 30);

        fieldN = new JTextField();
        fieldN.setText(Task4.DEFAULT_N + "");
        this.add(fieldN);
        fieldN.setBounds(45, 15, 100, 30);

        JLabel labelM = new JLabel("N:", SwingConstants.CENTER);
        this.add(labelM);
        labelM.setBounds(10, 15*4, 30, 30);

        fieldM = new JTextField();
        fieldM.setText(Task4.DEFAULT_M + "");
        this.add(fieldM);
        fieldM.setBounds(45, 15*4, 100, 30);

        JLabel labelSpeed = new JLabel("S:", SwingConstants.CENTER);
        this.add(labelSpeed);
        labelSpeed.setBounds(10, 15*10, 30, 30);

        fieldSpeed = new JTextField();
        fieldSpeed.setText(Task4.DEFAULT_SPEED + "");
        this.add(fieldSpeed);
        fieldSpeed.setBounds(45, 15*10, 100, 30);

        JLabel labelI = new JLabel("I:", SwingConstants.CENTER);
        this.add(labelI);
        labelI.setBounds(10, 15*7, 30, 30);

        fieldI = new JTextField();
        fieldI.setText(Task4.DEFAULT_CURRENT + "");
        this.add(fieldI);
        fieldI.setBounds(45, 15*7, 100, 30);

        JLabel labelAngle = new JLabel("A:", SwingConstants.CENTER);
        this.add(labelAngle);
        labelAngle.setBounds(10, 15*13, 30, 30);

        fieldAngle = new JTextField();
        fieldAngle.setText(Task4.DEFAULT_ANGLE + "");
        this.add(fieldAngle);
        fieldAngle.setBounds(45, 15*13, 100, 30);

        JButton startButton = new JButton("Create");
        class StartListener implements ActionListener
        {
            public void actionPerformed (ActionEvent e)
            {
                try
                {
                    Experiment a = new Experiment(Integer.valueOf(Task4.ui.fieldN.getText()), Integer.valueOf(Task4.ui.fieldM.getText()), Double.valueOf(Task4.ui.fieldI.getText()), Double.valueOf(Task4.ui.fieldSpeed.getText()), Double.valueOf(Task4.ui.fieldAngle.getText()), true);
                }
                catch (NumberFormatException ex)
                {
                    log("Invalid input\n");
                    ex.printStackTrace();
                    return;
                }
                log("Initing experiment");
            }
        }
        startButton.addActionListener(new StartListener());
        this.add(startButton);
        startButton.setBounds(10, 15*16, 135, 30);

        
        JLabel labelDT = new JLabel("dt:");
        this.add(labelDT);
        labelDT.setBounds(155, 15, 30, 30);
        
        fieldDT = new JTextField(Double.toString(Task4.dt));
        this.add(fieldDT);
        fieldDT.setBounds(190, 15, 95, 30);

        JLabel labelMaxSpeed = new JLabel("MxS:");
        this.add(labelMaxSpeed);
        labelMaxSpeed.setBounds(155, 15*4, 30, 30);

        fieldMaxSpeed = new JTextField(Double.toString(Task4.MAX_SPEED));
        this.add(fieldMaxSpeed);
        fieldMaxSpeed.setBounds(190, 15*4, 95, 30);

        JLabel labelMinSpeed = new JLabel("MnS:");
        this.add(labelMinSpeed);
        labelMinSpeed.setBounds(155, 15*7, 30, 30);

        fieldMinSpeed = new JTextField(Double.toString(Task4.MIN_SPEED));
        this.add(fieldMinSpeed);
        fieldMinSpeed.setBounds(190, 15*7, 95, 30);

        JLabel labelResoSpeed = new JLabel("SR:");
        this.add(labelResoSpeed);
        labelResoSpeed.setBounds(155, 15*10, 30, 30);

        fieldResoSpeed = new JTextField(Integer.toString(Task4.SPEED_RESOLUTION));
        this.add(fieldResoSpeed);
        fieldResoSpeed.setBounds(190, 15*10, 95, 30);

        JButton saveButton = new JButton("Save consts");
        class SaveListener implements ActionListener
        {
            public void actionPerformed (ActionEvent e)
            {
                try
                {
                    Task4.dt = Double.valueOf(fieldDT.getText());
                    Task4.MAX_SPEED = Double.valueOf(fieldMaxSpeed.getText());
                    Task4.MIN_SPEED = Double.valueOf(fieldMinSpeed.getText());
                    Task4.SPEED_RESOLUTION = Integer.valueOf(fieldResoSpeed.getText());
                }
                catch (NumberFormatException ex)
                {
                    log("Invalid input");
                    ex.printStackTrace();
                }
            }
        }
        saveButton.addActionListener(new SaveListener());
        this.add(saveButton);
        saveButton.setBounds(155, 15*13, 135, 30);

        JButton arrayButton = new JButton("Simulate");
        class SimulateListener implements ActionListener
        {
            public void actionPerformed (ActionEvent e)
            {
                class ui1 extends Thread
                {
                    public void run()
                    {
                        try
                        {
                            ExperimentSimulation a = new ExperimentSimulation(Integer.valueOf(Task4.ui.fieldN.getText()), Integer.valueOf(Task4.ui.fieldM.getText()), Double.valueOf(Task4.ui.fieldI.getText()));
                            a.start();
                        }
                        catch (NumberFormatException ex)
                        {
                            log("Invalid input\n");
                            ex.printStackTrace();
                            return;
                        }
                        log("Simulation Created");
                    }
                }
                new ui1().start();
            }
        }
        arrayButton.addActionListener(new SimulateListener());
        this.add(arrayButton);
        arrayButton.setBounds(155, 15*16, 135, 30);
        
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }   
    public void log (String s)
    {
        System.out.println(s);
    }
}
class Experiment extends Thread
{
    JButton keepButton;
    int N;
    int M;
    double I;
    double speed;
    double angle;
    double offset;
    Vect3D pos;
    Vect3D vel;
    Vect3D amp;
    Vect3D acc;
    Vect3D ind;
    Vect3D lastUpdate;
    Vect3D rad;
    boolean isVisual;
    Vect3D[][] wires;
    Canvas f;
    int step;
    Vector<MPoint> way;
    public enum State
    {
        WAITING,
        STARTED,
        PAUSED,
        ENDED
    }
    State state;
    public Experiment (int N_, int M_, double I_, double speed_, double angle_, boolean isVisual_)
    {
        N = N_;
        M = M_;
        I = I_;
        speed = speed_;
        angle = angle_;
        isVisual = isVisual_;
        pos = new Vect3D(((N-1)*Task4.WIRES_INTERVAL + Task4.LEFT_OFFSET + Task4.RIGHT_OFFSET)*Task4.HORIZONTAL_POS_OFFSET, 
            ((M-1)*Task4.WIRES_INTERVAL + Task4.TOP_OFFSET + Task4.BOTTOM_OFFSET)*Task4.VERTICAL_POS_OFFSET, 0);
        vel = new Vect3D(Math.cos(angle)*speed, -Math.sin(angle)*speed, 0.0);
        acc = new Vect3D(0,0,0);
        wires = new Vect3D[N][M];
        for (int i=0; i<N; i++)
        {
            for (int j=0; j<M; j++)
            {
                wires[i][j] = new Vect3D(Task4.LEFT_OFFSET + (i+1)*Task4.WIRES_INTERVAL, Task4.TOP_OFFSET + (j+1)*Task4.WIRES_INTERVAL,0.0);
            }
        }
        amp = new Vect3D(0.0,0.0,I);
        if (isVisual)
        {
            ExperimentFrame visual = new ExperimentFrame();
        }
        lastUpdate = new Vect3D(pos);
        step = 0;
        this.state = State.WAITING;
        log("Experiment " + this.getName() + " Created");
    }
    class ExperimentFrame extends JFrame
    {
        public ExperimentFrame ()
        {
            setSize(Math.min(Task4.WIRES_INTERVAL*(N-1) + Task4.HORIZONTAL_OFFSET + Task4.LEFT_OFFSET + Task4.RIGHT_OFFSET, Task4.SCREEN_RESOLUTION_WIDTH), Math.min(Task4.VERTICAL_OFFSET*4 + Task4.WIRES_INTERVAL*(M-1) + Task4.TOP_OFFSET + Task4.BOTTOM_OFFSET, Task4.SCREEN_RESOLUTION_HEIGHT));
            setResizable(true);
            setLayout(new FlowLayout());
            class VisualField extends Canvas
            {
                public VisualField()
                {
                    setSize(Math.min(Task4.WIRES_INTERVAL*(N-1) + Task4.TOP_OFFSET + Task4.BOTTOM_OFFSET, Task4.SCREEN_RESOLUTION_WIDTH), Math.min(Task4.WIRES_INTERVAL*(M-1) + Task4.LEFT_OFFSET + Task4.RIGHT_OFFSET, Task4.SCREEN_RESOLUTION_HEIGHT));
                    way = new Vector<MPoint>(0);
                    way.add(new MPoint(pos.x, pos.y));
                }
                public void paint (Graphics g)
                {
                    g.setColor(Color.BLACK);
                    for (int i=0; i<M; i++)
                    {
                        for (int j=0; j<N; j++)
                        {
                            g.fillOval((j)*Task4.WIRES_INTERVAL + Task4.LEFT_OFFSET, (i)*(Task4.WIRES_INTERVAL) + Task4.TOP_OFFSET, Task4.WIRE_RADIUS, Task4.WIRE_RADIUS);
                        }
                    }
                    g.setColor(Color.BLUE);
                    for (int i=1; i<way.size(); i++)
                    {
                        g.drawLine((int)way.elementAt(i-1).x, (int)way.elementAt(i-1).y, (int)way.elementAt(i).x, (int)way.elementAt(i).y);
                    }
                    //g.fillOval((int)pos.x,(int)pos.y,Task4.ELECTRON_RADIUS,Task4.ELECTRON_RADIUS);
                }
            }
            f = new VisualField();
            f.repaint();
            add(f);
            keepButton = new JButton("Start experiment");
            class keepExperimentTread extends Thread
            {
                public void run ()
                {
                    run_Mirror();
                }
            }
            class keepListener implements ActionListener
            {
                public void actionPerformed (ActionEvent e)
                {
                    switch (state)
                    {
                        case WAITING:
                            state = State.STARTED;
                            keepButton.setText("Pause experiment");
                            new keepExperimentTread().start();
                            break;
                        case STARTED:
                            state = State.PAUSED;
                            f.repaint();
                            keepButton.setText("Continue experiment");
                            break;
                        case PAUSED:
                            state = State.STARTED;
                            keepButton.setText("Pause experiment");
                            new keepExperimentTread().start();
                            break;
                        case ENDED:
                            log("Experiment ended");
                            keepButton.setEnabled(false);
                    }
                }
            }
            keepButton.addActionListener(new keepListener());
            add(keepButton);
            JButton reDrawButton = new JButton ("Redraw");
            class reDrawListener implements ActionListener
            {
                public void actionPerformed (ActionEvent e)
                {
                    f.repaint();
                }
            }
            reDrawButton.addActionListener(new reDrawListener());
            add(reDrawButton);
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            setVisible(true);
        }
    public void run_Mirror()
    {
        run();
    }
    }
    public void run ()
    {
        this.state = State.STARTED;
        while (state == State.STARTED)
        {
            //System.out.println("Current acc - " + acc.tostring());
            step++;
            move();
            calculateAcc();
            calculateVel();
            if (isVisual)
            {
                way.add(new MPoint(pos.x, pos.y));
            }
            /*if ((pos.add(lastUpdate.multiply(-1.0)).mod() >= Task4.UPDATE_FREQUENCY)&&(isVisual))
            {
                lastUpdate = new Vect3D(pos);
                f.repaint();
            }*/
            if ((step%5000==0)&&(isVisual))
            {
                f.repaint();
            }
            if (checkEnded())
            {
                state = State.ENDED;
                if (isVisual)
                {
                    keepButton.setEnabled(false);
                    keepButton.setText("Experiment ended");
                    f.repaint();
                }
                log("Experiment " + this.getName() + " ended at step " + this.step);
            }
            yield();
        }
    }
    public boolean checkEnded ()
    {
        //return((vel.y>0)||(pos.y<0));
        return((pos.x<0)||(pos.y<0))||(pos.x>(Task4.WIRES_INTERVAL*(N-1) + Task4.TOP_OFFSET + Task4.BOTTOM_OFFSET))||(pos.y>(Task4.WIRES_INTERVAL*(M-1) + Task4.LEFT_OFFSET + Task4.RIGHT_OFFSET));
        //return((pos.y<0)||(pos.y>(Task4.WIRES_INTERVAL*(M-1) + Task4.LEFT_OFFSET + Task4.RIGHT_OFFSET)));
        //return(pos.y<0);
    }
    /*public void calculateAcc ()
    {
        ind = new Vect3D(0.0,0.0,0.0);
        Vect3D rad;
        for (int i=0; i<N; i++)
        {
            for (int j=0; j<M; j++)
            {
                rad = pos.add(wires[i][j].multiply(-1.0)).multiply(Task4.PIXEL_LENGTH);
                rad.z = 0;
                ind = ind.add(amp.multiply(rad).multiply(1/(rad.mod()*rad.mod()))).multiply(Task4.ELECTRON_CHARGE/(2.0*Math.PI*Task4.EPSILLON_ZERO));                               //add consts
            }
        }
        acc = vel.multiply(ind).multiply(1.0/Task4.ELECTRON_MASS);
    }*/
    public void move ()
    {
        pos = pos.add(new Vect3D(vel.x*Task4.dt, vel.y*Task4.dt, vel.z*Task4.dt));
    }
    public void calculateVel()
    {
        vel = vel.add(new Vect3D(acc.x*Task4.dt, acc.y*Task4.dt, acc.z*Task4.dt));
        vel = vel.multiply(this.speed/vel.mod());
    }
    public void calculateAcc()
    {
        acc = new Vect3D(0.0,0.0,0.0);
        for(int i=0; i<N; i++)
        {
            for(int j=0; j<M; j++)
            {
                rad = Vect3D.add(pos, wires[i][j].multiply(-1));
                rad.z=0;
                acc = acc.add(new Vect3D(Task4.ELECTRON_CHARGE*this.I*rad.x*vel.z/2/Math.PI/Task4.EPSILLON_ZERO/Task4.ELECTRON_MASS/rad.mod()/rad.mod(),Task4.ELECTRON_CHARGE*this.I*rad.y*vel.z/2/Math.PI/Task4.EPSILLON_ZERO/Task4.ELECTRON_MASS/rad.mod()/rad.mod(), -Task4.ELECTRON_CHARGE*this.I*(pos.y*vel.y + pos.x*vel.x)/2/Math.PI/Task4.EPSILLON_ZERO/Task4.ELECTRON_MASS/rad.mod()/rad.mod()));
            }
        }
    }
    public void log (String s)
    {
        Task4.ui.log(s);
    }
}
class ExperimentSimulation extends Thread
{
    int N;
    int M;
    double I;
    Canvas d;
    boolean[][] isEnded;
    Experiment[][] exps;
    Vector<MPoint> way = new Vector<MPoint>(0);
    int Thread_Count = Task4.SPEED_RESOLUTION*Task4.ANGLE_RESOLUTION;
    public enum State
    {
        WAITING,
        STARTED,
        PAUSED,
        ENDED
    }
    public State state;
    public ExperimentSimulation(int N_, int M_, double I_)
    {
        this.setName("Experiment Simulation");
        N = N_;
        M = M_;
        I = I_;
        isEnded = new boolean[Task4.SPEED_RESOLUTION][Task4.ANGLE_RESOLUTION];
        class ExperimentSimulationFrame extends JFrame
        {
            public ExperimentSimulationFrame ()
            {
                setSize(Task4.LEFT_OFFSET + Task4.RIGHT_OFFSET + Task4.SPEED_RESOLUTION, Task4.TOP_OFFSET + Task4.BOTTOM_OFFSET + Task4.ANGLE_RESOLUTION);
                setLayout(null);
                setResizable(false);
                class ExperimentSimulationField extends Canvas
                {
                    public ExperimentSimulationField ()
                    {
                        setSize(Task4.SPEED_RESOLUTION, Task4.ANGLE_RESOLUTION);
                    }
                    public void paint (Graphics g)
                    {
                        g.setColor(Color.BLACK);
                        /*for (int i = 0; i< way.size(); i++)
                        {
                            g.drawLine((int)way.elementAt(i).x, (int)way.elementAt(i).y, (int)way.elementAt(i).x, (int)way.elementAt(i).y);
                            try
                            {
                                Thread.sleep(10);
                            }
                            catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }*/
                        for (int i=0; i<Task4.SPEED_RESOLUTION; i++)
                        {
                            for(int j=0; j<Task4.ANGLE_RESOLUTION; j++)
                            {
                                if (isEnded[i][j])
                                {
                                    g.drawLine(i,j,i,j);
                                }
                            }
                        }
                    }
                }       
                d = new ExperimentSimulationField();
                add(d);
                d.setBounds(Task4.LEFT_OFFSET, Task4.TOP_OFFSET, Task4.LEFT_OFFSET + Task4.SPEED_RESOLUTION, Task4.TOP_OFFSET + Task4.ANGLE_RESOLUTION);
                setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                setVisible(true);
            }
        }
        ExperimentSimulationFrame esf = new ExperimentSimulationFrame();
        exps = new Experiment[Task4.SPEED_RESOLUTION][Task4.ANGLE_RESOLUTION];
        for (int i=0; i<Task4.SPEED_RESOLUTION; i++)
        {
            for (int j=0; j<Task4.ANGLE_RESOLUTION; j++)
            {
                exps[i][j] = new Experiment (N, M, I, Task4.MIN_SPEED + (j+1)*(Task4.MAX_SPEED-Task4.MIN_SPEED)/(Task4.SPEED_RESOLUTION+1), Task4.MIN_ANGLE + i*(Task4.MAX_ANGLE-Task4.MIN_ANGLE)/Task4.ANGLE_RESOLUTION, false);
                exps[i][j].setName(this.getName() + " experiment " + i + " " + j);
                System.out.println("Named " + exps[i][j].getName());
            }
        }
        state = State.WAITING;
    }
    public void run()
    {
        Experiment makhmudov = new Experiment(0,0,0,0,0,false);
        makhmudov.state = Experiment.State.ENDED;
        if (state == State.WAITING)
        {
            for (int i=0; i<Task4.SPEED_RESOLUTION; i++)
            {
                for (int j=0; j<Task4.ANGLE_RESOLUTION; j++)
                {
                    exps[i][j].start();
                }
            }
        }
        state = State.STARTED;
        int ch = 0;
        int turn = 0;
        while (state == State.STARTED)
        {
            try
            {
                Thread.sleep(30);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            for (int i=0; i<Task4.SPEED_RESOLUTION; i++)
            {
                for (int j=0; j<Task4.ANGLE_RESOLUTION; j++)
                {
                    if ((exps[i][j].state == Experiment.State.ENDED)&&(!isEnded[i][j]))
                    {
                        isEnded[i][j] = true;
                        way.add(new MPoint(i,j));
                        exps[i][j] = makhmudov;
                        ch++;
                        Thread_Count--;
                    }
                }
            }
            if (ch > 10)
            {
                d.repaint();
                ch = 0;
                System.gc();
            }
            turn++;
            System.out.println(turn + " turn spent, " + Thread_Count + " running");
            if (Thread_Count == 0)
            {
                this.state = State.ENDED;
            }
            yield();
        }
    }
}
class Vect3D
{
    double x;
    double y;
    double z;
    public Vect3D (double x_, double y_, double z_)
    {
        x = x_;
        y = y_;
        z = z_;
    }
    public Vect3D (Vect3D a)
    {
        this.x = a.x;
        this.y = a.y;
        this.z = a.z;
    }
    public Vect3D multiply (double a)
    {
        return (new Vect3D(this.x*a, this.y*a, this.z*a));
    }
    public Vect3D multiply (Vect3D a)
    {
        return(new Vect3D(this.y*a.z-this.z*a.y, this.x*a.z-this.z*a.x, this.x*a.y-this.y*a.x));
    }
    public static Vect3D add(Vect3D addition1, Vect3D addition2)
    {
        return(new Vect3D(addition1.x + addition2.x, addition1.y + addition2.y, addition1.z + addition2.z));
    }
    public Vect3D add(Vect3D addition)
    {
        return(new Vect3D(this.x + addition.x, this.y + addition.y, this.z + addition.z));
    }
    public double mod ()
    {
        return(Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z));
    }
    public String tostring () //was used for debug
    {
        return (this.x + " " + this.y + " " + this.z);
    }
}
class MPoint
{
    double x;
    double y;
    public MPoint (double x_, double y_)
    {
        this.x = x_;
        this.y = y_;
    }
}

 

2 коментар

  1. Возможно, я неверно понимаю условия олимпиады в целом? Речь ведь идет не о том, чтобы написать программу, пусть даже с красивой визуализацией – это ведь не более чем программирование. Но олимпиада ведь по МОДЕЛИРОВАНИЮ, так что главное, как мне кажется – это, имея модель и программу, провести вычислительный эксперимент, набрать статистику, сделать ФИЗИЧЕСКИЕ выводы – вплоть до оценки погрешностей 🙂

    В задаче был вопрос, при каких условиях движение будет хаотическим, при каких – электрон будет проходить стенку насквозь? Хотелось бы посмотреть именно это решение, а не просто код программы…

    1. Мы публикуем материалы, предоставленные командой. Беседы на защите касались многих вопросов, в том числе и физики, и использованных технологий. Но конечно, были вопросы, которые остались без ответов.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *