如何模拟传感器


永远的记忆
2024-12-18 07:11:08 (2月前)


所以我正在开展一个项目,要求我做一些硬件模拟。假设我的皮带上装满了传感器。就像这个。
当obj到达传感器时,它应该触发……

4 条回复
  1. 0# 一号位 | 2019-08-31 10-32



    我不确定你是否打算关注MVVM,但无论哪种情况你都可以尝试这样做:



    对于视觉部分,您可以使用

    Canvas

    ,但任何其他小组可能会工作。 Canvas允许你使用

    Canvas.Left

    这样的东西,你所有的定位可能都是基于

    System.Windows.Point

    无论如何,价值,而不是相对定位。



    剩下的事情可以用其中一个来绘制

    System.Window.Shapes.Shape

    子类。这两个酒吧可能

    Rectangle

    ,对于梁将

    Line

    ,对于传感器可能是一个

    Ellipse

    或者a

    Rectangle




    梁对象应该有

    Visibility

    绑定到ViewModel中的某个属性(如果不使用MVVM,则只是后面的代码)。该

    Stroke

    梁和梁的性质

    Fill

    传感器的属性也应该受到约束。



    我不确定传感器尺寸会如何影响任何东西,可能意味着光束可能很宽?如果确实有影响,请绑定

    Width



    Height

    同样。还记得绑定梁的

    StrokeThickness

    如果传感器尺寸很重要



    对于该对象,您将使用

    Rectangle

    再次。再次,做必要的绑定。新的绑定将是

    Canvas.Left



    Canvas.Top

    ,以便你知道这个位置。



    现在我们需要为对象设置动画。由于您通过绑定获得了位置,因此您可以更改source属性中的位置 - 绑定引擎将为您执行渲染更改。您可以使用计时器来移动对象。



    现在我们需要找到碰撞。一种方法是计算它后面的代码,这将在每次对象位置改变时完成。还有另一种方法,因为您使用的是Canvas。读这个

    所以发帖

    。您需要做的就是转换底层证券

    Geometry

    对象和梁的实例(通过

    myobject.RenderedGeometry.FillContainsWithDetail(beam)

    )。



    当然还有很多其他方法可以做到这一点。我只是希望我设法提供启动项目的方向。


  2. 1# 威斯特 | 2019-08-31 10-32



    你需要

    HitTesting




    然后你需要设置一个

    DependencyProperty

    就像是

    CollisionDetected



    True




    然后申请一个

    DataTrigger

    到你的

    Beam

    xaml改变它

    Style/BackgroundColor

    等等








    1. </code>


    *新增代码* *



    在这个工作解决方案中,我使用了附加属性。我一直都很简单,专注于核心问题。










    Window2.xaml

    </强>






    1.     </Path>
    2.     <Path local:Window2.MovingObjectPos="{Binding (Canvas.Left), ElementName=ElpObj}"  Fill="Red" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left" Canvas.Left="200" Canvas.Top="50" Width="39" Data="M19.5,0.5 L19.5,147.5 M0.5,148.5 L38.5,148.5 L38.5,169.5 L0.5,169.5 z">
    3.     </Path>
    4.     <Path local:Window2.MovingObjectPos="{Binding (Canvas.Left), ElementName=ElpObj}"  Fill="Red" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left" Canvas.Left="300" Canvas.Top="50" Width="39" Data="M19.5,0.5 L19.5,147.5 M0.5,148.5 L38.5,148.5 L38.5,169.5 L0.5,169.5 z">
    5.     </Path>
    6.     <Path local:Window2.MovingObjectPos="{Binding (Canvas.Left), ElementName=ElpObj}"  Fill="Red" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left" Canvas.Left="400" Canvas.Top="50" Width="39" Data="M19.5,0.5 L19.5,147.5 M0.5,148.5 L38.5,148.5 L38.5,169.5 L0.5,169.5 z">
    7.     </Path>
    8.     <Ellipse x:Name="ElpObj" Fill="Pink" Stroke="Black" HorizontalAlignment="Right" VerticalAlignment="Top" Width="57" Height="51" Canvas.Left="701" Canvas.Top="115">
    9.         <Ellipse.Triggers>
    10.             <EventTrigger RoutedEvent="Loaded">
    11.                 <BeginStoryboard>
    12.                     <Storyboard>
    13.                         <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" To="50" By="-2.0"/>
    14.                     </Storyboard>
    15.                 </BeginStoryboard>
    16.             </EventTrigger>
    17.         </Ellipse.Triggers>
    18.     </Ellipse>
    19. </Canvas>
    20. </code>




    Window2.xaml.cs

    </强>




    1. using System;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Media;
      using System.Windows.Shapes;

    2. namespace WpfAnimation
      {
      ///


      /// Interaction logic for Window2.xaml
      ///

      public partial class Window2 : Window
      {
      public Window2()
      {
      InitializeComponent();
      }

    3.     public static double GetMovingObjectPos(DependencyObject obj)
    4.     {
    5.         return (double)obj.GetValue(MovingObjectPosProperty);
    6.     }
    7.     public static void SetMovingObjectPos(DependencyObject obj, double value)
    8.     {
    9.         obj.SetValue(MovingObjectPosProperty, value);
    10.     }
    11.     // Using a DependencyProperty as the backing store for MovingObject.  This enables animation, styling, binding, etc...
    12.     public static readonly DependencyProperty MovingObjectPosProperty =
    13.         DependencyProperty.RegisterAttached("MovingObjectPos", typeof(double), typeof(Window2), new PropertyMetadata(0.0, new PropertyChangedCallback(MovingObjectPosChanged)));
    14.     private static void MovingObjectPosChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    15.     {
    16.         double leftOfMovingObject = (double) e.NewValue ;
    17.         Path beam = (Path) d;
    18.         System.Diagnostics.Debug.WriteLine("Left = " + e.NewValue.ToString());
    19.         double leftOfBeam = Canvas.GetLeft(beam);
    20.         double widthOfBeam = 20.0;
    21.         if (leftOfMovingObject > leftOfBeam && leftOfMovingObject < leftOfBeam + widthOfBeam)
    22.         {
    23.             System.Diagnostics.Debug.WriteLine("Hit >>>>> = " + e.NewValue.ToString());
    24.             beam.Fill = Brushes.Gray;
    25.         }
    26.     }
    27. }
    28. }

    29. </code>

  3. 2# 纾潆锦袖迷子 | 2019-08-31 10-32



    我使用了我的旧答案

    Task

    ,并考虑无限移动物体。



    它使用实际

    HitTesting





    1. 创建一个

      UserControl

      对于Beam对象。这需要启动

      Task

      之后立马

      Loading

      。它包含一个包含DP的DP

      Panel



    2. </醇>


      BeamControl.xaml






      1. </code>


      BeamControl.xaml.cs




      1. using System;
        using System.Threading.Tasks;
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Media;
        using System.Windows.Shapes;

      2. namespace WpfAnimation
        {
        ///


        /// Interaction logic for BeamControl.xaml
        ///

        public partial class BeamControl : UserControl
        {

      3.     Path _beamPath;
      4.     public Panel Sensor
      5.     {
      6.         get { return (Panel)GetValue(SensorProperty); }
      7.         set { SetValue(SensorProperty, value); }
      8.     }
      9.     // Using a DependencyProperty as the backing store for Sensor.  This enables animation, styling, binding, etc...
      10.     public static readonly DependencyProperty SensorProperty =
      11.         DependencyProperty.Register("Sensor", typeof(Panel), typeof(BeamControl), new PropertyMetadata(null));
      12.     private  double left;
      13.     private double top;
      14.     public BeamControl()
      15.     {
      16.         InitializeComponent();
      17.         this.Loaded += BeamControl_Loaded;             
      18.     }
      19.     void BeamControl_Loaded(object sender, RoutedEventArgs e)
      20.     {
      21.         _beamPath = this.Content as Path;
      22.         left = Canvas.GetLeft(this);
      23.         top = Canvas.GetTop(this);
      24.         Task.Factory.StartNew(() =>
      25.         {
      26.             while (true)
      27.             {
      28.                 _doDetection();
      29.             }
      30.         });
      31.     }
      32.     void _doDetection()
      33.     {
      34.         // 200 is the height of the beam, you can change it
      35.         for (double i = top; i < 200; i = i + 1)
      36.         {
      37.             System.Diagnostics.Debug.WriteLine(i.ToString());
      38.             Point pt = new Point(left + 20.0, i);
      39.             this.Dispatcher.Invoke(() =>
      40.             {
      41.                 VisualTreeHelper.HitTest(Sensor,
      42.                     new HitTestFilterCallback((o) =>
      43.                     {
      44.                         if (o is Ellipse)
      45.                         {
      46.                             _beamPath.Fill = Brushes.DarkKhaki;
      47.                             System.Diagnostics.Debug.WriteLine("Detected ! " + o.GetType().ToString());
      48.                             System.Diagnostics.Debug.WriteLine(pt.ToString());
      49.                             return HitTestFilterBehavior.Stop;
      50.                         }
      51.                         else
      52.                             System.Diagnostics.Debug.WriteLine(o.GetType().ToString());
      53.                         return HitTestFilterBehavior.Continue;
      54.                     }),
      55.                     new HitTestResultCallback((result) => { return HitTestResultBehavior.Continue; }),
      56.                     new PointHitTestParameters(pt));
      57.             });
      58.         }
      59.     }
      60. }
      61. }

      62. </code>


      MainWindow.xaml






      1.     <local:BeamControl Canvas.Left="300" Canvas.Top="50" Sensor="{Binding RelativeSource={RelativeSource AncestorType=Canvas, Mode=FindAncestor}}"/>
      2.     <Ellipse x:Name="ElpObj" Fill="Pink" Stroke="Black" HorizontalAlignment="Right" VerticalAlignment="Top" Width="57" Height="51" Canvas.Left="548" Canvas.Top="114">
      3.         <Ellipse.Triggers>
      4.             <EventTrigger RoutedEvent="Loaded">
      5.                 <BeginStoryboard>
      6.                     <Storyboard>
      7.                         <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" To="50" By="-0.5" Duration="0:0:20"/>
      8.                     </Storyboard>
      9.                 </BeginStoryboard>
      10.             </EventTrigger>
      11.         </Ellipse.Triggers>
      12.     </Ellipse>
      13. </Canvas>
      14. </code>


      运行该应用程序

      没有调试



登录 后才能参与评论