question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Trident] Flicker/Jump of interpolated property value

See original GitHub issue

Version of Radiance (current development is 3.5-SNAPSHOT)

Only trident is used

Sub-project (Neon, Trident, Substance, Flamingo, …)

Trident 3.0.0 https://mvnrepository.com/artifact/org.pushing-pixels/radiance-trident/3.0.0

Version of Java (current minimum is 9)

adoptjdk jdk-11.0.2+9

Version of OS

Betriebsystemname Microsoft Windows 10 Enterprise Version 10.0.18363 Build 18363

The issue you’re experiencing (expected vs actual, screenshot, stack trace etc)

My timeline creates a jump/flicker in the interpolated property that I cannot explain. Still image

SSCCE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JPanel;

import org.pushingpixels.trident.api.Timeline;
import org.pushingpixels.trident.api.Timeline.RepeatBehavior;
import org.pushingpixels.trident.api.ease.TimelineEase;
import org.pushingpixels.trident.api.swing.SwingRepaintTimeline;

public class MovingSpheresTest extends JDialog {

	private final double sphereRadius = 3d;

	private final double sphereCount = 12d;

	private final double helixHeight = 100d;

	private final double size = 200d;

	private final double animationSpeed = 0.5d;

	private List<CenteredSphere> spheres;

	private SwingRepaintTimeline repaintTimeline;

	private final JPanel contentPanel = new JPanel() {
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			paintFrame((Graphics2D) g);
		}

		private void paintFrame(Graphics2D g) {
			Graphics2D create = (Graphics2D) g.create();
			try {
				create.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
				create.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
				create.setColor(Color.BLACK);
				for (CenteredSphere centeredSphere : spheres) {
					create.fill(centeredSphere);
				}
			} finally {
				create.dispose();
			}
		}
	};

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		try {
			MovingSpheresTest dialog = new MovingSpheresTest();
			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			dialog.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the dialog.
	 */
	public MovingSpheresTest() {
		setBounds(100, 100, 450, 300);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setLayout(new FlowLayout());
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		installSpheres();
		installRepaintTimeline();
	}

	private void installSpheres() {
		double helixRadius = helixHeight / 2;
		double effectiveWidth = size - (2 * sphereRadius);
		double sphereDistance = effectiveWidth / (sphereCount - 1);
		double sphereCenterX = sphereRadius;
		double sphereCenterY = size / 2d;
		double sphereCenterYInitial = sphereCenterY - helixRadius;

		spheres = new ArrayList<>();
		for (int sphereIndex = 0; sphereIndex < sphereCount; sphereIndex++) {
			CenteredSphere sphere = new CenteredSphere(sphereCenterX, sphereRadius);
			spheres.add(sphere);
			sphereCenterX += sphereDistance;
			Timeline.builder()
					.addPropertyToInterpolate(Timeline.<Double>property("y").on(sphere).from(sphereCenterYInitial)
							.to(sphereCenterY + helixRadius))
					.setEase(new FullSine((float) (sphereIndex * 2 * Math.PI / sphereCount)))
					.setDuration((long) (animationSpeed * 3000d)).playLoop(RepeatBehavior.LOOP);
		}

	}

	private class FullSine implements TimelineEase {

		private float horizontalOffset;

		private FullSine(float horizontalOffset) {
			this.horizontalOffset = horizontalOffset;
		}

		@Override
		public float map(float durationFraction) {
			return ((float) Math.sin(durationFraction * Math.PI * 2f + horizontalOffset) + 1f) / 2f;
		}
	}

	private void installRepaintTimeline() {
		repaintTimeline = SwingRepaintTimeline.repaintBuilder(contentPanel).build();
		repaintTimeline.playLoop(RepeatBehavior.LOOP);
	}

	public class CenteredSphere extends Ellipse2D.Double {

		private double sphereCenterX;
		private double sphereRadius;

		public CenteredSphere(double sphereCenterX, double sphereRadius) {
			this.sphereCenterX = sphereCenterX;
			this.sphereRadius = sphereRadius;
		}

		public void setY(double y) {
			setFrameFromCenter(sphereCenterX, y, sphereCenterX + sphereRadius, y + sphereRadius);
		}
	}
}

Description with sscce also here on stackoverflow

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
kirill-grouchnikovcommented, Sep 30, 2020

Thanks for reporting this. In the future, the best place to file bugs is right here, as I don’t monitor StackOverflow for Radiance questions.

1reaction
kirill-grouchnikovcommented, Sep 30, 2020

This is interesting. It’s because of the underlying assumption that the TimelineEase always maps the [0.0-1.0] interval without “warping” the end points. In this particular case, during each animation loop, the custom FullSine is used to remap that interval based on the sphere offset, but during the loop reset, the “end” points are not mapped.

This is a valid use case. Will address.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Trident 1.1 – interpolating properties - Pushing Pixels
This entry is going to talk about the most basic capability of Trident – interpolating properties of Java objects.
Read more >
get-interpolated-asset-property-values - AWS Documentation
Description. Get interpolated values for an asset property for a specified time interval, during a period of time. If your time series is...
Read more >
Can Stylus interpolate for a property value rather than a ...
I wonder if there is a workaround. Is there a way (in Stylus) for a Mixin (or another construct) to generate different variable...
Read more >
Modelling of rent prices - which interpolation method to use?
I'd like to use this data to create surface of rent prices for the whole country and use this information as a proxy...
Read more >
Interpolating Scattered Data - MATLAB & Simulink - MathWorks
Scattered data consists of a set of points X and corresponding values V ... The Method property represents the interpolation method that performs...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found