创建一个模拟时钟


24

创建一个模拟时钟

目标:使用任何编程语言来创建可工作的模拟时钟。

要求:

  • 您的时钟应至少具有小时和分钟指针。
  • 产生的时钟可以是图像,动画或ASCII艺术形式。
  • 预计时钟会显示当地时间。

可选的:

  • 除了分钟和小时指针,您还可以使时钟显示秒指针。
  • 如果需要,您还可以将时区设置为可配置的。
  • 您可以自由选择是否忽略或处理有关leap秒的问题。
  • 如果用户调整系统时钟或发生日光变化,您可能会想想程序会发生什么。

由于这是一场,因此请发挥创造力,并画一些漂亮的时钟以备不时之需。除了我不会接受自己的答案外,大多数赞成者都胜出

最后,建议(但不是必需)在答案中张贴时钟的至少一个屏幕截图(或在使用ASCII字体的情况下输出文本)。这样,人们就无需编译并运行它即可查看它的含义。


该问题旨在恢复已删除的问题。

请注意,它不是这个其他问题的重复。这个问题是要求ASCII艺术的。这不限于ASCII艺术,而是,因此预期答案会大不相同。


我的囊壳溶液:xclock。需要安装xclock。
juniorRubyist

Answers:


31

SVG + Javascript

SVG模拟时钟截图

▶▶▶现场演示here

它使用SVG的内置动画功能来旋转指针,并使用一些附加的Javascript来获取本地时间并设置初始指针位置。它可以在Chrome和Safari中正常运行,并且应与大多数现代浏览器兼容,因为它不使用任何滤镜效果。

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" width="400" height="400" version="1.0">
  <defs>
    <linearGradient id="a" x1="0%" y1="100%" x2="0%" y2="0%">
      <stop offset="0%" style="stop-color:#777799"/>
      <stop offset="100%" style="stop-color:#ffffff"/>
    </linearGradient>
    <linearGradient id="b" x1="0%" y1="100%" x2="0%" y2="0%">
      <stop offset="0%" style="stop-color:#ffffff"/>
      <stop offset="25%" style="stop-color:#b6b6cc"/>
      <stop offset="40%" style="stop-color:#515177"/>
      <stop offset="48%" style="stop-color:#ffffff"/>
      <stop offset="56%" style="stop-color:#ffffff"/>
      <stop offset="75%" style="stop-color:#8b8baa"/>
      <stop offset="98%" style="stop-color:#efeff4"/>
      <stop offset="100%" style="stop-color:#fbfbfc"/>
    </linearGradient>
    <linearGradient id="c" x1="0%" y1="100%" x2="0%" y2="0%">
      <stop offset="0%" style="stop-color:#ffffff"/>
      <stop offset="100%" style="stop-color:#777799"/>
    </linearGradient>
    <radialGradient id="d" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
      <stop offset="0%" style="stop-color:#ffffff"/>
      <stop offset="40%" style="stop-color:#ffffff"/>
      <stop offset="70%" style="stop-color:#e6e6ee"/>
      <stop offset="92%" style="stop-color:#b6b6cc"/>
      <stop offset="100%" style="stop-color:#636388"/>
    </radialGradient>
    <radialGradient id="e" cx="50%" cy="150%" r="200%" fx="50%" fy="150%">
      <stop offset="0%" style="stop-color:#ffffff;stop-opacity:0"/>
      <stop offset="59%" style="stop-color:#ffffff;stop-opacity:0"/>
      <stop offset="60%" style="stop-color:#ffffff;stop-opacity:0.6"/>
      <stop offset="70%" style="stop-color:#ffffff;stop-opacity:0.3"/>
      <stop offset="100%" style="stop-color:#ffffff;stop-opacity:0.0"/>
    </radialGradient>
  </defs>
  <g transform="translate(200 200)">
    <circle cx="0" cy="0" r="200" fill="#cecedd"/>
    <circle cx="0" cy="0" r="196" stroke="url(#a)" stroke-width="5" fill="url(#b)"/>
    <circle cx="0" cy="0" r="170" stroke="url(#c)" stroke-width="4" fill="url(#d)"/>
    <circle cx="0" cy="0" r="172" stroke="#ffffff" stroke-width="0.5" fill="none"/>
    <circle cx="0" cy="0" r="193.5" stroke="#ffffff" stroke-width="0.5" fill="none"/>
    <g id="O">
      <polygon points="4,155 4,130 -4,130 -4,155" style="fill:#777799;stroke:#313155;stroke-width:1"/>
      <polygon points="4,-155 4,-130 -4,-130 -4,-155" style="fill:#777799;stroke:#313155;stroke-width:1"/>
    </g>
    <g transform="rotate(30)"><use xlink:href="#O"/></g>
    <g transform="rotate(60)"><use xlink:href="#O"/></g>
    <g transform="rotate(90)"><use xlink:href="#O"/></g>
    <g transform="rotate(120)"><use xlink:href="#O"/></g>
    <g transform="rotate(150)"><use xlink:href="#O"/></g>
    <polygon id="h" points="6,-80 6,18 -6,18 -6,-80" style="fill:#232344">
      <animateTransform id="ht" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="86400s" repeatCount="indefinite"/>
    </polygon>
    <polygon id="m" points="3.5,-140 3.5,23 -3.5,23 -3.5,-140" style="fill:#232344">
      <animateTransform id="mt" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="3600s" repeatCount="indefinite"/>
    </polygon>
    <polygon id="s" points="2,-143 2,25 -2,25 -2,-143" style="fill:#232344">
      <animateTransform id="st" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="60s" repeatCount="indefinite"/>
    </polygon>
    <circle cx="0" cy="0" r="163" fill="url(#e)"/>
  </g>
  <script type="text/javascript"><![CDATA[
    var d = new Date();
    var s = d.getSeconds();
    var m = d.getMinutes() + s/60;
    var h = (d.getHours() % 12) + m/60 + s/3600;
    document.getElementById('st').setAttribute('from',s*6);
    document.getElementById('mt').setAttribute('from',m*6);
    document.getElementById('ht').setAttribute('from',h*30);
    document.getElementById('st').setAttribute('to',360+s*6);
    document.getElementById('mt').setAttribute('to',360+m*6);
    document.getElementById('ht').setAttribute('to',360+h*30);
  ]]></script>
</svg>

哇!看起来超仿形所缺少的只是阴影下的阴影!

带有阴影效果看起来不错,但动画在Chrome中可能会出现一点故障。
吱吱作响的ossifrage,2014年

1
凉。我不知道SVG可以做到这一点。
塞巴斯蒂安·内格拉苏斯

17

Java 8

我制作了一个时钟,该时钟会根据一天中的小时更改颜色,以显示当地时间。随着时间的流逝,它将逐渐改变其颜色,白天使用较亮的颜色,而夜间使用较暗的颜色。

窗口可调整大小,时钟将自动调整为您选择的大小。

此外,如果用户调整系统时钟或如果夏令时发生变化,时钟将自动反映出来。

有两种形式可以运行它:

  1. 运行ClockDemo文件,即java clock.ClockDemo。这将打开一个窗口,您将在那里看到时钟。

  2. 运行ClockSave文件,即java clock.ClockSave filename width height [HH:mm:ss]。这只会将时钟保存在具有给定文件名,宽度和高度的PNG文件中。时钟将以给定的时间绘制,如果省略,则以当前时间绘制。例如,如果您运行它,java clock.ClockSave clock.png 600 500 12:38:24它将把时钟保存在clock.png文件中的600x500图像中,并且时钟将显示为12:38:24 AM。在00-23间隔内使用小时。


屏幕截图

以下是一些屏幕截图和生成的文件:

00:36:50 AM:

00:36:50上午

02:38:51 AM:

02:39:51 AM

上午06:42:13:

上午06:42:13

上午11:15:28:

上午11:15:28

下午05:02:37:

下午05:02:37

下午07:11:30:

下午07:11:30

09:29:34 PM:

下午09:29:34


源代码

我在名为的程序包中将源分为五个不同的文件clock

也可以在GitHub上获得

ClockDemo.java

package clock;

import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;

public class ClockDemo {
    public static void main(String[] args) {
        EventQueue.invokeLater(ClockDemo::runIt);
    }

    private static void runIt() {
        final JFrame j = new JFrame();
        j.setTitle("JClock");
        final JClock clock = new JClock(new CoolPaint());

        j.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                clock.stop();
                j.dispose();
            }
        });

        j.add(clock);
        j.setBounds(20, 20, 600, 500);
        j.setVisible(true);
        clock.start();
    }
}

ClockSave.java

package clock;

import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class ClockSave {
    public static void main(String[] args) {

        // Too much arguments.
        if (args.length < 3 || args.length > 4) {
            System.out.println("Bad usage: Should be java clock.ClockSave filename width height [HH:mm:ss]");
            return;
        }

        // Parse the image size.
        int h, w;
        try {
            w = Integer.parseInt(args[1]);
            h = Integer.parseInt(args[2]);
        } catch (NumberFormatException e) {
            System.out.println("Bad usage: Should be java clock.ClockSave filename width height [HH:mm:ss]");
            return;
        }

        // Parse the intended time.
        LocalTime time;
        if (args.length == 4) {
            try {
                DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss");
                time = LocalTime.parse(args[3], df);
            } catch (DateTimeParseException e) {
                System.out.println("Bad usage: Should be java clock.ClockSave filename width height [HH:mm:ss]");
                return;
            }
        } else {
            time = LocalTime.now();
        }

        // Save to an image.
        try {
            new CoolPaint().saveClock(w, h, time, args[0]);
        } catch (IOException e) {
            System.out.println("Error on image output: " + e.getMessage());
        }
    }
}

JClock.java

package clock;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import javax.swing.JComponent;

public class JClock extends JComponent {
    private static final long serialVersionUID = 1L;

    private final CoolPaint paint;
    private final Object lock;
    private Thread updater;

    public JClock(CoolPaint paint) {
        this.paint = paint;
        this.lock = new Object();
    }

    private void runClock() {
        int lastTime = -1;
        try {
            while (isRunning()) {
                Thread.sleep(10);
                int t = time();
                if (t != lastTime) {
                    lastTime = t;
                    repaint();
                }
            }
        } catch (InterruptedException e) {
            // Do nothing, the thread will die naturally.
        }
    }

    private int time() {
        return LocalTime.now().get(ChronoField.SECOND_OF_DAY);
    }

    private boolean isRunning() {
        synchronized (lock) {
            return updater == Thread.currentThread();
        }
    }

    public void start() {
        synchronized (lock) {
            if (updater != null) return;
            updater = new Thread(this::runClock);
            updater.start();
        }
    }

    public void stop() {
        synchronized (lock) {
            updater = null;
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        paint.paintClock(getWidth(), getHeight(), time(), (Graphics2D) g);
    }
}

ClockPaint.java

package clock;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import javax.imageio.ImageIO;

public interface ClockPaint {

    public void paintClock(int width, int height, int seconds, Graphics2D g2);

    public default void paintClock(int width, int height, LocalTime time, Graphics2D g2) {
        paintClock(width, height, time.get(ChronoField.SECOND_OF_DAY), g2);
    }

    public default void paintClock(int width, int height, Graphics2D g2) {
        paintClock(width, height, LocalTime.now(), g2);
    }

    public default void saveClock(int width, int height, String fileName) throws IOException {
        saveClock(width, height, LocalTime.now(), fileName);
    }

    public default void saveClock(int width, int height, LocalTime time, String fileName) throws IOException {
        saveClock(width, height, time.get(ChronoField.SECOND_OF_DAY), fileName);
    }

    public default void saveClock(int width, int height, int seconds, String fileName) throws IOException {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        paintClock(width, height, seconds, (Graphics2D) image.getGraphics());
        String f = fileName.endsWith(".png") ? fileName : fileName + ".png";
        ImageIO.write(image, "png", new File(f));
    }
}

CoolPaint.java

package clock;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

public class CoolPaint implements ClockPaint {

    private static final int SECONDS_IN_MINUTE = 60;
    private static final int SECONDS_IN_HALF_HOUR = 30 * SECONDS_IN_MINUTE;
    private static final int SECONDS_IN_HOUR = 60 * SECONDS_IN_MINUTE;
    private static final int SECONDS_IN_12_HOURS = 12 * SECONDS_IN_HOUR;

    private static final int AM_0_00 = 0;
    private static final int AM_3_00 = 3 * SECONDS_IN_HOUR;
    private static final int AM_4_30 = 4 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int AM_7_30 = 7 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int AM_12_00 = 12 * SECONDS_IN_HOUR;
    private static final int PM_4_30 = 16 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int PM_7_30 = 19 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int PM_9_00 = 21 * SECONDS_IN_HOUR;
    private static final int PM_12_00 = 24 * SECONDS_IN_HOUR;

    private static final Color BLACK = new Color(0, 0, 0);
    private static final Color DARK_GRAY = new Color(32, 32, 32);
    private static final Color DARK_BLUE = new Color(0, 0, 128);
    private static final Color PURPLE = new Color(128, 0, 128);
    private static final Color CYAN = new Color(0, 255, 255);
    private static final Color YELLOW = new Color(225, 225, 0);
    private static final Color PALE_YELLOW = new Color(224, 224, 64);
    private static final Color RED = new Color(255, 0, 0);
    private static final Color GREEN = new Color(0, 255, 0);
    private static final Color LIGHT_BLUE = new Color(128, 128, 255);
    private static final Color SKY_CYAN = new Color(48, 224, 224);

    private static final Color[] COLOR_CYCLE = {
        DARK_GRAY, LIGHT_BLUE, RED, PALE_YELLOW, GREEN, SKY_CYAN, LIGHT_BLUE, DARK_GRAY
    };

    private static final int RADIAL_PERIOD_LENGTH = PM_12_00 / COLOR_CYCLE.length;
    private static final String[] ROMAN = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"};

    private static class Painter {
        private final int width;
        private final int height;
        private final int seconds;
        private final int radius;
        private final Graphics2D g2;
        private final int cx;
        private final int cy;
        private final int secondColorIndex;
        private final int secondsInPeriod;
        private final Color pointersAndNumbersColor;

        public Painter(int width, int height, int seconds, Graphics2D g2) {
            this.width = width;
            this.height = height;
            this.seconds = seconds;
            this.radius = Math.min(width / 2, height / 2);
            this.cx = width / 2;
            this.cy = height / 2;
            this.g2 = g2;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            this.secondColorIndex = seconds / RADIAL_PERIOD_LENGTH;
            this.secondsInPeriod = seconds % RADIAL_PERIOD_LENGTH;

            int startIndex = (secondColorIndex + COLOR_CYCLE.length + 5) % COLOR_CYCLE.length;
            int endIndex = (secondColorIndex + COLOR_CYCLE.length + 6) % COLOR_CYCLE.length;
            Color color1 = COLOR_CYCLE[startIndex];
            Color color2 = COLOR_CYCLE[endIndex];
            this.pointersAndNumbersColor = mixColors(color1, color2, 0, RADIAL_PERIOD_LENGTH, secondsInPeriod);
        }

        private int mixColorComponent(int startComponent, int endComponent, double position) {
            int difference = endComponent - startComponent;
            return startComponent + (int) (difference * position);
        }

        private Color mixColors(Color startColor, Color endColor, int startTime, int endTime, int currentTime) {
            double normalized = (currentTime - startTime) / (double) (endTime - startTime);
            return new Color(
                    mixColorComponent(startColor.getRed(), endColor.getRed(), normalized),
                    mixColorComponent(startColor.getGreen(), endColor.getGreen(), normalized),
                    mixColorComponent(startColor.getBlue(), endColor.getBlue(), normalized));
        }

        private Color upperBackgroundColor() {
            if (seconds < 0) throw new IllegalArgumentException();
            if (seconds <= AM_3_00) return BLACK;
            if (seconds <= AM_4_30) return mixColors(BLACK, DARK_BLUE, AM_3_00, AM_4_30, seconds);
            if (seconds <= AM_7_30) return mixColors(DARK_BLUE, CYAN, AM_4_30, AM_7_30, seconds);
            if (seconds <= AM_12_00) return CYAN;
            if (seconds <= PM_4_30) return CYAN;
            if (seconds <= PM_7_30) return mixColors(CYAN, DARK_BLUE, PM_4_30, PM_7_30, seconds);
            if (seconds <= PM_9_00) return mixColors(DARK_BLUE, BLACK, PM_7_30, PM_9_00, seconds);
            if (seconds <= PM_12_00) return BLACK;
            throw new IllegalArgumentException();
        }

        private Color lowerBackgroundColor() {
            if (seconds < 0) throw new IllegalArgumentException();
            if (seconds <= AM_3_00) return mixColors(BLACK, DARK_BLUE, AM_0_00, AM_3_00, seconds);
            if (seconds <= AM_4_30) return mixColors(DARK_BLUE, PURPLE, AM_3_00, AM_4_30, seconds);
            if (seconds <= AM_7_30) return mixColors(PURPLE, YELLOW, AM_4_30, AM_7_30, seconds);
            if (seconds <= AM_12_00) return mixColors(YELLOW, CYAN, AM_7_30, AM_12_00, seconds);
            if (seconds <= PM_4_30) return mixColors(CYAN, YELLOW, AM_12_00, PM_4_30, seconds);
            if (seconds <= PM_7_30) return mixColors(YELLOW, PURPLE, PM_4_30, PM_7_30, seconds);
            if (seconds <= PM_9_00) return mixColors(PURPLE, DARK_BLUE, PM_7_30, PM_9_00, seconds);
            if (seconds <= PM_12_00) return mixColors(DARK_BLUE, BLACK, PM_9_00, PM_12_00, seconds);
            throw new IllegalArgumentException();
        }

        private void paintBackground() {
            Point2D p1 = new Point2D.Double(width / 2, 0);
            Point2D p2 = new Point2D.Double(width / 2, height);
            g2.setPaint(new GradientPaint(p1, upperBackgroundColor(), p2, lowerBackgroundColor()));
            g2.fillRect(0, 0, width, height);
        }

        private RadialGradientPaint colorOnCycle(Point2D center, float radius) {
            Color baseColor1 = COLOR_CYCLE[(secondColorIndex + COLOR_CYCLE.length - 1) % COLOR_CYCLE.length];
            Color baseColor2 = COLOR_CYCLE[secondColorIndex];
            Color baseColor3 = COLOR_CYCLE[(secondColorIndex + COLOR_CYCLE.length + 1) % COLOR_CYCLE.length];
            Color baseColor4 = COLOR_CYCLE[(secondColorIndex + COLOR_CYCLE.length + 2) % COLOR_CYCLE.length];

            Color start = mixColors(baseColor1, baseColor2, 0, RADIAL_PERIOD_LENGTH, secondsInPeriod);
            Color end = mixColors(baseColor3, baseColor4, 0, RADIAL_PERIOD_LENGTH, secondsInPeriod);
            float index2 = (RADIAL_PERIOD_LENGTH - secondsInPeriod) / (float) RADIAL_PERIOD_LENGTH / 2;
            float index3 = 0.5f + index2;
            float[] positions = index3 == 1.0 ? new float[] {0.0f, index2, 1.0f}
                    : new float[] {0.0f, index2, index3, 1.0f};
            Color[] colors = index3 == 1.0 ? new Color[] {start, baseColor2, end}
                    : new Color[] {start, baseColor2, baseColor3, end};

            return new RadialGradientPaint(center, radius, positions, colors);
        }

        private void paintClockArea() {
            Point2D center = new Point2D.Double(width / 2, height / 2);
            g2.setPaint(colorOnCycle(center, radius));
            g2.fillOval(width / 2 - radius, height / 2 - radius, radius * 2, radius * 2);
        }

        private double pointerRevolutionsToRadians(double angle) {
            return Math.toRadians((450 + angle * -360) % 360.0);
        }

        private void paintPointers() {
            double hAngle = pointerRevolutionsToRadians(seconds % SECONDS_IN_12_HOURS / (double) SECONDS_IN_12_HOURS);
            double mAngle = pointerRevolutionsToRadians(seconds % SECONDS_IN_HOUR / (double) SECONDS_IN_HOUR);
            double sAngle = pointerRevolutionsToRadians(seconds % SECONDS_IN_MINUTE / (double) SECONDS_IN_MINUTE);

            g2.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.drawLine(cx, cy, (int) (cx + Math.cos(hAngle) * radius * 0.55), (int) (cy - Math.sin(hAngle) * radius * 0.55));
            g2.drawLine(cx, cy, (int) (cx + Math.cos(mAngle) * radius * 0.85), (int) (cy - Math.sin(mAngle) * radius * 0.85));
            g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.drawLine(cx, cy, (int) (cx + Math.cos(sAngle) * radius * 0.85), (int) (cy - Math.sin(sAngle) * radius * 0.85));
        }

        private void paintNumbers() {
            Font originalFont = g2.getFont();
            double amplification = (int) Math.max(radius * 0.08, originalFont.getSize()) / (double) originalFont.getSize();
            AffineTransform at0 = AffineTransform.getScaleInstance(amplification, amplification);
            Font amplifiedFont = originalFont.deriveFont(at0);
            g2.setFont(amplifiedFont);
            FontMetrics fm = g2.getFontMetrics();

            for (int i = 1; i <= 12; i++) {
                double angle = pointerRevolutionsToRadians(i / 12.0);
                double textInclination = Math.toRadians(30 * i);
                AffineTransform at = AffineTransform.getRotateInstance(textInclination);
                at.scale(amplification, amplification);
                Font derivedFont = originalFont.deriveFont(at);
                g2.setFont(derivedFont);
                int pixelsOffset = fm.stringWidth(ROMAN[i]) / 2;
                int xPlot = (int) (cx + Math.cos(angle) * radius * 0.9 - pixelsOffset * Math.cos(textInclination));
                int yPlot = (int) (cy - Math.sin(angle) * radius * 0.9 - pixelsOffset * Math.sin(textInclination));
                g2.drawString(ROMAN[i], xPlot, yPlot);
            }
            g2.setFont(originalFont);
        }

        private void paintDots() {
            for (int i = 1; i < 60; i++) {
                if (i % 5 == 0) continue;
                double angle = pointerRevolutionsToRadians(i / 60.0);
                g2.fillRect((int) (cx + Math.cos(angle) * radius * 0.9) - 1, (int) (cy - Math.sin(angle) * radius * 0.9) - 1, 3, 3);
            }
        }

        public void paintClock() {
            paintBackground();
            paintClockArea();

            g2.setColor(pointersAndNumbersColor);
            g2.setPaint(pointersAndNumbersColor);
            paintNumbers();
            paintDots();
            paintPointers();
        }
    }

    @Override
    public void paintClock(int width, int height, int seconds, Graphics2D g2) {
        new Painter(width, height, seconds, g2).paintClock();
    }
}

我对各种桌面时钟感到沮丧(我需要一个:)),因此决定将您的代码用作简单时钟的基础。您是否有这个代码的Github存储库?
ipolevoy '18

@ipolevoy如您所愿,我将其添加到GitHub
维克多·斯塔夫萨

感谢您的努力!
ipolevoy '18

16

自由帕斯卡

该时钟显示月亮的时间,日期和相位。但是,与具有小窗口以显示月相的机械钟不同,在我的时钟中,整个面部都用来显示月相。今天2月14日是满月。您可以在下面看到接下来几天的预期输出。

uses graph,sysutils;

const hemisphere=-1; {-1=north,1=south}
MonthStr : array[1..12] of string [3] =
('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep ','Oct','Nov','Dec');

var yy,dd,mm,hh,mn,ss,ms: word;
var s: string; d2fullmoon,hour,min:real; sec:word;

var gd, gm, n : integer;
var right, left, centre: word;

begin

  gd := D4bit;
  gm := m640x480;
  initgraph(gd,gm,'');
  setbkcolor(blue);cleardevice; setbkcolor(black);
  setlinestyle(0,0,3);
  settextjustify(centertext,centertext);
  settextstyle(defaultfont,horizdir,2);

  while true do begin

    {output to console}

    DecodeDate(Date,YY,MM,DD);
    Writeln (Format ('Today is %d/%d/%d',[dd,mm,yy]));

    DecodeTime(Time,HH,Mn,SS,MS);
    Writeln (format('The time is %d:%d:%d.%d',[hh,mm,ss,ms]));

    d2fullmoon:=yy*(365*3+366)/4+mm*365/12+dd-2014*(365*3+366)/4-2*365/12-14;
    writeln ('days since full moon 14 feb 2014 ',d2fullmoon);

    if ss mod 15=0 then begin {Refresh display every 15 sec. Only the second hand is refreshed every sec.}

      {Draw circle and 180deg pie in yellow/black. Draw yellow or black ellipse on top. Add boxes for date}

      if sin(d2fullmoon/29.530588853*2*pi)*hemisphere>0 then right:=yellow else right:=black;
      left:=yellow-right;

      setcolor(right);setfillstyle(solidfill,right);
      fillellipse(320,240,200,200);

      setfillstyle(solidfill,left);setcolor(left);
      pieslice(320,240,90,270,200);

      if cos(d2fullmoon/29.530588853*2*pi)>0 then centre:=yellow else centre:=black;
      setcolor(centre); setfillstyle(solidfill,centre);
      fillellipse(320,240,abs(trunc(200*cos(d2fullmoon/29.530588853*2*pi))),200);

      setcolor (blue); setfillstyle(solidfill,blue);
      bar (270,135,370,165); bar (270,345,370,315);

      {fill in numbers}

      for n:=1 to 12 do begin
        setcolor(blue); setfillstyle(solidfill,blue);
        fillellipse(319+trunc(170*sin(n*pi/6)),240-trunc(170*cos(n*pi/6)),15,15);
        fillellipse(320+trunc(170*sin(n*pi/6)),240-trunc(170*cos(n*pi/6)),15,15);

        moveto(322+trunc(170*sin(n*pi/6)),240-trunc(170*cos(n*pi/6)));
        setcolor(white);
        str(n,s);outtext(s);
      end;

      {fill in date}

      str(yy,s);
      moveto(320,330);outtext(s);
      str(dd,s);
      moveto(320,150);outtext(s+monthstr[mm]);

      {draw hour and minute hands}

      hour:=hh+mn/60; min:=mn+ss/60;
      setcolor(cyan) ;setfillstyle(solidfill,cyan);
      moveto(320,240);
      linerel(trunc(140*sin(min*pi/30)),trunc(-140*cos(min*pi/30)));
      fillellipse(320+trunc(140*sin(min*pi/30)),240+trunc(-140*cos(min*pi/30)),7,7);
      moveto(320,240);
      linerel(trunc(100*sin(hour*pi/6)),trunc(-100*cos(hour*pi/6)));
      fillellipse(320+trunc(100*sin(hour*pi/6)),240+trunc(-100*cos(hour*pi/6)),7,7);
      fillellipse(320,240,10,10);

    end;

    {draw second hand in XOR mode, sleep for a second, then repeat to undraw}

    sec:=ss;
    setwritemode(xorput); setcolor(white);
    moveto(320+trunc(12*sin(sec*pi/30)),240+trunc(-12*cos(sec*pi/30)));
    linerel(trunc(150*sin(sec*pi/30)),trunc(-150*cos(sec*pi/30)));

    Sleep(1000);

    moveto(320+trunc(12*sin(sec*pi/30)),240+trunc(-12*cos(sec*pi/30)));
    linerel(trunc(150*sin(sec*pi/30)),trunc(-150*cos(sec*pi/30)));
    setwritemode(copyput);

  end;
  closegraph;
end.

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明


太好了,我真的很喜欢这个。
Victor Stafusa 2014年

12

我的朋友在TI 84 BASIC中写了一个简单的例子:

StoreGDB 0
CoordOff
GridOff
AxesOff
LabelOff
ExprOff
ClrDraw
62->Ymax
0->Ymin
94->Xmax
0->Xmin
Func
FnOff 0,1,2,3,4,5,6,7,8,9
PlotsOff 1,2,3
Full
Xmax/2->Xmax
Ymax/2->Ymax
~Xmax->Xmin
~Ymax->Ymin
Degree

15->H
18->M
20->S

Circle(36,~22,7)
Circle(0,0,30)
For(X,1,12)
Text(28-int(cos(X*30)*25),46+int(sin(30*X)*25),X)
End

{0,0,0}->|LANG

While getKey=0
getTime->|LTIME
getDate->|LDATE

Text(0,0,"12 HR")
Text(50,0,"24 HR")
If |LTIME(1)>12:Then
Text(6,7,(|LTIME(1)-12))
Else
Text(6,7,|LTIME(1))
End

If |LTIME(1)<=9
Then
Text(56,4,"O")
Text(56,8,|LTIME(1))
Else
Text(56,4,|LTIME(1))
End

Text(29,4,|LTIME(2))


If |LDATE(2)=1
Text(0,70,"JAN")

If |LDATE(2)=2
Text(0,70,"FEB")

If |LDATE(2)=3
Text(0,70,"MAR")

If |LDATE(2)=4
Text(0,70,"APR")

If |LDATE(2)=5
Text(0,70,"MAY")

If |LDATE(2)=6
Text(0,70,"JUN")

If |LDATE(2)=7
Text(0,70,"JUL")

If |LDATE(2)=8
Text(0,70,"AUG")

If |LDATE(2)=9
Text(0,70,"SEP")

If |LDATE(2)=10
Text(0,70,"OCT")

If |LDATE(2)=11
Text(0,70,"NOV")

If |LDATE(2)=12
Text(0,70,"DEC"
Text(2,81,",")
Text(0,85,|LDATE(3))
Text(8,75,|LDATE(1))


If |LTIME(1)>=12
Then
Text(50,80,"PM")
Else
Text(50,80,"AM")
End

If |LTIME(3)!=|LANG(3)/6
Line(0,0,sin(|LANG(3))*S,cos(|LANG(3))*S,0)

If |LTIME(2)!=|LANG(2)/6
Then
Line(0,0,sin(|LANG(2))*M,cos(|LANG(2))*M,0)
Line(0,0,sin(|LANG(1))*H,cos(|LANG(1))*H,0)
End

|LTIME(1)*30+|LTIME(2)/2->|LANG(1)
|LTIME(2)*6->|LANG(2)
|LTIME(3)*6->|LANG(3)

Line(0,0,sin(|LANG(1))*H,cos(|LANG(1))*H
Line(0,0,sin(|LANG(2))*M,cos(|LANG(2))*M
Line(0,0,sin(|LANG(3))*S,cos(|LANG(3))*S
End

在此处输入图片说明


如果可以的话,我会给+100 :)
Timtech

您可以发布屏幕截图吗?
Victor Stafusa 2014年

不,我的TI-84坏了,我找不到适合的模拟器
TheDoctor

2
@Victor-亲身体验了TI,更新了屏幕截图
TheDoctor 2014年

@TheDoctor尼斯。:)
Victor Stafusa 2014年

9

Mathematica

显示当地时间的普通香草时钟:

Dynamic@Refresh[ClockGauge@AbsoluteTime[], UpdateInterval -> 1]

时钟


标准选项

选项


手绘钟表

内置时钟表还有其他选择。这是一个。

时针和分针已实现连续扫描。它们与秒针一起更新。

u[i_, k_] := {Sin[2 \[Pi] i/k], Cos[2 \[Pi] i/k]};
Dynamic[{f = Date[], Clock[{1, 1}, 1]}]
Graphics[Dynamic@{Circle[{0, 0}, 1.175], Circle[{0, 0}, 1.2],

   (* tick marks at minutes *)
   Table[Text[".", u[i, 60]], {i, 60}],  

   (* hour labels *)
   Table[Text[i, u[i, 12]], {i, 12}],  

   (* hour hand *)
   {Darker@Red, Arrowheads[.12], Thickness[.0175], Arrow[{{0, 0}, .6 u[f[[4]]+f[[5]]/60, 12]}]},

   (*minute hand *)
   {Blue, Arrowheads[.08], Thickness[.0085], Arrow[{{0, 0}, .85 u[f[[5]]+f[[6]]/60, 60]}]},

   (*second hand *)
   {Thickness[.005], Arrow[{{0, 0}, .9 u[f[[6]], 60]}]}}, 
   BaseStyle -> 25]

时钟4


您已经在手绘量规代码块的顶部孤立了一行代码。我会编辑它,但是系统不允许一个字符的编辑,它只需要一个换行符。
乔纳森·范·马特雷

8

附言-最初旨在帮助我的孩子学习分辨时间。第1页显示当前时间,第2-4页为学习者页面。学习者使用的页面是rand随机的,因此每次处理时它们都是不同的。如果要显示当前时间,请使用Ghostscript制作PDF版本。适用于A4纸张的尺寸。

%!PS-Adobe-3.0
%%Creator: Toby Thurston
%%Title: (Pages of pedagogical clocks)
%%CreationDate: (2014-02-14)
%%BoundingBox: 12 12 583 828 
%%Pages: 1
%%EndComments
<< /PageSize [595 842] >> setpagedevice
%%BeginSetup
/clock {
  /mins exch def
  /hour exch def
  /r exch def % radius
  /cr r 100 div def
  % draw the minute marks
  12 { .5 setlinewidth 4 { 6 rotate r 0 moveto r 20 div 0 rlineto stroke } repeat
        2 setlinewidth     6 rotate r 0 moveto r 20 div 0 rlineto stroke } repeat  
  % numbers           
  /fontsize r 0.14 mul def
  /Helvetica findfont fontsize scalefont setfont
  /s 2 string def 
  /rr r 0.9 mul def
  1 1 12 { /n exch def /theta 90 30 n mul sub def
  /st n s cvs def st stringwidth pop /dx exch 2 div neg def
  rr theta cos mul rr theta sin mul moveto dx fontsize 3 div neg rmoveto st show
  } for

  % draw hands (unless hour is negative)
  -1 hour lt {
      gsave % hour hand first
      90 60 hour mul mins add 2 div sub rotate
      newpath
      0 2 moveto
      15 cr mul  3 cr mul 33 cr mul   0 cr mul 50 cr mul  3 cr mul curveto 
      55 cr mul 15 cr mul 60 cr mul   0 cr mul 76 cr mul  0 cr mul curveto
      60 cr mul  0 cr mul 55 cr mul -15 cr mul 50 cr mul -3 cr mul curveto 
      33 cr mul  0 cr mul 15 cr mul  -3 cr mul  0 cr mul -2 cr mul curveto
      closepath 0 0 .677 setrgbcolor fill
      grestore
      gsave % minute hand on top
      90 6 mins mul sub rotate
      newpath
      0 2 moveto
      15 cr mul 3 cr mul 33 cr mul 0         50 cr mul  1 cr mul curveto 
      65 cr mul 3 cr mul 83 cr mul 0         97 cr mul  0        curveto
      83 cr mul 0        65 cr mul -3 cr mul 50 cr mul -1 cr mul curveto 
      33 cr mul 0        15 cr mul -3 cr mul 0         -2 cr mul curveto
      closepath .635 0 0 setrgbcolor fill
      grestore
  } if 

  % finally do central dot (to cover starts of hands) and outer band      
  .5 setlinewidth
  0 0 moveto 0 0 r 20 div   0 360 arc fill
             0 0 r 1.07 mul 0 360 arc stroke

} def
%%EndSetup
%%Page: 1 1 
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  297 480 translate
  120 

  (%Calendar%) /IODevice resourcestatus {
   pop pop (%Calendar%) currentdevparams
   dup /Running get { dup /Hour get exch /Minute get }{ 0 0 } ifelse } { -1 -1 } ifelse

  clock
pgsave restore
showpage
%%Page: 2 2
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  75 -55 translate
  4 {
     5 { 0 165 translate % a page of clocks for learners
         50 rand 12 mod rand 60 mod clock 
         % line underneath           
         gsave [1 3] 0 setdash 50 neg dup 1.8 mul moveto 50 2 mul 0 rlineto stroke grestore
     } repeat
     146 5 165 mul neg translate
  } repeat
pgsave restore
showpage
%%Page: 3 3
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  75 -55 translate
  4 {
     5 { 0 165 translate    % whole multiple of five minutes only
         50 rand 12 mod rand 12 mod 5 mul clock 
         gsave [1 3] 0 setdash 50 neg dup 1.8 mul moveto 50 2 mul 0 rlineto stroke grestore
     } repeat
     146 5 165 mul neg translate
  } repeat
pgsave restore
showpage
%%Page: 4 4
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  75 -55 translate
  4 {
     5 { 0 165 translate    % quarter hours only
         50 rand 12 mod rand 4 mod 15 mul clock 
         gsave [1 3] 0 setdash 50 neg dup 1.8 mul moveto 50 2 mul 0 rlineto stroke grestore
     } repeat
     146 5 165 mul neg translate
  } repeat
pgsave restore
showpage
%%EOF

在此处输入图片说明 在此处输入图片说明


4
+1用于撰写附言来教孩子。你是一位了不起的父母。
乔纳森·范·马特雷

rand每次不会给您相同的结果吗?除非您以某种方式将其播种,也许(/dev/rand)(r)file read pop srand
luser droog 2014年

@luserdroog ...错误编号 仅srand在要固定 PS伪随机数序列中的位置时才需要。引用PSLRM:“执行srand特定值会导致随后的调用,rand以生成可重复的结果序列。”
Thruston 2014年

是的,但是解释器本身1 srand在执行用户程序之前进行了初始化。因此,您必须引入自己的熵才能获得不可重现的序列。尚未使用Distiller进行测试,但这是Ghostscript所做的。gsnd -q -dBATCH -c 'rand ='总是给我16807.
luser楚格设计

4

演示:http : //jsfiddle.net/kelunik/Vuuq8/7/embedded/result/

的HTML

<div id="clock">
    <div id="h"></div>
    <div id="m"></div>
    <div id="s"></div>
</div>

的CSS

html, body {
    margin: 0;
    padding: 0;
    text-align: center;
}
#clock {
    width: 100vmin;
    height: 100vmin;
    border-radius: 50%;
    border: 1vmin solid #333;
    position: relative;
    box-shadow: 0 0 5vmin rgba(0, 0, 0, .3);
    box-sizing: border-box;
    margin: 0 auto;
    transform: scale(.8);
}
#h, #m, #s {
    top: 50vmin;
    left: 50vmin;
    position: absolute;
}
#h:before, #m:before, #s:before {
    content:"";
    position: absolute;
    left: 100%;
    height: 0;
    box-shadow: 0 0 2vmin rgba(0,0,0,.2);
    border-radius: 50%;
}
#h:before {
    width: 25vmin;
}
#m:before {
    width: 35vmin;
}
#s:before {
    width: 45vmin;
}
#h:before {
    background: black;
    height: 4vmin;
    transform: translateY(-2vmin);
}
#m:before {
    background: black;
    height: 2vmin;
    transform: translateY(-1vmin);
}
#s:before {
    background: red;
    height: 2vmin;
    transform: translateY(-1vmin);
}

Java脚本

var h = document.getElementById('h');
var m = document.getElementById('m');
var s = document.getElementById('s');

setInterval(function () {
    refreshClock();
}, 1000);

function refreshClock() {
    var time = new Date;

    deg = time.getSeconds() * 6 - 90;
    s.style.webkitTransform = s.style.MozTransform = s.style.msTransform = s.style.transform = "rotate(" + deg + "deg)";

    deg = time.getMinutes() * 6 - 90;
    m.style.webkitTransform = m.style.MozTransform = m.style.msTransform = m.style.transform = "rotate(" + deg + "deg)";

    deg = time.getHours() % 12 * 30 - 90;
    h.style.webkitTransform = h.style.MozTransform = h.style.msTransform = h.style.transform = "rotate(" + deg + "deg)";
}

window.onload = function () {
    refreshClock();
};

我得到一个时钟,但时针和分针(秒)指向右边。什么都没动。
贾斯汀

您使用什么浏览器?
kelunik

Google Chrome ..
贾斯汀

您的答案看起来很有希望,很有趣,但现在却失败了。refreshClock函数中的transform CSS属性出了点问题(但是我不知道到底是什么)。在IE,chrome和firefox中尝试过,在任何人中都无法使用。
Victor Stafusa 2014年

@Victor似乎现在只能在Firefox中工作,但是在那里工作。
kelunik 2014年

4

这是处理中的一个:

int ax,ay,bx,by,cx,cy,dx,dy,last;
int q = 1;
float c = 0;
float h = 0;
float m = 0;

void setup() {
  size(displayWidth, displayHeight);
  background(0);
}

boolean sketchFullScreen() {
  return true;
}

void draw() {
  colorMode(HSB);
  fill(c,255,255,4);
  noStroke();
  rect(0,0,width,height);

  c+=0.4;
  if (c > 255) c = 0;

  colorMode(RGB);

  ax = int(random(displayWidth));
  ay = int(random(displayHeight));
  bx = ax + int(random(-50,50));
  by = ay + int(random(0,50));

  strokeWeight(1);

  if (random(0,1)>0.5) {
    fill(random(255),random(255),random(255));
    stroke(random(255),random(255),random(255));
  }
  else {
    noFill();
    stroke(random(255),random(255),random(255));
  }

  switch(int(random(6))) {
    case 0: // line
    line(ax,ay,bx,by);

    break;
    case 1: // bezier (arc)
    cx = int(random(ax-20,bx+20));
    cy = int(random(ay-20,by+20));
    dx = int(random(ax-20,bx+20));
    dy = int(random(ay-20,by+20));
    bezier(ax,ay,cx,cy,dx,dy,bx,by);

    break;
    case 2: // box
    quad(ax,ay,ax,by,bx,by,bx,ay);

    break;
    case 3: // ellipse
    ellipse(ax,ay,random(15,50),random(15,50));

    break;
    case 4: // triangle
    cx = int(random(ax-20,bx+20));
    cy = int(random(ay-20,by+20));
    dx = int(random(ax-20,bx+20));
    dy = int(random(ay-20,by+20));
    triangle(cx,cy,bx,by,dx,dy);

    break;
    case 5: // arc
    arc(ax,ay,random(15,50),random(15,50),random(2)*PI,random(2)*PI);

    break;  
  }

  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
  float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; 
  float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;

  cx = width/2;
  cy = height/2;

  // Draw the hands of the clock
  stroke(255);
  strokeWeight(1);
  line(cx, cy, cx + cos(s) * 500, cy + sin(s) * 500);
  strokeWeight(2);
  line(cx, cy, cx + cos(m) * 400, cy + sin(m) * 400);
  strokeWeight(4);
  line(cx, cy, cx + cos(h) * 300, cy + sin(h) * 300);

}

void mouseMoved() {
  exit();
}
void keyPressed() {
  background(0);
}

全屏


这个很漂亮!
danmcardle

它说我不能覆盖PApplet的方法吗?
Kritixi Lithos

@danmcardle:太丑了!
sergiol


3

GNUPLOT

unset clip points
set clip one
unset clip two
set bar 1.000000
unset border
set xdata
set ydata
set zdata
set x2data
set y2data
set timefmt x "%d/%m/%y,%H:%M"
set timefmt y "%d/%m/%y,%H:%M"
set timefmt z "%d/%m/%y,%H:%M"
set timefmt x2 "%d/%m/%y,%H:%M"
set timefmt y2 "%d/%m/%y,%H:%M"
set timefmt cb "%d/%m/%y,%H:%M"
set boxwidth
set style fill  empty border
set dummy t,y
set format x "% g"
set format y "% g"
set format x2 "% g"
set format y2 "% g"
set format z "% g"
set format cb "% g"
set angles radians
unset grid
set key title ""
unset key
unset label
unset arrow
unset style line
unset style arrow
set style histogram clustered gap 2 title  offset 0, 0, 0
unset logscale
set offsets 0, 0, 0, 0
set pointsize 1
set encoding default
unset polar
set parametric
unset decimalsign
set view 60, 30, 1, 1
set samples 100, 100
set isosamples 10, 10
set surface
unset contour
set clabel '%8.3g'
set mapping cartesian
set datafile separator whitespace
unset hidden3d
set cntrparam order 4
set cntrparam linear
set cntrparam levels auto 5
set cntrparam points 5
set size ratio 0 1,1
set origin 0,0
set style data points
set style function lines
set xzeroaxis linetype -2 linewidth 1.000
set yzeroaxis linetype -2 linewidth 1.000
set zzeroaxis linetype -2 linewidth 1.000
set x2zeroaxis linetype -2 linewidth 1.000
set y2zeroaxis linetype -2 linewidth 1.000
set ticslevel 0.5
set mxtics default
set mytics default
set mztics default
set mx2tics default
set my2tics default
set mcbtics default
set noxtics
set noytics
set noztics
set nox2tics
set noy2tics
set nocbtics
set title ""  offset character 0, 0, 0 font "" norotate
set timestamp bottom 
set timestamp ""  offset character 0, 0, 0 font "" norotate
set rrange [ * : * ] noreverse nowriteback  # (currently [0.000000:10.0000] )
set trange [ * : * ] noreverse nowriteback  # (currently [-5.00000:5.00000] )
set urange [ * : * ] noreverse nowriteback  # (currently [-5.00000:5.00000] )
set vrange [ * : * ] noreverse nowriteback  # (currently [-5.00000:5.00000] )
set xlabel ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set x2label ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set xrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set x2range [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set ylabel ""  offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90
set y2label ""  offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90
set yrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set y2range [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set zlabel ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set zrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set cblabel ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set cbrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set zero 1e-008
set lmargin -1
set bmargin -1
set rmargin -1
set tmargin -1
set locale "C"
set pm3d explicit at s
set pm3d scansautomatic
set pm3d interpolate 1,1 flush begin noftriangles nohidden3d corners2color mean
set palette positive nops_allcF maxcolors 0 gamma 1.5 color model RGB 
set palette rgbformulae 7, 5, 15
set colorbox default
set colorbox vertical origin screen 0.9, 0.2, 0 size screen 0.05, 0.6, 0 bdefault
set loadpath 
set fontpath 
set fit noerrorvariables
set arrow from 0,0 to sin(`date +%M`*3.1416/30),cos(`date +%M`*3.1416/30) 
set arrow from 0,0 to sin((`date +%H`%12)*3.1416/6)/2,cos((`date +%H`%12)*3.1416/6)/2
plot sin(t),cos(t)
reread

在Linux centos 6.5中


+1它甚至可以在Tektronix窗口中工作。xterm -t -e "gnuplot -e 'set term tek40xx' clock.plot"(令人
不快的

1
为了避免眨眼,您可以在重读之前添加“暂停60”
delfosse 2014年

3

简单的MATLAB代码,主要是为了欣赏24小时拨号工作而编写的。

具有24和12小时刻度盘的MATLAB手表示例 1 runWatch()暂停(0.6); 结束

% 20160829 :: grapesh@gmail.com
function runWatch()
cla;

dialHours  = 24;   % You can set it to 12 but why?
midnightUp = true; % defines position of midnight

col.hr = 'k'; 
col.mn = 'b'; 
col.sc = 'r'; 

logoStr = ['Perpetuum'];

xo = 0; yo = 0; 
RH  = 0.7;   RM  = 0.95; Rb = 0.5*(RH+RM);
RarrH = RH; RarrM = Rb; RarrS = RM;

fig_handle = findobj(allchild(0), 'flat', 'type', 'figure');

if isempty(fig_handle), set(gcf,'Position',[100 100 500 500]); end
hoursPhase = 3*pi/2; if midnightUp == true, hoursPhase = pi/2; end

hold on;
circle(xo, yo, RH,col.hr); 
circle(xo, yo, RM,col.mn);% ,'b');
circle(xo, yo, (RH+RM)/2,col.mn); %0.5*[1 1 1]);

text (xo - 2.5*RH/8+0.003, yo - RH/2-0.003, logoStr,'Color',0.5*[1 1 1],'FontAngle','italic');
text (xo - 2.5*RH/8,       yo - RH/2,       logoStr, 'FontAngle','italic')
axis equal; axis off;

% Hour dial
dh = pi/dialHours; h = 0:-dh:-pi+dh;
xH = RH*cos(2*h+hoursPhase); yH = RH*sin(2*h+hoursPhase);
xHb= Rb*cos(2*h+hoursPhase); yHb= Rb*sin(2*h+hoursPhase);
for n=1:length(xH)
    plot([xH(n),xHb(n)],[yH(n),yHb(n)],col.hr);
end
% Minute dial
dm = pi/60; m = 0:-dm:-pi+dm;
xM = RM*cos(2*m+pi/2); yM = RM*sin(2*m+pi/2);
xMb= Rb*cos(2*m+pi/2); yMb= Rb*sin(2*m+pi/2);
for n=1:length(xM)
    plot([xM(n),xMb(n)],[yM(n),yMb(n)],'Color',col.mn);
end

% Labels Hour
dhl = pi/dialHours; hl = 0:-dhl:-pi+dhl;  ratioH = -dialHours/180;
xHl= 0.5*(Rb+RH)*cos(2*hl+hoursPhase); 
yHl= 0.5*(Rb+RH)*sin(2*hl+hoursPhase);
for n=1:length(xHl)
    octagon (xHl(n), yHl(n), 0.3*(RH-Rb), 'w');
    text (xHl(n),yHl(n), num2str( rad2deg(hl(n)*ratioH) ),...
        'HorizontalAlignment','center','Rotation',rad2deg(2*hl(n)+hoursPhase-pi/2),...
        'FontWeight','b','FontSize',13,'Color',col.hr);    

end

% Labels Minute
dml = pi/12; ml=0:-dml:-pi+dml;  ratioM = -60/180; 
xMl= 0.5*(Rb+RM)*cos(2*ml+pi/2); yMl= 0.5*(Rb+RM)*sin(2*ml+pi/2);
for n=1:length(xMl)    
    octagon (xMl(n), yMl(n), 0.3*(RM-Rb), 'w');
    text (xMl(n),yMl(n), num2str( rad2deg(ml(n)*ratioM) ),...
        'HorizontalAlignment','center','Rotation',rad2deg(2*ml(n)), ...
        'FontWeight','b','Color',col.mn);
end

octagon (xo, yo-0.5*(RH+Rb), 0.04, col.hr);
octagon (xo, yo-0.5*(RH+Rb), 0.03, col.mn);

[now_year, now_month, now_day, ...
    now_hour, now_minute, now_second] = datevec(now);

% Arrows
K = -2*pi/dialHours; D = hoursPhase;
now_hour = now_hour + now_minute/60;
xarrowh = RarrH*cos(K*now_hour+D);
yarrowh = RarrH*sin(K*now_hour+D);
plot([0,xarrowh],[0,yarrowh],'Color',col.hr,'LineWidth',6); 
plot([0,xarrowh],[0,yarrowh],'Color',0.5*[1 1 1],'LineWidth',3); 
arrowhead (xarrowh,yarrowh,0.02,atan2(yarrowh,xarrowh),col.hr);

K = -2*pi/60; D = pi/2;
now_minute = now_minute + now_second/60;
xarrowm  = RarrH*cos(K*now_minute+D);
yarrowm  = RarrH*sin(K*now_minute+D);
xarrowml = RarrM*cos(K*now_minute+D);
yarrowml = RarrM*sin(K*now_minute+D);
plot([0,xarrowml],[0,yarrowml],'Color','k', 'LineWidth',4);
plot([0,xarrowml],[0,yarrowml],'Color',col.mn, 'LineWidth',2);
arrowhead (xarrowml,yarrowml,0.02,atan2(yarrowml,xarrowml),col.mn);

K = -2*pi/60; D = pi/2;
now_second = round(now_second);
xarrows = RarrH*cos(K*now_second+D);
yarrows = RarrH*sin(K*now_second+D);
xarrowsl = RarrS*cos(K*now_second+D);
yarrowsl = RarrS*sin(K*now_second+D);
plot([0,xarrowsl],[0,yarrowsl],'Color',col.sc,'LineWidth',1);
arrowhead (xarrowsl,yarrowsl,0.02,atan2(yarrows,xarrows)-pi,col.sc);

text(0.7,1,...
    [pad_with(floor(now_hour),2,'0'), ':', pad_with(floor(now_minute),2,'0'), ':', pad_with(now_second,2,'0')],...
    'FontSize',8,'FontWeight','n','BackgroundColor','w');

% Dial center
plot(xo, yo, 'ko','MarkerSize',10,'MarkerFaceColor','k');
plot(xo, yo, 'ko','MarkerSize',8,'MarkerFaceColor',0.5*[0 1 1]);

end

function [XX,YY] = circle(varargin)
%x and y are the coordinates of the center of the circle
%r is the radius of the circle
%0.01 is the angle step, bigger values will draw the circle faster but
%you might notice imperfections (not very smooth)

col = 'k';
x = varargin{1};
y = varargin{2};
r = varargin{3};
if length(varargin) > 3
    col = varargin{4};
end

ang=0:0.01:2*pi; 
xp=r*cos(ang);
yp=r*sin(ang);
XX = x+xp; YY = y+yp;
plot(XX,YY,'Color',col);
end

function octagon (xo, yo, R, col)

t = (1/16:1/8:1)'*2*pi;
x = R*cos(t);
y = R*sin(t);
fill(xo+x, yo+y,col,'EdgeColor','none')
end

% 20151001 :: grapesh@gmail.com
% Use :: str = pad_with (num, L, pad)
% function creates a string of L length
% padded with leading 'pad' symbol
% e.g., num=23,    L=4, pad='.' --> '..23';
% e.g., num='23W', L=4, pad=' ' --> ' 23W';
% 
function str = pad_with (num, L, pad)

if ~ischar(num)
    num = num2str(num);
end
strL = length(num);
if L<strL, L = strL; end;
for n=1:L-strL, str(n) = pad; end;
c = 0;
for n=L-strL+1:L
    c = c+1; str(n) = num(c);
end
end

function [x, y] = arrowhead (xo, yo, height, alpha, col)

x(1) = xo + height*sin(alpha);
y(1) = yo - height*cos(alpha);

x(2) = xo - height*sin(alpha);
y(2) = yo + height*cos(alpha);

x(3) = xo + 2*height*cos(alpha);
y(3) = yo + 2*height*sin(alpha);

fill(x, y,col,'EdgeColor','none')
end

1
欢迎来到PPCG!不错的第一答案。
FantaC

2

Python (带matplotlib)

这是在桌面上运行的非常基本的时钟。改变interval在第二到最后一行1连续运动,而不是每秒一个刻度。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import datetime

plt.rcParams['toolbar'] = 'None' 
fig = plt.figure(figsize=(4,4),facecolor='w')
ax = plt.subplot(111, polar=True)
plt.axes().get_yaxis().set_visible(False)

#12 labels, clockwise
marks = np.linspace(360./12,360,12, endpoint=True)
ax.set_thetagrids(marks,map(lambda m: int(m/30),marks),frac=.85,size='x-large')
ax.set_theta_direction(-1)
ax.set_theta_offset(np.pi/2)
ax.grid(None)

#hands
wids  = [.2,.03,.01]
lens  = [.75,.9,1]
clrs = plt.cm.winter(np.linspace(0, 1, 3))
factor = [12,60,60,1]

#convert time to radians
def timedata():
    x =  str(datetime.datetime.now().time())
    fig.canvas.set_window_title(x[:8])
    data = map(lambda n: float(n), x.split(':'))+[0]
    for i in range(3):
        data[i]=2*np.pi*(data[i]/factor[i]+data[i+1]/factor[i+1]/factor[i])
        data[i]-=(wids[i]/2)
    return data[:3]

#create hands
bars = ax.bar(timedata(), lens, width=wids, bottom=0.0, color=clrs, linewidth=0)
map(lambda b: b.set_alpha(0.5), bars)

#tick
def animate(i):
    map(lambda bt: bt[0].set_x(bt[1]), zip(bars,timedata()))
    return bars

ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), interval=1000)
plt.show()

pyclock


2

Mathematica

我从Mathematica帮助浏览器中使用了比我可能更多的演示代码,

时钟

Voltmeter3[v_, label_] := 
  Graphics[{{(*case*){EdgeForm[{Thickness[.007], GrayLevel[0]}], 
      GrayLevel[.2], 
      Rectangle[{-1.2, -1.1}, {1.2, 1.3}, 
       RoundingRadius -> .2]},(*case holes*){White, 
      Disk[{-1, -.9}, .05], Disk[{1, -.9}, .05], Disk[{1, 1.1}, .05], 
      Disk[{-1, 1.1}, .05]},(*case outer rim*){Black, 
      Disk[{0, .1}, 1.15], GrayLevel[.5], Disk[{-.02, .12}, 1.13], 
      GrayLevel[.2], Disk[{0, .1}, 1.11]},(*face highlight*)
     EdgeForm[{CapForm["Round"], Thickness[.02], Hue[.125, .7, .6]}], 
     Hue[.125, 1, 1], 
     Disk[{.02, .1}, 
      1, {1.1 Pi, -.1 Pi}],(*face shadow*){EdgeForm[{CapForm["Round"],
         Thickness[.01], Hue[.125, 1, 1]}], Hue[.125, 1, 1], 
      Disk[{-.02, .12}, 1, {1.1 Pi, -.1 Pi}]},(*face*){EdgeForm[], 
      Hue[.125, .5, 1], 
      Rotate[Polygon[({.1, -.04} + # &) /@ 
         Flatten[{{{0, 0}, {0, 1}}, 
           Array[{Sin[2 Pi*(#/50)], Cos[2 Pi*(#/50)]} &, 30]}, 1], 
        VertexColors -> 
         Flatten[{Hue[.125, 0, 1], 
           Array[Hue[.125, .5, 1] &, 50 + 1]}]], 
       30/50 Pi, {0, 
        0}]},(*case mid line highlight*){Hue[.125, .7, .6], 
      Thickness[.025], CapForm["Round"], 
      Line[{{-.95, -.2}, {0, .1}, {.95, -.2}}]},(*case mid disk \
highlight*){Hue[.125, .7, .6], Disk[{0, 0}, .25, {.95 Pi, .05 Pi}]}},
    Inset[
     AngularGauge[v, {0, 100}, GaugeFaceStyle -> None, 
      GaugeFrameStyle -> None, 
      GaugeMarkers -> 
       Graphics[{Hue[0, 1, .7], 
         Polygon[{{.1, .03}, {.1, -.03}, {.95, -.03}, {1, 
            0}, {.95, .03}}]}], 
      GaugeLabels -> {Placed[
         Style[label, FontFamily -> "Helvetica", Bold, 
          FontSize -> Scaled[.08], White], {.5, .35}]}, 
      LabelStyle -> 
       Directive[FontFamily -> "Helvetica", FontSize -> Scaled[.06]], 
      ScaleOrigin -> {{.85 Pi, .15 Pi}, .9}, 
      ScaleDivisions -> {2, 10}, 
      ScaleRanges -> {{Scaled[.75], Scaled[1]}}, 
      ScaleRangeStyle -> Hue[0, 1, .7, .7], AxesStyle -> Opacity[0], 
      TicksStyle -> {Thickness[.01], Thickness[.005]}, 
      ImageSize -> Automatic, ImagePadding -> None], {0, 0}, {0, 
      0}, {1.75, Automatic}], {(*case mid disk*)GrayLevel[.2], 
     Disk[{0, 0}, .2], GrayLevel[0], Disk[{0, 0}, .075], 
     Disk[{-.85, -.4}, .05], Disk[{.85, -.4}, .05]}}, 
   PlotRangeClipping -> True];

Dynamic@Refresh[
  GraphicsRow[{Voltmeter3[DateList[][[4]], "Hour"], 
    Voltmeter3[DateList[][[5]], "Minute"], 
    Voltmeter3[DateList[][[6]], "Second"]}], UpdateInterval -> 1]

1

C +开罗+ xcb

基本上删除了后记解决方案,并将其翻译为开罗。:)

这样做有些陷阱:ps使用度数,Cairo使用弧度;ps使用+ y 向上定向窗口,xcb使用+ y 向下定向窗口。

//xclock.c
//cc $(pkg-config --cflags --libs cairo xcb xcb-icccm) -o xclock xclock.c -lcairo -lxcb -lxcb-icccm
#include <math.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <cairo.h>
#include <cairo-xcb.h>
#include <xcb/xcb.h>
#include <xcb/xcb_image.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_icccm.h>

double deg_rad (double rad){
    return rad * (180.0/M_PI);
}

double rad_deg (double deg){
    return deg * (M_PI/180.0);
}

typedef struct {
    int width, height;
    int scrno;
    xcb_screen_t *scr;
    xcb_connection_t *connection;
    xcb_drawable_t win;
    unsigned int white;
    xcb_visualtype_t *visual_type;

    cairo_surface_t *surface;
    cairo_t *cr;
} Window;
Window window;

int makewindow()
{
    xcb_screen_iterator_t iter;
    xcb_depth_iterator_t depth_iter;
    uint32_t mask=0;
    uint32_t values[2];

    window.connection = xcb_connect(NULL,&window.scrno);
    iter = xcb_setup_roots_iterator(xcb_get_setup(window.connection));
    for (; iter.rem; --window.scrno, xcb_screen_next(&iter))
        if (window.scrno == 0)
        {
            window.scr = iter.data;
            break;
        }
    window.win = xcb_generate_id(window.connection);
    window.white = window.scr->white_pixel;
    mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
    values[0] = window.white;
    values[1] = XCB_EVENT_MASK_EXPOSURE;
    xcb_create_window(window.connection, XCB_COPY_FROM_PARENT,
            window.win, window.scr->root,
            0, 0,
            window.width, window.height,
            5,
            XCB_WINDOW_CLASS_INPUT_OUTPUT,
            window.scr->root_visual,
            mask,
            values);
    xcb_icccm_set_wm_name(window.connection, window.win, XCB_ATOM_STRING, 8, strlen("xcr"), "xcr");
    xcb_map_window(window.connection, window.win);
    xcb_flush(window.connection);

    depth_iter = xcb_screen_allowed_depths_iterator(window.scr);
    for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
        xcb_visualtype_iterator_t visual_iter;

        visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
        for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
            if (window.scr->root_visual == visual_iter.data->visual_id) {
                window.visual_type = visual_iter.data;
                goto visual_found;
            }
        }
    }
visual_found: ;

    {
        window.surface = cairo_xcb_surface_create (window.connection,
                window.win, window.visual_type, window.width, window.height);
        window.cr = cairo_create (window.surface);

        //cairo_select_font_face (window.cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        //cairo_set_font_size (window.cr, 32.0);
        cairo_set_source_rgb (window.cr, 0.0, 0.0, 0.0);
        cairo_translate(window.cr, window.width / 2, window.width / 2);
        cairo_scale(window.cr, 1, -1);
        //cairo_move_to (window.cr, 10.0, 50.0);
        //cairo_show_text (window.cr, "Hello, world");

        //cairo_surface_flush(window.surface);
        //xcb_flush(window.connection);
    }
    return 0;
}

int destroywindow() {
    cairo_destroy (window.cr);
    cairo_surface_destroy (window.surface);
    xcb_disconnect(window.connection);
    return 0;
}

int gettime(int *hour, int *min, int *sec) {
    time_t t;
    struct tm *tm;
    time(&t);
    tm = localtime(&t);
    *hour = tm->tm_hour;
    *min = tm->tm_min;
    *sec = tm->tm_sec;
    return 0;
}

void drawclock(int x) {
    int hour, min, sec;
    double radius, centradius;
    int i, j;

    (void)x;
    signal(SIGALRM, drawclock);
    //hour = 0; min = 30; sec = 30;
    gettime(&hour, &min, &sec);
    hour %= 12;
    //printf("%02d:%02d:%02d\n", hour, min, sec);
    radius = (double)window.width / 2.0;
    radius -= 10.0;
    centradius = radius / 100.0;

    // Erase
    cairo_set_source_rgb(window.cr, 1.0, 1.0, 1.0);
    cairo_paint(window.cr);
    cairo_set_source_rgb(window.cr, 0.0, 0.0, 0.0);

    // Ticks
    for (i = 0; i < 12; i++){
        cairo_set_line_width(window.cr, 1);
        for (j = 0; j < 4; j++){
            cairo_rotate(window.cr, rad_deg(6));
            cairo_move_to(window.cr, radius, 0);
            cairo_rel_line_to(window.cr, (double)radius / 20.0, 0);
            cairo_stroke(window.cr);
        }
        cairo_set_line_width(window.cr, 3);
        cairo_rotate(window.cr, rad_deg(6));
        cairo_move_to(window.cr, radius, 0);
        cairo_rel_line_to(window.cr, (double)radius / 20.0, 0);
        cairo_stroke(window.cr);
    }

    // Hour hand
    cairo_save(window.cr);
        cairo_rotate(window.cr, rad_deg(90.0 - (60.0 * (double)hour + (double)min)/2));
        cairo_new_path(window.cr);
        cairo_move_to(window.cr, 0, 2);
        cairo_curve_to(window.cr, 15.0 * centradius, 3.0 * centradius,
                                  33.0 * centradius, 0,
                                  50.0 * centradius, 3.0 * centradius);
        cairo_curve_to(window.cr, 55.0 * centradius, 15.0 * centradius,
                                  60.0 * centradius, 0,
                                  76.0 * centradius, 0);
        cairo_curve_to(window.cr, 60.0 * centradius, 0,
                                  55.0 * centradius, -15.0 * centradius,
                                  50.0 * centradius, -3.0 * centradius);
        cairo_curve_to(window.cr, 33.0 * centradius, 0,
                                  15.0 * centradius, -3.0 * centradius,
                                  0, -2.0 * centradius);
        cairo_close_path(window.cr);
        cairo_set_source_rgb (window.cr, 0.0, 0.0, 0.677);
        cairo_fill(window.cr);
    cairo_restore(window.cr);

    // Minute hand
    cairo_save(window.cr);
        cairo_rotate(window.cr, rad_deg(90.0 - 6.0 * (double)min));
        cairo_new_path(window.cr);
        cairo_move_to(window.cr, 0, 2);
        cairo_curve_to(window.cr, 15.0 * centradius, 3.0 * centradius,
                                  33.0 * centradius, 0,
                                  50.0 * centradius, centradius);
        cairo_curve_to(window.cr, 65.0 * centradius, 3.0 * centradius,
                                  83.0 * centradius, 0,
                                  97.0 * centradius, 0);
        cairo_curve_to(window.cr, 83.0 * centradius, 0,
                                  65.0 * centradius, -3.0 * centradius,
                                  50.0 * centradius, -1.0 * centradius);
        cairo_curve_to(window.cr, 33.0 * centradius, 0,
                                  15.0 * centradius, -3.0 * centradius,
                                  0, -2.0 * centradius);
        cairo_close_path(window.cr);
        cairo_set_source_rgb (window.cr, 0.635, 0.0, 0.0);
        cairo_fill(window.cr);
    cairo_restore(window.cr);

    cairo_surface_flush(window.surface);
    xcb_flush(window.connection);

    //printf("alarm in %d\n", 60 - sec);
    alarm(60 - sec);
}

int main(int argc, char **argv)
{
    xcb_generic_event_t *e;
    window.width = window.height = 200;
    signal(SIGALRM, drawclock);

    makewindow();
    while (e = xcb_wait_for_event(window.connection)){
        switch(e->response_type & ~0x80){
        case XCB_EXPOSE:
            drawclock(0);
        }
        free(e);
        //sleep(1);
    }
    destroywindow();

    return 0;
}

xclock视窗


您参加聚会迟到了,但这是一个不错的答案。+1
维克多·斯塔夫萨

谢谢。这是一个有趣的问题。我必须学习一堆xcb才能做到这一点。我写了《Hello World》窗口作为迈向此的垫脚石。
luser droog

1

点击运行。由于时钟是单个表情符号,因此只能以30分钟为增量显示。

function updateTick(){let e=new Date,t=e.getSeconds()+60*e.getMinutes()+e.getHours()%12*60*60,n=parseInt(t/3600*2)+1;document.documentElement.style.setProperty("--tick",n)}let d=new Date;setTimeout(()=>{setInterval(updateTick,18e5)},1e3*(d.getMinutes()+d.getSeconds())%30),updateTick();
@counter-style item{system:cyclic;symbols:"🕛" "🕧" "🕐" "🕜" "🕑" "🕝" "🕒" "🕞" "🕓" "🕟" "🕔" "🕠" "🕕" "🕡" "🕖" "🕢" "🕗" "🕣" "🕘" "🕤" "🕙" "🕥" "🕚" "🕦"}span.tik-terk-clerk::before{content:counters(item, "", item);counter-reset:item calc(var(--tick,1))}span.tik-terk-clerk::before{font-size:72pt}
<span class="tik-terk-clerk"></span>


0

人们正在学习编程,因此创建模拟时钟具有某种吸引力。事实上,我今年教了一个JavaScript课,当我们使用p5.js实现模拟时钟时,我的学生很开心。

使用p5.js制作的模拟时钟

有关模拟时钟的源代码,请访问https://github.com/mveteanu/JSCourse。


1
欢迎来到PPCG!您不仅应该在代码中发布链接,还应在答案中包含代码。
Steadybox

1
您好,欢迎光临本站。这看起来像是正确的答案,但是我们通常更喜欢将代码放在答案中而不是链接中。
小麦巫师
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.