示例#1
0
def linear_intersection(line_1, line_2):
    # first establish if lines are given as absolute lengths or origins and angles
    l1_xy = None
    l2_xy = None
    try:
        if not all(iterable(p) for p in line_1 + line_2):
            # allow for rotation and clockwise arguments to be passed
            l1_xy = (line_1[0], point_pos(line_1[0], 9999999, *line_1[1:]))
            l2_xy = (line_2[0], point_pos(line_2[0], 9999999, *line_2[1:]))
    except AttributeError:
        raise ValueError(
            "Expected each line to be either 2 x,y pairs or and x,y pair and an radial description."
        )
    d_x = (l1_xy[0][0] - l1_xy[1][0], l2_xy[0][0] - l2_xy[1][0])
    d_y = (l1_xy[0][1] - l1_xy[1][1], l2_xy[0][1] - l2_xy[1][1])

    def determinant(a, b):
        return a[0] * b[1] - a[1] * b[0]

    div = determinant(d_x, d_y)

    if not div:
        raise Exception('Supplied lines do not intersect.')
    d = (determinant(*l1_xy[0:2]), determinant(*l2_xy[0:2]))
    return (determinant(d, d_x) / div, determinant(d, d_y) / div)
示例#2
0
    def collect_export_data(self, multi_file=True, join_tables=[]):
        uid = P.unique_identifier
        participant_ids = self.__master.query(
            "SELECT `id`, `{0}` FROM `participants`".format(uid))

        colnames = []
        sub = {P.unique_identifier: 'participant'}

        # if P.default_participant_fields(_sf) is defined use that, but otherwise use
        # P.exclude_data_cols since that's the better way of doing things
        fields = P.default_participant_fields if multi_file else P.default_participant_fields_sf
        if len(fields) > 0:
            for field in fields:
                if iterable(field):
                    sub[field[0]] = field[1]
                    colnames.append(field[0])
                else:
                    colnames.append(field)
        else:
            for colname in self.__master.table_schemas['participants'].keys():
                if colname not in ['id'] + P.exclude_data_cols:
                    colnames.append(colname)
        for colname in P.append_info_cols:
            if colname not in self.__master.table_schemas['session_info'].keys(
            ):
                err = "Column '{0}' does not exist in the session_info table."
                raise RuntimeError(err.format(colname))
            colnames.append(colname)
        for t in [P.primary_table] + join_tables:
            for colname in self.__master.table_schemas[t].keys():
                if colname not in ['id', P.id_field_name
                                   ] + P.exclude_data_cols:
                    colnames.append(colname)
        column_names = TAB.join(colnames)
        for colname in sub.keys():
            column_names = column_names.replace(colname, sub[colname])

        data = []
        for p in participant_ids:
            primary_t = P.primary_table
            selected_cols = ",".join(["`" + col + "`" for col in colnames])
            q = "SELECT " + selected_cols + " FROM participants "
            if len(P.append_info_cols
                   ) and 'session_info' in self.__master.table_schemas:
                info_cols = ",".join(['participant_id'] + P.append_info_cols)
                q += "JOIN (SELECT " + info_cols + " FROM session_info) AS info "
                q += "ON participants.id = info.participant_id "
            for t in [primary_t] + join_tables:
                q += "JOIN {0} ON participants.id = {0}.participant_id ".format(
                    t)
            q += " WHERE participants.id = ?"
            p_data = []
            for trial in self.__master.query(q, q_vars=tuple([p[0]])):
                row_str = TAB.join(utf8(col) for col in trial)
                p_data.append(row_str)
            data.append([p[0], p_data])

        return [column_names, data]
示例#3
0
    def remove_boundaries(self, labels):
        """Removes one or more boundaries from the boundary set.

		Args:
			labels (:obj:`List`): A list containing the labels of the boundaries to remove.
		
		Raises:
			KeyError: If any label does not correspond to a boundary within the set.
		
		"""
        if not iterable(labels): labels = [labels]
        for label in labels:
            self.__verify_label(label)
            self.boundaries.pop(label, None)
示例#4
0
    def which_boundary(self, p, labels=None, ignore=[]):
        """Determines which boundary (if any) a given point is within.

		Unlike :meth:`within_boundary`, which checks whether a point is within a
		`specific` boundary, this method returns the name of the boundary (if any) a
		given point is within (e.g. 'left_button'). If the point falls within multiple
		boundaries, the label of the boundary that was added most recently will be
		returned.

		By default, the point will be tested against all boundaries in the set.
		To check only a subset of the boundaries, you can specify the names of the
		boundaries to check using the ``labels`` argument. Conversely, you can exclude
		specific boundaries from the search using the ``ignore`` argument.

		Args:
			p (:obj:`Tuple` or :obj:`List`): The (x, y) coordinates of the point to test
				against the set's boundaries.
			labels (:obj:`List`, optional): A list containing the labels of the
				boundaries to inspect. Defaults to inspecting all boundaries.
			ignore (:obj:`List`, optional): A list containing the labels of any
				boundaries to ignore. Defaults to an empty list (no ignored boundaries).
		
		Returns:
			:obj:`str` or None: The label of the boundary that the point is within, or
			``None`` if the point does not fall within any boundary.
		
		Raises:
			KeyError: If any given labels do not correspond to a boundary within the set.
			ValueError: If the given point is not a valid set of (x, y) coordinates.
		
		"""
        if not labels:
            labels = list(self.boundaries.keys())
        if not iterable(ignore):
            ignore = [ignore]

        boundary = None
        for l in self.boundaries.keys():
            if l in ignore or not l in labels:
                continue
            self.__verify_label(l)
            if self.boundaries[l].within(p):
                boundary = l

        return boundary
示例#5
0
    def clear_boundaries(self, preserve=[]):
        """Removes all boundaries from the boundary set.

		Args:
			preserve (:obj:`List`, optional): A list containing the labels of any
				boundaries that should remain in the set after the clear.

		Raises:
			KeyError: If any label does not correspond to a boundary within the set.
		
		"""
        if not iterable(preserve):
            preserve = [preserve]
        preserved = OrderedDict()
        for label in preserve:
            self.__verify_label(label)
        for label in self.labels:
            if label in preserve:
                preserved[label] = self.boundaries[label]
        self.boundaries = preserved