Ejemplo n.º 1
0
    def render_nbodysystem(a, tup, ps, vs, paths):
        """
        Args:
            a: param between 0 and 1 -> time
            tup: tuple returned from solution function (t, vels, poss)
            ps: list of graphical points """

        t = np.array(tup[0])
        vels = tup[1]
        poss = tup[2]

        duration = max(t)
        assert duration == stop_time

        # display one out of the discrete calculated positions, the closest one to the time in the sequence
        i_to_display = np.where(t <= a * duration)[0][-1]

        # import ipdb; ipdb.set_trace()  # noqa BREAKPOINT

        for n in range(num_of_bodies):
            # cut the vector down/extend the vector to a 3d vector, since you can't plot more or less than 3d

            # import ipdb; ipdb.set_trace()  # noqa BREAKPOINT
            pos_of_particle_np = math_utils.get_3d_vec_from_nd_vec(
                poss[n][i_to_display])
            pos_of_particle = math_utils.np_to_p3d_Vec3(pos_of_particle_np)
            vel_of_particle_np = math_utils.get_3d_vec_from_nd_vec(
                vels[n][i_to_display])
            vel_of_particle = math_utils.np_to_p3d_Vec3(vel_of_particle_np)

            ps[n].setPos(pos_of_particle)

            # plot the velocity vectors
            vs[n].setTailPoint(pos_of_particle)

            vel_vector_to_plot = pos_of_particle + vel_of_particle

            if np.linalg.norm(vel_of_particle_np) >= 1:
                vel_vector_to_plot = math_utils.np_to_p3d_Vec3(
                    pos_of_particle_np +
                    math_utils.normalize(vel_of_particle_np) * np.log(np.linalg.norm(vel_of_particle_np)))

            vs[n].setTipPoint(vel_vector_to_plot)

            # trace out the paths over time
            paths[n].extendCoords([pos_of_particle_np])

        pass
Ejemplo n.º 2
0
    def update_alignment(self):
        """ """
        pos_for_x = math_utils.p3d_to_np(
            Frame2d.axis_direction_vectors[0]) * Ticks.get_tick_pos_along_axis(
                self.width, self.axes_ticks_numbers[0], 0.0)
        pos_for_y = math_utils.p3d_to_np(
            Frame2d.axis_direction_vectors[1]) * Ticks.get_tick_pos_along_axis(
                self.height, self.axes_ticks_numbers[1], 0.0)

        pos_tmp = math_utils.p3d_to_np(pos_for_y) + math_utils.p3d_to_np(
            pos_for_x)

        for line in self.linesin2dframe.lines:
            x_scale = self.get_p3d_to_frame_unit_length_scaling_factor(0)
            y_scale = self.get_p3d_to_frame_unit_length_scaling_factor(1)

            # print("x_scale, y_scale: ", x_scale, y_scale)
            cond = np.abs(x_scale) > 1e-8 and np.abs(y_scale) > 1e-8
            if cond:
                line.setScale(x_scale, 1., y_scale)
                line.setPos(math_utils.np_to_p3d_Vec3(pos_tmp))
            else:
                print(
                    "scaling by too low is not supported by p3d, do it differently!"
                )
                self.clear_plot()
Ejemplo n.º 3
0
    def set_cursor_position(self, a):
        """ """
        cursor_pos = math_utils.np_to_p3d_Vec3(
            math_utils.p3d_to_np(self.get_v1()) + a *
            (math_utils.p3d_to_np(self.get_v2()) -
             math_utils.p3d_to_np(self.get_v1())))

        self.p_c.setPos(cursor_pos)
Ejemplo n.º 4
0
 def get_a_param(self, c2):
     """
     a is between 0 and 1 and represents a time if multiplied by the duration.
     FIXME: replace getTail/TipPoints with other stuff. """
     t = 1. - (
         np.linalg.norm(
             self.edge_graphics.line.getTailPoint() - math_utils.np_to_p3d_Vec3(c2)) /
         np.linalg.norm(
             self.edge_graphics.line.getTailPoint() - self.edge_graphics.line.getTipPoint()))
     return t
Ejemplo n.º 5
0
    def update_while_moving_function(self, s_a, v1, v_dir, p_c, line):
        # logical, given:
        # for the current sequence:
        # s_a: parameter between 0 and 1 for the time between the sequence's current start and end points
        # s_l: fixed length of what length a sequence should have (choose a reasonable length, corresponding to a time of maybe 10 seconds, after that, start a new (always finite) sequence)
        # s_dur: fixed duration of the sequence
        # EdgeRecorder.time_ind=1 (s), (time corresponding to the length of the hint line at start of recording),
        # v1 (branch point),
        # v_dir (direction of branching),
        # lps_rate (length per second rate of the player/recorder)

        # graphical: p1, p2, p_c, line

        # asked (logical):
        # the length of the line at the covered_time (line always just keeps increasing in size, not separate segments). Time in seconds is extracted from s_a (given)

        self.state.set_s_a(s_a)  # update s_a

        covered_time = s_a * (EdgeRecorder.s_l / EdgePlayer.lps_rate)
        covered_length = EdgeRecorder.s_l * s_a

        len_ind = EdgeRecorder.time_ind * EdgePlayer.lps_rate
        s_a_ind = EdgeRecorder.time_ind * EdgePlayer.lps_rate / EdgeRecorder.s_l

        if s_a <= s_a_ind:
            line.setTipPoint(math_utils.np_to_p3d_Vec3(len_ind * v_dir + v1))
        elif s_a > s_a_ind:
            line.setTipPoint(
                math_utils.np_to_p3d_Vec3(covered_length * v_dir + v1))
        else:
            print("invalid value of s_a: ", s_a)
            exit(1)

        line.setTailPoint(math_utils.np_to_p3d_Vec3(v1))

        # set cursor point:
        cursor_pos = math_utils.np_to_p3d_Vec3(covered_length * v_dir + v1)
        p_c.setPos(cursor_pos)

        # update the label position (which should be pinned to the (self.p_c), which gets set one line above)

        self.recorder_label.setPos(*tuple(cursor_pos))
Ejemplo n.º 6
0
    def render_hints(self):
        """ render various on-hover things:
            - cursors
            - time labels """
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()

            ray_direction, ray_aufpunkt = cameraray.getCameraMouseRay(
                self.cameragear.camera, base.mouseWatcherNode.getMouse())
            r1 = ray_aufpunkt
            e1 = ray_direction


            closestedge = None
            d_min = float('inf')

            # points of shortest edge_length
            c1_min = None
            c2_min = None

            for edge in self.draggablegraph.graph_edges:
                # find closest line (infinite straight)
                r2 = edge.getTailPoint()
                edge_p1 = r2
                edge_p2 = edge.getTipPoint()

                e2 = edge_p2 - edge_p1  # direction vector for edge infinite straight line

                d = np.abs(math_utils.shortestDistanceBetweenTwoStraightInfiniteLines(r1, r2, e1, e2))
                c1, c2 = math_utils.getPointsOfShortestDistanceBetweenTwoStraightInfiniteLines(
                    r1, r2, e1, e2)

                # only count this edge if the vector of shortest edge_length lies in-between the
                # start and end points of the line
                # if d is not None:
                # if d_min is None:
                #     d_min = d
                # if closestedge is None:
                #     closestedge = edge
                if c1_min is None:
                    c1_min = c1
                if c2_min is None:
                    c2_min = c2

                # conditions for closest edge
                # -    d < d_min
                # -    the line segment of shortest edge_length touches the edge's line within the
                #      two node points of the edge:
                #

                if d < d_min and math_utils.isPointBetweenTwoPoints(edge_p1, edge_p2, c1):
                    d_min = d
                    closestedge = edge

                    c1_min = c1
                    c2_min = c2

                    self.shortest_distance_line.setTipPoint(math_utils.np_to_p3d_Vec3(c1))
                    self.shortest_distance_line.setTailPoint(math_utils.np_to_p3d_Vec3(c2))
                    self.shortest_distance_line.show()

                    # -- set the time label
                    # ---- set the position of the label to the position of the mouse cursor, but a bit higher
                    if closestedge is not None:
                        self.time_label.textNodePath.show()
                        self.time_label.setPos(*(ray_aufpunkt + ray_direction * 1.))

                        # figure out the parameter t
                        t = np.linalg.norm(closestedge.getTailPoint() - math_utils.np_to_p3d_Vec3(c2))/np.linalg.norm(closestedge.getTailPoint() - closestedge.getTipPoint())

                        # print("t = np.linalg.norm(closestedge.getTailPoint() - math_utils.np_to_p3d_Vec3(c2))/np.linalg.norm(closestedge.getTailPoint() - closestedge.getTipPoint())")
                        # print(t, "np.linalg.norm(", closestedge.getTailPoint(), " - ", math_utils.np_to_p3d_Vec3(c2), ")/, np.linalg.norm(", closestedge.getTailPoint(), " - ", closestedge.getTipPoint(), ")")

                        self.time_label.setText("t = {0:.2f}".format(t))
                        self.time_label.update()
                        self.time_label.textNodePath.setScale(0.04)

                    else:
                        self.time_label.textNodePath.hide()

            # -- color edges
            if closestedge is not None:
                for edge in self.draggablegraph.graph_edges:
                    # color all
                    edge.setColor(Vec4(1., 1., 1., 1.), 1)
                    if edge is closestedge:
                        edge.setColor(Vec4(1., 0., 0., 1.), 1)
            else:
                # hide the connection line
                self.shortest_distance_line.hide()

                # make all the same color
                for edge in self.draggablegraph.graph_edges:
                    edge.setColor(Vec4(1., 1., 1., 1.), 1)

            self.hoverindicatorpoint.setPos(math_utils.np_to_p3d_Vec3(
                ray_aufpunkt + ray_direction * 1.))

            # -- color point
            # ---- find closest point,
            # within a certain radius (FIXME: automatically calculate that radius based on the
            # sorroundings)

            d_min_point = None
            closestpoint = None
            for point in self.draggablegraph.graph_points:
                d = np.linalg.norm(math_utils.p3d_to_np(point.getPos())
                                   - math_utils.p3d_to_np(ray_aufpunkt))
                if d_min_point is not None:
                    if d < d_min_point:
                        d_min_point = d
                        closestpoint = point
                else:
                    d_min_point = d
                    closestpoint = point

            # ---- color in point
            for point in self.draggablegraph.graph_points:
                point.setColor(Vec4(1., 0., 1., 1.), 1)

                if point is closestpoint:
                    point.setColor(Vec4(1., 0., 0., 1.), 1)
                else:
                    point.setColor(Vec4(1., 1., 1., 1.), 1)
Ejemplo n.º 7
0
    def render_hints(self):
        """ render various on-hover things:
            - cursors
            - time labels """

        get_hover_points_success, ray_direction, ray_aufpunkt, edge_p1, edge_p2, c1, c2 = (
            self.get_hover_points())

        if get_hover_points_success is True:
            if math_utils.isPointBetweenTwoPoints(edge_p1, edge_p2, c1):
                self.shortest_distance_line.setTipPoint(math_utils.np_to_p3d_Vec3(c1))
                self.shortest_distance_line.setTailPoint(math_utils.np_to_p3d_Vec3(c2))
                self.shortest_distance_line.show()

                # -- set the time label
                # ---- set the position of the label to the position of the mouse cursor,
                #      but a bit higher
                self.time_label.textNodePath.show()
                self.time_label.setPos(*(ray_aufpunkt + ray_direction * 1.))

                a = self.get_a_param(c2)
                t = a * self.edge_graphics.get_duration_func()

                self.time_label.setText("t = {0:.2f}, a = {1:.2f}".format(t, a))
                self.time_label.update()
                self.time_label.textNodePath.setScale(0.04)

                # -- color edges

                # on hover, change the color to be
                # darker than otherwise
                primary_color = self.edge_graphics.get_primary_color()

                darkening_factor = 0.5
                new_rgb_v3 = np.array([
                    primary_color[0],
                    primary_color[1],
                    primary_color[2]]) * darkening_factor
                new_color = Vec4(new_rgb_v3[0], new_rgb_v3[1], new_rgb_v3[2], 1.)

                # when hovered-over
                self.edge_graphics.set_primary_color(new_color,
                                                   change_logical_primary_color=False)
            else:
                self.shortest_distance_line.setColor(Vec4(1., 1., 1., 1.), 1)  # when not hovered-over

                self.edge_graphics.set_primary_color(self.edge_graphics.get_primary_color())

                self.shortest_distance_line.hide()
                self.time_label.textNodePath.hide()

            # -- color point
            # ---- find closest point,
            # within a certain radius

            d_min_point = None
            closestpoint = None

            playerline_limiting_positions = [self.edge_graphics.get_inset_v1(),
                                             self.edge_graphics.get_inset_v2()]

            for pos in playerline_limiting_positions:
                d = np.linalg.norm(
                    math_utils.p3d_to_np(pos)
                    - math_utils.p3d_to_np(ray_aufpunkt))

                if d_min_point is not None:
                    if d < d_min_point:
                        d_min_point = d
                        closestpoint = pos
                else:
                    d_min_point = d
                    closestpoint = pos
Ejemplo n.º 8
0
def draw_nbody_system(self):
    shade_of_gray = 0.1
    base.setBackgroundColor(shade_of_gray, shade_of_gray, shade_of_gray)

    ob = OrbiterOrtho(base.cam, r_init=3.)
    # ob.set_view_to_xy_plane()
    # ob.set_view_to_xz_plane()

    cs = CoordinateSystem(ob)

    from plot_utils.nbodysystem.calc import get_pos_as_func_of_time

    animation_length_factor = 10.
    stop_time = 5. * animation_length_factor
    num_points = int(1000 * math.floor(animation_length_factor))

    # make all bodies white
    nbodies_color = (1., 1., 1., 1.)

    d = 3
    # two bodies: two points
    num_of_bodies = 5

    def get_radius_from_mass_3d_sphere(mass):
        """ assume incompressibility
        Args:
            mass: a positive number
        Returns: radius """
        rho = 1.
        return (3. * mass / (4. * rho * np.pi))**(1./3.)

    import plot_utils.colors.colors as colors

    ps = []  # graphics: points
    vs = []  # velocity vectors
    paths = []  # paths (tracing out movement)

    vis = []
    xis = []
    ms = []
    ncs = []
    cols = []

    for n in range(num_of_bodies):
        vi = np.array([0.2 * np.random.rand(),
                       0.2 * np.random.rand(),
                       0.2 * np.random.rand()]) * (-1.)**math.floor(np.random.rand()*10) * 0.4  # consistent with d=3
        xi = np.array([np.random.rand(),
                       np.random.rand(),
                       np.random.rand()]) * (-1.)**math.floor(np.random.rand()*10) * 0.65
        vis.append(vi)
        xis.append(xi)

        # resolved error: nan's in result when mi and nc are n-dependent ...
        mi = (1. + n) * 5
        ms.append(mi)

        nc = (-1.)**math.floor(np.random.rand()*10)
        ncs.append(nc)

        color = colors.get_next_mpl_color()
        cols.append(color)

        p = Point3d(scale=get_radius_from_mass_3d_sphere(mi))
        p.setColor(color)
        p.setPos(math_utils.np_to_p3d_Vec3(xi))
        ps.append(p)

        v = Vector()
        v.setColor(color)
        vs.append(v)

        paths.append(primitives.SegmentedLinePrimitive(color=Vec4(*color)))

    vis = [vi * 0.1 for vi in vis]

    def render_nbodysystem(a, tup, ps, vs, paths):
        """
        Args:
            a: param between 0 and 1 -> time
            tup: tuple returned from solution function (t, vels, poss)
            ps: list of graphical points """

        t = np.array(tup[0])
        vels = tup[1]
        poss = tup[2]

        duration = max(t)
        assert duration == stop_time

        # display one out of the discrete calculated positions, the closest one to the time in the sequence
        i_to_display = np.where(t <= a * duration)[0][-1]

        # import ipdb; ipdb.set_trace()  # noqa BREAKPOINT

        for n in range(num_of_bodies):
            # cut the vector down/extend the vector to a 3d vector, since you can't plot more or less than 3d

            # import ipdb; ipdb.set_trace()  # noqa BREAKPOINT
            pos_of_particle_np = math_utils.get_3d_vec_from_nd_vec(
                poss[n][i_to_display])
            pos_of_particle = math_utils.np_to_p3d_Vec3(pos_of_particle_np)
            vel_of_particle_np = math_utils.get_3d_vec_from_nd_vec(
                vels[n][i_to_display])
            vel_of_particle = math_utils.np_to_p3d_Vec3(vel_of_particle_np)

            ps[n].setPos(pos_of_particle)

            # plot the velocity vectors
            vs[n].setTailPoint(pos_of_particle)

            vel_vector_to_plot = pos_of_particle + vel_of_particle

            if np.linalg.norm(vel_of_particle_np) >= 1:
                vel_vector_to_plot = math_utils.np_to_p3d_Vec3(
                    pos_of_particle_np +
                    math_utils.normalize(vel_of_particle_np) * np.log(np.linalg.norm(vel_of_particle_np)))

            vs[n].setTipPoint(vel_vector_to_plot)

            # trace out the paths over time
            paths[n].extendCoords([pos_of_particle_np])

        pass

    myseq = Sequence(duration=stop_time,
                     extraArgs=[
                         # the solution vector including the times
                         get_pos_as_func_of_time(
                             ms, ncs,
                             vis, xis,
                             stoptime=stop_time, numpoints=num_points,
                             d=d, num_of_bodies=num_of_bodies),
                         ps,
                         vs,
                         paths
                     ],
                     update_function=render_nbodysystem)

    myseq.start()
Ejemplo n.º 9
0
    def update(self):
        """ resets the positions """

        orbit_center = math_utils.np_to_p3d_Vec3(
            self.camera_gear.get_orbit_center())

        if not self.l1o:
            self.l1o = Line1dSolid(thickness=self.crosshair_outer_thickness,
                                   color=self.crosshair_outer_color)
            self.l1o.reparentTo(self)
            self.l1o.set_render_above_all(True)

        self.l1o.setTailPoint(orbit_center -
                              Vec3(self.crosshair_outer_lines_length /
                                   2., 0., 0.))
        self.l1o.setTipPoint(orbit_center +
                             Vec3(self.crosshair_outer_lines_length /
                                  2., 0., 0.))

        if not self.l2o:
            self.l2o = Line1dSolid(thickness=self.crosshair_outer_thickness,
                                   color=self.crosshair_outer_color)
            self.l2o.reparentTo(self)
            self.l2o.set_render_above_all(True)

        self.l2o.setTailPoint(orbit_center -
                              Vec3(0., self.crosshair_outer_lines_length /
                                   2., 0.))
        self.l2o.setTipPoint(orbit_center +
                             Vec3(0., self.crosshair_outer_lines_length /
                                  2., 0.))

        if not self.l3o:
            self.l3o = Line1dSolid(thickness=self.crosshair_outer_thickness,
                                   color=self.crosshair_outer_color)
            self.l3o.reparentTo(self)
            self.l3o.set_render_above_all(True)

        self.l3o.setTailPoint(orbit_center -
                              Vec3(0., 0., self.crosshair_outer_lines_length /
                                   2.))
        self.l3o.setTipPoint(orbit_center +
                             Vec3(0., 0., self.crosshair_outer_lines_length /
                                  2.))

        if not self.l1i:
            self.l1i = Line1dSolid(thickness=self.crosshair_inner_thickness,
                                   color=self.crosshair_inner_color)
            self.l1i.set_render_above_all(True)
            self.l1i.reparentTo(self)

        self.l1i.setTailPoint(orbit_center -
                              Vec3(self.crosshair_inner_lines_length /
                                   2., 0., 0.))
        self.l1i.setTipPoint(orbit_center +
                             Vec3(self.crosshair_inner_lines_length /
                                  2., 0., 0.))

        if not self.l2i:
            self.l2i = Line1dSolid(thickness=self.crosshair_inner_thickness,
                                   color=self.crosshair_inner_color)
            self.l2i.set_render_above_all(True)
            self.l2i.reparentTo(self)

        self.l2i.setTailPoint(orbit_center -
                              Vec3(0., self.crosshair_inner_lines_length /
                                   2., 0.))
        self.l2i.setTipPoint(orbit_center +
                             Vec3(0., self.crosshair_inner_lines_length /
                                  2., 0.))

        if not self.l3i:
            self.l3i = Line1dSolid(thickness=self.crosshair_inner_thickness,
                                   color=self.crosshair_inner_color)
            self.l3i.set_render_above_all(True)
            self.l3i.reparentTo(self)

        self.l3i.setTailPoint(orbit_center -
                              Vec3(0., 0., self.crosshair_inner_lines_length /
                                   2.))
        self.l3i.setTipPoint(orbit_center +
                             Vec3(0., 0., self.crosshair_inner_lines_length /
                                  2.))