グラフ、図面、図面をデジタル化するためのプログラム:プロジェクト「アルゴリズム:数学」のアルゴリズム







内容



はじめに

動作原理

プログラムの説明

プログラムの最終コード

サンプルを使用してデジタル機能を操作する利点

エピローグ






はじめに



科学や教育、工学に関連するさまざまな分野では、デジタルメディアがまだ存在していなかったときに作成されたグラフからデータを取得したり、グラフが作成された実際のデータが失われたり、最後に、グラフは、明示的な形式でポイントの座標のセットを提供しない一部のデバイスの操作の最終形式です。



データを取得するには、そのようなグラフ(またはグラフィックオブジェクト)を「 デジタイズ 」する必要があります。つまり、グラフポイントの横座標と縦座標を取得する必要があります。その後、さまざまな操作を実行できます。新しい(高品質の)グラフを作成し、計算を実行し、それを新しい形式に変換する(たとえば、スプラインを作成する)など。



プロジェクト「 家庭教師:数学 」(Habrahabr- 「チューター:数学」の記事を読んで統一状態試験とVPRの準備からアイデアまで、リリースまで。ユニークな教育プロジェクトに関する話 )では、主に2つの方法でこの問題に遭遇しました。





この投稿では、このために作成されたgraphicsDigitizing関数のコードを提供し、その仕組みについても簡単に説明します。 また、どのようにライブで動作するかを確認できます。



動作原理



プログラムは非常に簡単です。 「最初の」レイヤーの特定のフィールドにデジタルイラストレーション(スキャン、写真、スクリーンショット、その他の写真)を配置する必要があります。 次に、手動処理が実行されます。





いくつかの理由でBスプラインを選択しました。





次の図は、一連のポイント(参照ポイント)、1度、2度、および3度のBスプラインのセット、およびベジェ曲線(示されている場合、本質的に7度のBスプライン)を示しています。







他の多くのタスクと同様に、グラフをデジタル化するプログラムを作成するには、 Wolfram言語を使用します。



プログラムの説明



もちろん、以下に示すプログラムのコード全体がステップごとにどのように機能するかについては説明しませんが、非常に長い時間であり、私たちのように、議論中の問題に興味がある人、さらにはそれを緊急に必要としている人は自分でそれを把握することができます幸いなことに、コードのすべての「歯車」では短いです。



その主な要素に注意を払います。



実装する必要がある関数のセットから始めましょう。 ドキュメントでそれぞれの機能を確認できます。



CompoundExpressionClearAllSetDelayedOptionalPatternBlankImageImageResizeListRuleColorSpaceWithSetImageDimensionsCreateDialogExpressionCellDynamicModuleGridDefaultButtonDialogReturnIfLessLengthNoneDropTransposePartSpanReplaceAllRescaleAllMinMaxRuleDelayedRealRoundCopyToClipboardBSplineCurveSplineDegreeTabViewRowSliderDynamicTimesPiPowerImageSizeSmallSlider2DSetterBarInputFieldFieldSizeAlignmentLeftSpacingsAutomaticLocatorPaneFramedGraphicsInsetCosSinEdgeFormDirectiveAbsoluteThicknessRGBColorOpacityYellowRectangleDashedBluePlotRangePlusLocatorAutoCreateTrueCenterTopAxesAspectRatio初期化NullConditionStringFileExistsQImportBlankNullSequenceEchoInactiveNothing



このプログラムの主な機能の1つは、インタラクティブなスペースとオブジェクトを作成するDynamicModule関数です。 その助けを借りて、構造全体の「復活」があります。



グリッド機能は、スペースを整理するために必要です-さまざまな形状のテーブルを作成し、セルにコンテンツを配置できます:テキスト、スライダー、イラスト、インタラクティブなオブジェクトなど。



関数LocatorPaneSliderSlider2DInputFieldは、インタラクティブな要素-ポイント、スライダー(それぞれ1次元と2次元)を選択できるフィールド、テキスト入力フィールド(関数定義領域用)を作成するのに役立ちます。



グラフィックプリミティブを「描画」するには、 Graphics関数を使用します(必要に応じて3DでGraphics3Dを使用します)。



そしてもちろん、ここではBSplineCurve関数が最も重要です。これにより、完成したBスプラインカーブの形で一連のポイントを表すことができます。







以下のビデオでは、プログラムがどのようにライブで動作するかを見ることができます。







プログラムの最終コード



実際、最終的な機能は見た目ほど大きくありません。 もちろん、これはWolfram言語の優れた機能の直接的な結果ですが:



コードを表示




ClearAll[graphicsDigitizing]; graphicsDigitizing[image_Image: ImageResize[Image[{{{1,1,1}}},ColorSpace->"RGB"],{600,600}]]:=With[ {im=ImageResize[image,600]}, With[ {imdim=ImageDimensions[im]}, CreateDialog[{ ExpressionCell[ DynamicModule[ {degree,xmin=0,xmax=1,ymin=0,ymax=1,currentFunction,u,unew,udiap,\[Alpha],\[Beta]1,\[Beta]2}, Grid[ { { DefaultButton[ "    ", DialogReturn[ With[ {var1=If[ Length[u]<4, None, unew=Drop[u,2]; udiap=Transpose[u[[1;;2]]]; Transpose[ { Rescale[unew[[All,1]],{Min[udiap[[1]]],Max[udiap[[1]]]},{xmin,xmax}], Rescale[unew[[All,2]],{Min[udiap[[2]]],Max[udiap[[2]]]},{ymin,ymax}]} ]/.x_Real:>Round[x,0.01]],var2=degree}, CopyToClipboard[BSplineCurve[var1,SplineDegree->var2]]] ]] }, { TabView[ {""->Grid[ { { Grid[ { { Row[{" :",Slider[Dynamic@\[Alpha],{-Pi/6,Pi/6},ImageSize->Small]}," "] }, { Row[{":",Slider2D[Dynamic[\[Beta]1],{0.2 Max[imdim] {-1,-1},0.2 Max[imdim] {1,1}}],Slider2D[Dynamic[\[Beta]2],{0.2 Max[imdim] {-1,-1},0.2 Max[imdim] {1,1}}]}," "] }, { Row[{" :",SetterBar[Dynamic@degree,{0,1,2,3,4}]}," "] }, { Grid[{{"\!\(\*SubscriptBox[\(x\), \(min\)]\) =", InputField[Dynamic[xmin],FieldSize->{3,1}],"\!\(\*SubscriptBox[\(x\), \(max\)]\) =", InputField[Dynamic[xmax],FieldSize->{3,1}]},{"\!\(\*SubscriptBox[\(y\), \(min\)]\) =", InputField[Dynamic[ymin],FieldSize->{3,1}],"\!\(\*SubscriptBox[\(y\), \(max\)]\) =", InputField[Dynamic[ymax],FieldSize->{3,1}]}}] }}, Alignment->Left, Spacings->{Automatic,1}], LocatorPane[ Dynamic@u, Framed@Dynamic@Graphics[{Inset[im,{0,0},{0,0},imdim,{Cos[\[Alpha]],Sin[\[Alpha]]}], {EdgeForm[Directive[AbsoluteThickness[3],RGBColor[{214,0,0}/255]]], Opacity[0.2,Yellow], Rectangle[u[[1]],u[[2]]]}, {Dashed,Blue,AbsoluteThickness[4], If[Length[u]<4,BSplineCurve[u[[1;;2]],SplineDegree->2],BSplineCurve[Drop[u,2],SplineDegree->degree]] }}, PlotRange->Transpose[{\[Beta]1,imdim+\[Beta]2}],ImageSize->600],LocatorAutoCreate->True] } },Alignment->{Center,Top} ], ""->Dynamic@Graphics[ {Blue,AbsoluteThickness[2], If[Length[u]<4, BSplineCurve[u[[1;;2]],SplineDegree->2], BSplineCurve[unew=Drop[u,2]; udiap=Transpose[u[[1;;2]]]; Transpose[ {Rescale[unew[[All,1]],{Min[udiap[[1]]],Max[udiap[[1]]]},{xmin,xmax}], Rescale[unew[[All,2]],{Min[udiap[[2]]],Max[udiap[[2]]]},{ymin,ymax}]}], SplineDegree->degree]]}, PlotRange->{{xmin,xmax},{ymin,ymax}}, ImageSize->600, Axes->True, AspectRatio->imdim[[2]]/imdim[[1]]] },Alignment->Center] } } ], Initialization:>(u={{0,0},imdim};\[Alpha]=0; degree=3;\[Beta]1=0.1 Max[imdim] {-1,-1};\[Beta]2=0.1 Max[imdim] {1,1})] ]}];]]; graphicsDigitizing[image_String/;FileExistsQ[image]]:=graphicsDigitizing[Import[image]]; graphicsDigitizing[x___]:=(Echo[Inactive[graphicsDigitizing][x],"  : "]; Nothing)
      
      





サンプルを使用してデジタル機能を操作する利点



当然、デジタル化前のグラフィックスでは作業は非常に困難ですが、たとえばプログラムを使用してスケジュールをデジタル化した後は、すでに多くのことができます。 いくつかの例を示します。



たとえば、グラフを与えます:







それをデジタル化し( 上記のビデオを参照 )、計算を行いましょう。



まず、プログラムの作業中に取得した式の先頭部分をBSplineCurveからBSplineFunction置き換えるだけで 、すでに計算を実行できる分析式を作成します。







唯一の欠点は、そのような関数が1に正規化されることです。つまり、関数f(t)は、tを0から1に変更すると、そのすべての値(Bスプラインのポイント)を実行します。







ただし、これは簡単に戦えます。 補間多項式を作成するだけで十分です。







その後、すでに何でもできます。



たとえば、1〜9のグラフを作成します。







タスク領域全体に機能を統合します。







導関数をプロットします。







曲線の長さを見つける:







または、曲線の分析表現(パラメーター形式):





イラスト付きのコード
 pts=Rationalize[{{0.01`,10.92`},{0.19`,16.36`},{0.34`,20.76`},{0.55`,25.17`},{0.96`,29.57`},{1.9100000000000001`,34.49`},{2.74`,38.63`},{3.38`,42.09`},{3.97`,44.03`},{4.47`,49.77`},{4.88`,56.5`},{5.29`,63.24`},{5.65`,69.19`},{6.0600000000000005`,74.63`},{6.53`,78.52`},{7.0200000000000005`,83.96000000000001`},{7.46`,86.55`},{8.02`,89.4`},{8.26`,86.55`},{8.67`,82.4`},{9.21`,80.85000000000001`},{9.57`,79.81`},{9.93`,79.81`}},1/100]; ptsL=Length[pts]; splineDegree=3; knots=ConstantArray[0,splineDegree]~Join~Subdivide[ptsL-splineDegree]~Join~ConstantArray[1,splineDegree]; FullSimplify@Simplify[ Sum[ pts[[i+1]]PiecewiseExpand[BSplineBasis[{splineDegree,knots},i,t]], {i,0,ptsL-1}] ]
      
      





もちろん、最初のスケジュールを単純に調整することもできます。







エピローグ



デジタル化機能についての話があなたにとって有用であり、私たちのアルゴリズムを使用できることを願っています。 前の記事でお約束したように、アプリケーションとその内部にあるアルゴリズムについて、さらに多くの新しいストーリーが見つかります。


プロジェクト「 チューター:数学 」に関する一連の記事の中で、統一国家試験とVLRに備えるための記事。



All Articles