Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graphics 在Mathematica中绘制时钟面(寻找更好的解决方案)_Graphics_Wolfram Mathematica_Drawing_Clock - Fatal编程技术网

Graphics 在Mathematica中绘制时钟面(寻找更好的解决方案)

Graphics 在Mathematica中绘制时钟面(寻找更好的解决方案),graphics,wolfram-mathematica,drawing,clock,Graphics,Wolfram Mathematica,Drawing,Clock,我试图找到一个在Mathematica中绘制钟面状图形对象的通用解决方案。我已经实现了自己的一个版本,但我认为必须存在一个更好的解决方案。一个简洁的版本,更少的代码或更清晰的思维过程将不胜感激 我的版本: radius = 1; elementList = Join[Table[i, {i, 3, 1, -1}], Table[i, {i, 12, 4, -1}]]; elementNumber = Length[elementList]; thetaList = Table[i, {i,

我试图找到一个在Mathematica中绘制钟面状图形对象的通用解决方案。我已经实现了自己的一个版本,但我认为必须存在一个更好的解决方案。一个简洁的版本,更少的代码或更清晰的思维过程将不胜感激

我的版本:

radius = 1;
elementList = 
  Join[Table[i, {i, 3, 1, -1}], Table[i, {i, 12, 4, -1}]];
elementNumber = Length[elementList];
thetaList = Table[i, {i, 0, 2 Pi, 2 Pi/elementNumber}][[1 ;; 12]];
coordinateList = Map[{radius*Cos[#], radius*Sin[#]} &, thetaList];
objectList = 
  Map[Style[#, FontFamily -> "Georgia", FontSize -> 30] &, 
   elementList];
Graphics[
 Join[
  MapThread[Text[#1, #2] &, {objectList, coordinateList}],
  {Circle[{0, 0}, 1.2*radius]}
  ]
 ]

以下是一个函数的版本,它概括了时钟面的生成,允许您轻松更改数字的样式、“小时数”和时钟面的半径:

Options[clockFace] = {FontFamily -> "Georgia", FontSize -> 30};
clockFace[hours_Integer, radius_?NumericQ, opts : OptionsPattern[]] /;
   hours > 0 && Im[radius] == 0 && radius > 0 :=
 With[{range = Range[12]},
  With[{objects = 
        Style[#, 
          FilterRules[{opts}, Options[Style]] ~Join~ Options[clockFace]] & /@ range,
       thetas = Pi/2 - 2 Pi*range/hours},
  Graphics[Append[
     MapThread[Text[#1, {Cos[#2], Sin[#2]}] &, {objects, thetas}],
     Circle[radius*1.2]]]]]
有些事情只是数学式的问题;比如说,

FilterRules[{opts}, Options[Style]] ~Join~ Options[clockFace]
是将相关可选参数传递给
Style
的方法,同时确保在相关位置使用
钟面
的默认值,因为Mathematica将使用它在规则列表中找到的第一个适用规则(函数选项只是规则列表)。我还使用了
来命名事物,这就是为什么会有嵌套;其他人可能更喜欢使用单个
模块
。无论哪种方式,只要有可能,最好使事情成为局部变量


不过,最大的变化是使用
Range
按顺序生成数字列表,然后调整
thetas
的定义,使所有内容都放在正确的位置。我认为更容易看到发生了什么,因为减号意味着你在顺时针方向移动,通过
Pi/2
进行偏移,很明显你是从时钟的顶端开始的

这里有一种制作时钟的方法:

clockFace = Import["http://i.imgur.com/ufanv.jpg"];
{hour, minute, second} = Take[Date[], -3];
hour = Mod[hour, 12] + minute/60.; 
Graphics3D[
{
 {Texture[clockFace], 
      Polygon[{{-1, -1, 0}, {1, -1, 0}, {1, 1, 0}, {-1, 1, 0}},
         VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}
      ]
 }, 
 {Black, AbsoluteThickness[8], 
      Line[{{0, 0, 0}, 
       .55 {Cos[Pi/2 - 2 Pi hour/12], Sin[Pi/2 - 2 Pi hour/12], 0}}
      ]
 },
 {Black, AbsoluteThickness[5], 
      Line[{{0, 0, 0}, 
       .8 {Cos[Pi/2 - 2 Pi minute/60], Sin[Pi/2 - 2 Pi minute/60], 0}}
      ]
 }
}, 
Boxed -> False, Lighting -> "Neutral"]

添加

这是一个旋转的3D时钟,供您娱乐:

clockFace = Import["http://i.imgur.com/ufanv.jpg"];
vtc = VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
hand[thickness_, radius_, time_] := {AbsoluteThickness[thickness],
   Line[{{0, 0, -1}, {radius Cos[Pi/2 + 2 Pi time],
      radius Sin[Pi/2 + 2 Pi time], -1}}],
   Line[{{0, 0, 1}, {radius Cos[Pi/2 - 2 Pi time],
      radius Sin[Pi/2 - 2 Pi time], 1}}],
   Line[{{0, -1, 0}, {radius Cos[Pi/2 - 2 Pi time], -1,
      radius Sin[Pi/2 - 2 Pi time]}}],
   Line[{{0, 1, 0}, {radius Cos[Pi/2 + 2 Pi time], 1,
      radius Sin[Pi/2 + 2 Pi time]}}],
   Line[{{-1, 0, 0}, {-1, radius Cos[Pi/2 + 2 Pi time],
      radius Sin[Pi/2 + 2 Pi time]}}],
   Line[{{1, 0, 0}, {1, radius Cos[Pi/2 - 2 Pi time],
      radius Sin[Pi/2 - 2 Pi time]}}]};
Dynamic[
  {hour, minute, second} = Take[Date[], -3];
  hour = Mod[hour, 12] + minute/60.;
  Graphics3D[{
    {Texture[clockFace],
     Polygon[{{1, -1, -1}, {-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}},
      vtc],
     Polygon[{{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}}, vtc],
     Polygon[{{-1, 1, -1}, {-1, -1, -1}, {-1, -1, 1}, {-1, 1, 1}},
      vtc], Polygon[{{1, -1, -1}, {1, 1, -1}, {1, 1, 1}, {1, -1, 1}},
      vtc], Polygon[{{-1, -1, -1}, {1, -1, -1}, {1, -1, 1}, {-1, -1,
        1}}, vtc],
     Polygon[{{1, 1, -1}, {-1, 1, -1}, {-1, 1, 1}, {1, 1, 1}}, vtc]
     }, {Black,
     hand[8, .55, hour/12],
     hand[5, .8, minute/60],
     hand[3, .8, second/60]
     }
    },
   Boxed -> False, Lighting -> "Neutral",
   ViewPoint ->
    5 {Cos[2 Pi second/60], Sin[2 Pi second/60],
      Sin[2 Pi second/30]}, SphericalRegion -> True,
Background -> Black, ImageSize -> Full]] // Deploy

以下是一个工作的3D时钟,通过将@Arnoud的答案与以下内容轻松结合而成:

编辑

动画是在计划任务中使用光栅化[]捕获的

a = Graphics3D[(* etc etc*)];
b = {};
t = CreateScheduledTask[AppendTo[b, Rasterize@a], {2, 30}];
StartScheduledTask[t];
While[MatchQ[ScheduledTasks[], {ScheduledTaskObject[_, _, _, _,True]}],Pause[1]];
RemoveScheduledTask[ScheduledTasks[]];
Export["c:\\test.gif", b, "DisplayDurations" -> 1]

你的方法很好。只是有点乱。以下是我的解释:

hours = 12;
radius = 1;
thetaList = Rest@Range[2 Pi, 0, -2 Pi/hours] + Pi/2;
coordinateList = radius {Cos@#, Sin@#} & /@ thetaList;
Graphics[{
  FontFamily -> "Georgia",
  FontSize -> 30,
  Text ~MapThread~ {Range@hours, coordinateList},
  Circle[{0, 0}, 1.2 radius]
}]
Mathematica有一种叫做内置的东西。从文档中可以看出,为时钟表面设计样式的可能性是无穷的。裸骨版本如下所示:

ClockGauge[]

也许这是一个很好的起点:我认为@BrettChampion的建议完美地回答了这个问题。我对问这个问题感到有点惭愧(在我问这个问题之前,我应该先问谷歌和文档,然后才问)。我应该保留还是删除这篇文章,哪个选择对社区更有利?我会保留你的文章。有很多有趣的方法来构造时钟(和时钟面)。@Ning IMHO,作为一个学习数学并每天使用它的人,我说保留它。下面的两个答案很有趣,我喜欢通过观察其他人如何处理这类问题来学习(即两个非常不同的答案)。+1,好的。这是一种错误。我甚至下载了v8以便运行它。@rcollyer我恐怕不明白。怎么了?对不起,是口语。《城市词典》中的单词与我在这里的用法最为接近。具体来说,我是在评论使用一个非常强大的工具来创建精确的时钟动画的讽刺。@rcollyer您注意到上次编辑中使用了
ScheduledTask
?我以前从来没有这样用过!不,我没有。哇,我觉得第一次使用是荒谬的。这个更糟糕,也更有趣。也许你可以使用类似于
Polygon[#,vtc]&/@(PolyhedronData[“Cube”,“VertexCoordinates”][[[#]]]和/@PolyhedronData[“Cube”,“faceindex”])
的方法来获取面coords@belisarius,这是一个很好的提示,但我必须单独调整多边形,使侧面的多边形垂直。是的。我想知道是否可以用排列来解决这个问题。我没有很努力,但找不到一个明显的方法。请看问题中的时间戳:)@belisarius哦,好吧,在这里也有这个解决方案也没什么坏处。我想这个网站上几乎所有关于Mma的问题都可以重新编写,因为大多数问题都来自v7和v8:D
ClockGauge[]