Просмотр полной версии : C#
[CCCP] Monster
02.10.2010, 14:06
C# (произносится си-шарп) — объектно-ориентированный язык программирования. Разработан в 1998—2001 годах группой инженеров под руководством Андерса Хейлсберга в компании Microsoft как основной язык разработки приложений для платформы Microsoft .NET. Компилятор с C# входит в стандартную установку самой .NET, поэтому программы на нём можно создавать и компилировать даже без инструментальных средств, вроде Visual Studio.
C# относится к семье языков с C-подобным синтаксисом, из них его синтаксис наиболее близок к C++ и Java. Язык имеет статическую типизацию, поддерживает полиморфизм, перегрузку операторов (в том числе операторов явного и неявного приведения типа), делегаты, атрибуты, события, свойства, обобщённые типы и методы, итераторы, анонимные функции с поддержкой замыканий, LINQ, исключения, комментарии в формате XML.
Переняв многое от своих предшественников — языков C++, Java, Delphi, Модула и Smalltalk — С#, опираясь на практику их использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем: так, C# не поддерживает множественное наследование классов (в отличие от C++).
Особенности языка:
C# разрабатывался как язык программирования прикладного уровня для CLR и, как таковой, зависит, прежде всего, от возможностей самой CLR. Это касается, прежде всего, системы типов C#, которая отражает BCL. Присутствие или отсутствие тех или иных выразительных особенностей языка диктуется тем, может ли конкретная языковая особенность быть транслирована в соответствующие конструкции CLR. Так, с развитием CLR от версии 1.1 к 2.0 значительно обогатился и сам C#; подобного взаимодействия следует ожидать и в дальнейшем. (Однако эта закономерность была нарушена с выходом C# 3.0, представляющим собой расширения языка, не опирающиеся на расширения платформы .NET.) CLR предоставляет C#, как и всем другим .NET-ориентированным языкам, многие возможности, которых лишены «классические» языки программирования. Например, сборка мусора не реализована в самом C#, а производится CLR для программ, написанных на C# точно так же, как это делается для программ на VB.NET, J# и др.
По памяти отмечу, что наш усатый на первом-втором курсе из литературы особо напирал на Гради Буча, Эндрю Троелсена и Г. Шильда. Если кому нужно, второго могу и залить.
Просветите меня, как обрабатывать xml?
Есть у меня такой xml:
<?xml version="1.0" encoding="UTF-8"?>
<Model xmlns="http://www.esi-group.com/ns/VAOne" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.esi-group.com/ns/VAOne http://www.esi-us-rd.com/xml/schemas/VAOne/rev2/VAOne.xsd" name="Cube" note="">
<Version>1.1.0</Version>
<GlobalFrequencyDomain>
<FrequencyDomain start_freq="16" end_freq="8000" domain_type="2"/>
</GlobalFrequencyDomain>
<SolveOptions override_wavefields="false" beam_flexure_x="true" beam_flexure_y="true" beam_extension="true" beam_torsion="true" plate_extension="true" plate_flexure="true" plate_shear="true" average_radeff="false" symmetric_SEA_matrix="true" acoustic_pressure="true" compute_variance="false" solution_type="eHybrid" hybrid_quick="false" hybrid_quicknum="6" vsea_steps="20" override_eigen_frequencies="false" eigenlocallow="-5" eigenlocalhi="17826" eigengloballow="-5" eigenglobalhi="10695.6" local_mass="true" local_modes="false" modes="true" override_local_eigen_frequencies="false" override_global_eigen_frequencies="false" superelement_analysis="false" senqset="500" recover_fe_rad_eff="true" recover_nodal_eu="true" overrideGlobalAcousticEigenFreqs="false" getLocalAcousticModesInBand="true" minGlobalAcousticEigenValueFreq="-5" maxGlobalAcousticEigenValueFreq="10695.6" getAcousticModes="true" recoverBEM="true" overrideFEAcousticJunctionEps="false" feacousticJunctionEps="1e-006" recoverFEAcoustic="true">
<BulkDataCards/>
<ControlCards/>
</SolveOptions>
<Nodes>
<Node node_id="1" x="0" y="0" z="0"/>
<Node node_id="2" x="0" y="1" z="0"/>
<Node node_id="3" x="1" y="0" z="0"/>
<Node node_id="4" x="1" y="1" z="0"/>
<Node node_id="5" x="0" y="0" z="1"/>
<Node node_id="6" x="0" y="1" z="1"/>
<Node node_id="7" x="1" y="0" z="1"/>
<Node node_id="8" x="1" y="1" z="1"/>
<Node node_id="9" x="0.2" y="0.2" z="1"/>
<Node node_id="10" x="0.2" y="0.8" z="1"/>
<Node node_id="11" x="0.8" y="0.2" z="1"/>
...
...
Пытаюсь загрузить его в свою программу:
public class AutoSeaModel {
public XmlDocument xDoc = new XmlDocument();
public XmlElement xRoot;
String fileName;
public SortedDictionary<int, Node> nodes = new SortedDictionary<int, Node>();
public SortedDictionary<int, Face> faces = new SortedDictionary<int, Face>();
public SortedDictionary<String, Shell> shells = new SortedDictionary<String, Shell>();
public SortedDictionary<String, Cavity> cavities = new SortedDictionary<String, Cavity>();
public AutoSeaModel(String fileName)
{
this.fileName = fileName;
xDoc.Load(fileName);
xRoot = xDoc.DocumentElement;
XmlNodeList xNodes = xDoc.SelectNodes("/Model/Nodes/Node");
foreach(XmlElement xNode in xNodes) {
Node newNode = new Node(this, xNode);
nodes.Add(newNode.node_id, newNode);
}
XmlNodeList xFaces = xDoc.SelectNodes("/Model/Faces/FlatPlateFace");
foreach (XmlElement xFace in xFaces)
{
...
...
Вопрос мой в том, как использовать XPath?
По моим соображениям строка
XmlNodeList xNodes = xDoc.SelectNodes("/Model/Nodes/Node");
Должна вернуть набор XmlElement'ов, каждый из которых должен соответствовать строке типа
<Node node_id="1" x="0" y="0" z="0"/>
Но метод SelectNodes все время возвращает мне пустой список. Что я делаю не так?
Upd:
Все дело оказалось в пространстве имен XML. Помогла эта статья:
http://codehelper.ru/questions/102/new/xpath-%D1%81%D0%B5%D0%BB%D0%B5%D0%BA%D1%82%D0%BE%D1%80-%D0%BF%D0%BE-xml-c-namespace
Bad Gateway
22.01.2011, 20:08
Это вроде просто, но я не знаю как. Подскажите, если не трудно.
http://s1.ipicture.ru/uploads/20110122/AI21n9U6.jpg
Bad Gateway, еще нужна помощь?
надо задать размер матрицы nxm, и после чего загнать в матрицу числа. Как создать матрицу я понимаю. Но как лучше заполнить матрицу, мне не совсем ясно. Вызывать каждый раз диалоговое окно и просить ввести в поле i,j элемент не вариант. Загонять из файла тоже. Возможно ли создать как-нибудь сразу таблицу, которую можно будет заполнить, после чего передать данные в массив?
Таблицу можно создать с помощью контрола DataGridView
Реквестирую сюда мини срачик о том что лучше c# или Java. Заодно и мне объясните.
Жила-была Java. Microsoft обиделся, что яву придумали не они и решил сделать свою, с блек джеком и девками.
В принципе языки очень похожи даже синтаксисом (хоть я и не вникал в C# так как в яву, но это и так заметно).
Жила-была Java. Microsoft обиделся, что яву придумали не они и решил сделать свою, с блек джеком и девками.
Получается что шарп лучше т.к. там есть блек джек и девки))
Ява лучше уже потому, что она кроссплатформанная.
CMETAHA, основная моя мысль в том, что изучать можно любой из этих языков, а потом легко мигрировать на другой (сделать замену "import" <-> "using" :D ).
Единственное, чего мне хотелось бы в Java из C#, это перегрузка стандартных операторов, сеттеры и геттеры:
Перегрузка операторов:
// C#
public class MyClass {
public MyClass operator+(MyClass firstValue, MyClass secondValue) {
return ...;
}
}
Тогда можно так:
newMyObj = myObj1 + myObj2;
вместо такого
// Java
public class MyClass {
public static MyClass add(MyClass firstValue, MyClass secondValue) {
return ...;
}
}
newMyObj = MyClass.add(myObj1, myObj2));
сеттеры и геттеры:
//C#:
public class SomeClass {
private MyClass fMyValue;
public MyClass myValue {
get {
return fMyValue;
}
set {
// Здесь можно выкинуть исключение, если value не подходит
fMyValue = value;
}
}
}
А далее инкапсулированное поле используется как открытая переменная:
SomeClass someObject;
...
someObject.myValue = ...;
... = someObject.myValue;
Java:
//Java
public class SomeClass {
private MyClass myValue;
public MyClass getMyValue {
return myValue;
}
public void setMyValue(MyClass value) {
// Здесь можно выкинуть исключение, если value не подходит
this.myValue = value;
}
}
А далее нужно использовать методы:
SomeClass someObject;
...
someObject.setMyValue(...);
... = someObject.getMyValue();
Смысл шарпа вообще не ясен. Заставляет таскать с собой громоздкий фреймворк, при этом не предоставляя основой и главной фичи java и jre - кроссплатформенности, и отсутствия необходимости в перекомпиляции под платформу. А при этом к тому же еще и производительность страдает. Java лучше.
По истории срачей между M$ и Sun можно тут (http://ru.wikipedia.org/wiki/Java#Java_.D0.B8_Microsoft) почитать про J# и C#. Про блэкджек уже сказали выше.
А как же mono?
Там все равно полноценной поддержки майкрософтовских технологий нет, компанию его разрабатывающую вообще продали недавно и под никсами он не нужен. Те кто C# любят пусть кодят под винду.
Console.WriteLine("\nОтвет: " + y);
Console.WriteLine("Округлить до n чисел после запятой, введите n...");
buf = Console.ReadLine();
byte n = Convert.ToByte(buf);
Console.WriteLine("\nОтвет: " + Math.Round(y, n));
}
}
}
Как сделать так, чтобы строки "Округлить до n чисел после запятой, введите n..." и само n исчезли при при его вводе, и остались только ответы.
OneHalf, оно вроде. Спасибо.
А не подскажите ещё как развилку сделать там же, наподобие "Округлить до n чисел после запятой? Если да - нажмите то-то, если нет то-то", при ответе нет - выходит.
OverDoser
01.03.2011, 18:46
OneHalf, оно вроде. Спасибо.
А не подскажите ещё как развилку сделать там же, наподобие "Округлить до n чисел после запятой? Если да - нажмите то-то, если нет то-то", при ответе нет - выходит.
Можно использовать
/*инициализация caseSwitch*/
switch (caseSwitch)
{
case У:/*что делать при вводе чего-то(У)*/
break;
case Х:
/*что делать при вводе чего то (X)*/
break;
default:
/*делаем,если введено что-то другое*/
}
Надеюсь знаем такое?(расписал если вдруг не знаете).
А в вашем случае делаем стринг.
К примеру если вводите N-округляем(
case N:
/нужные действия/
break;
)если вводите M-не округляем(
case M:
/*нужные действия*/
break;)
Ну и если другое,то(
default:
/*нужные действия*/
break;}//закрываем начало switch(зададите сами))
разбираюсь с dataGridView.
с помощью dataGridView1.Columns.Add("MyColumnName", "MyColumnHeaderText");
можно добавить столбец.
Но я не понимаю двух вещей.
1) зачем нужен первый параметр. Нигде в таблице его не обнаружил
2) Можно ли как-нибудь отцентровать текст в заголовке колонки?
Mad-Dan, по columnName можно обращаться к столбцам: dataGridView1.Columns["Name"]
удалите, вышел даббл пост.
возник также вопрос, как в datagridview передать 2 мерный массив.
Я вижу вариант, что бы поэлементно загнать. Но должен быть способ проще.
Подскажите пожалуйста, дан массив вещественных чисел А, нужно сформировать из его отрицательных элементов массив В, а из положительных - С.
SolidlSnake
24.04.2011, 17:35
Arantar, просто через проверку, если число из массива A > 0 то скопируй его в массив C, в противном случае, в массив B.
Я понимаю, как сделать надо, просто я не обладаю пока достаточными знаниями, чтобы реализовать это. И прошу помощи с этим.
SolidlSnake
24.04.2011, 21:38
Arantar,
max = 10; //или ваше значение
int[] A = new int[max], B = new int[max], C = new int[max];
//...
//где-то тут задаются числа для массива A
int x = 0,y = 0;
for (int i = 0, i<10, i++)
{
if (a[i]>=0)
{
c[x]=a[i];
x++;
}
else
{
b[y]=a[i];
y++;
}
Код, конечно ужасен, я сам программирование изучаю не так давно, шарп так и вовсе не знаю, но примерная концепция твоего задания есть.
Дальше пусть всякие профи доделают. :)
ну вообще-то разумней через arraylist создавать новые массивы. Размеров-то их мы не знаем. А ArrayList позволяет изменять размер массива в процессе. Насколько я знаю, с обычными массивами такое не реально.
SolidlSnake
25.04.2011, 14:50
Mad-Dan, да, точно, а то будет утечка памяти. Лишние слоты в массиве останутся.
Mad-Dan, да, точно, а то будет утечка памяти.Утечка памяти в C#? :eek: :lol:
pokibor,
Человек понятия попутал. Утечки нет. А вот нерациональное использование ресурсов есть.
SolidlSnake
26.04.2011, 14:19
pokibor, как жалко, что вы видите только то, что вы хотите. :)
Mad-Dan, спасибо, за разъяснения. :)
По поводу утечки памяти. Можно ли принудительно прибить какую-нибудь переменную?
По поводу утечки памяти. Можно ли принудительно прибить какую-нибудь переменную?А что именно нужно? Если речь идет об удалении какого-то объекта, то можно присвоить NULL и вызвать сборку мусора. GC.Collect, кажется.
pokibor,
Ну вообщем надо отсортировать массив. При этом желательно сохранить первоначальный массив, и при этом сам отсортированный массив дальше не используется, используются только индексы элементов массива.
Обошелся без этого. Просто вспомогательный массив существует только в функции сортировки.
можно ли в DataGridView и в TextBox сделать так, что бы вводились только числа?
spyderDFX
29.05.2011, 15:39
Нужно решить на C# вот такие проблемы:
открыть какое-либо изображение;
показать его на экране (bitmap юзать?);
выделить на нём контрастные участки;
показать изменённое изображение.
Никогда не работал с готовыми изображениями, поэтому хз как всё это делать.
как в datagridview задать точность выводимого числа?
1. Может кто подсказать каким образом я в шарпе могу сменить MAC-адрес сетевой карты, да еще и с рестартом оной? То есть после смены нужно сетевую карту отключить и включить.
Данную проблему я решил очень глупо. Скачал devcon.exe, добавилв сборку программы и перенаправленным вводом\выводом совершаю данные действия. Хотелось бы нормального решения.
2. Как в шарпе сделать запрос на обновление IP-адреса, который выдан DHCP, или сделать что-нибудь аналогичное кнопке "Исправить" в сетевом подключении?
Сколько не искал не могу инфы нарыть, прошу, откликнитесь :)
Эмм... а разве это делается не на winapi? Причем тут шарп то?
В .NET существует обертка над WMI. Существует метод Enable, Disable, Reset. Судя по документации ресет только в висте, но у меня не работает ни один, пишет недопустимый метод. Про ресет что метод не реалзиован ни в одном из классов.
Про обновление аренды от DHCP я нашел только в том же WMI - RenewDHCPLease (хотя сейчас проверяю подойдет ли "ipconfig /renew" для этих целей).
Хотелось бы красивого решения, а не использование сторонней программы...
Pharaon, а необходимо это сделать конкретно на WMI что ли?
Скажу так, мне просто необходимо это сделать. Не важно что и как, но чтобы код работал на шарпе. Есть винАпи функции? Какие?
Ладно, отключение карты уже не так важно, пусть немного коряво так, но через утилиту от микрософта работает.
Вся проблема в обновлении айпишника, причем не просто в обновлении, а именно аналоге конпки исправить в состоянии сетевого подключения. Любой способ, хотя бы наведите на путь истинный, скока не искал н емогу найти, гугл на меня в обиде)
Th0R(D0)NaR
12.09.2011, 20:20
помогите написать проги
Использовать перечислимый тип для хранения названий дней недели (месяцев, названий организационно-правовых форм предприятий и т.п.) с последующей печатью на экране значений созданного перечислимого типа.
вариант перечислений: Виды печатных изданий (книга, журнал, газета и т.п.)
Разработать структуру, описывающую координаты и другие требуемые параметры квадрата с расчётом его площади.
Разработать консольное приложение, позволяющее одному пользователю загадывать число в заданном диапазоне, а другому отгадывать это число, вводя произвольные числа с последующим указанием того, больше это число загаданного или нет.
Th0R(D0)NaR,
совсем лень думать?
примитивные же проги.
учебный год похоже начался.
Есть задание: нужно определить площадь на выбранном отрезке под заданной кривой методом численного интегрирования.
Программа должна обеспечить ввод с клавиатуры уравнений функций и нахождение значения площади под полученной кривой.
И есть загвоздка, как обеспечить с клавиатуры ввод уравнений функций, программа создается через Windows Forms, т.е. там нужно реализовать эту функцию...
Arantar, нужно реализовать лексический и синтаксический анализаторы, осуществляющие разбор грамматики математических выражений (и саму грамматику под нужную схему подогнать). Грамматика мат. выражений проста, её хоть грамматикой простого предшествования можно представить, а для таких грамматик есть простой и эффективный алгоритм разбора. В общем-то, задача сугубо техническая и требует освоения методов синтаксического анализа (лексический тут элементарен).
Возможно, в C# даже есть соответствующие компоненты, но я этим не занимался и потому не знаю...
Ну а если лень делать, то можно предписать вбивать функцию в префиксной или постфиксной формах. Тут вообще мудрить с разбором не придётся, до того всё просто.
Хотелось бы примерчик небольшой увидеть этого, если не трудно...
Arantar, Вот: Парсер математических выражений (http://habrahabr.ru/blogs/net/50158/), через регексы (http://habrahabr.ru/qa/12188/), много разных примеров (http://www.cyberforum.ru/csharp-beginners/thread181987.html)
Arantar, учите матчасть (http://log-in.ru/books/21391).
Для разбора математических выражений я в своё время использовал следующую грамматику (привожу её в формате моей программы для построения матрицы предшествования, там из названия разделов ясно, где что):
>TERMINAL<
var
const
+
-
*
/
rt
^
log
func
(
)
>NOT_TERMINAL<
ВЫР
ПВЫР
ПР1
ПР1а
ПР2
ПР2а
ПР3
ПР3а
ПР4
ПР4а
ПР5
ПР5а
ПЕРЕМ
КОНСТ
СКОБ
>START<
ВЫР
>RULES<
ВЫР -> ПВЫР
ПВЫР -> ПР1
+ ПР1
- ПР1
ПВЫР + ПР1
ПВЫР - ПР1
ПР1 -> ПР1а
ПР1а -> ПР2
ПР1а * ПР2
ПР1а / ПР2
ПР2 -> ПР2а
ПР2а -> ПР3
ПР2а ^ ПР3
ПР2а rt ПР3
ПР3 -> ПР3а
ПР3а -> ПР4
ПР3а log ПР4
ПР4 -> ПР4а
ПР4а -> ПР5
func ПР5
ПР4а func ПР5
ПР5 -> ПР5а
ПР5а -> ПЕРЕМ
КОНСТ
СКОБ ВЫР )
СКОБ -> (
ПЕРЕМ -> var
КОНСТ -> const
>END<Она является грамматикой простого предшествоания, а нетерминалы ПР<число> разграничивают операторы по приоритетам, чем выше приоритет - тем выше число. То есть легко свои операторы добавить. Все функции задаются терминалом func, ну а какая именно функция - это уже лексический анализ (правда, поскольку тут речь идёт об элементарной математике, то функции могут быть только от одной переменной - т.е. имеются в виду синусы, косинусы и так далее). var и const - терминалы для переменной и константы соответственно. rt и log - для операция корня и логарифма, которые я решил в рамках грамматики реализовать операторами, т.к. там по сути две переменные должны быть.
Что же касается префиксной (http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_% D0%BD%D0%BE%D1%82%D0%B0%D1%86%D0%B8%D1%8F)/постфиксных (http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_% D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D 0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C) записей - то это в Википедию по ссылкам.
Теперь что касается "примерчика". Вообще-то у меня есть программа для построения по грамматике матрицы предшествования и последующей генерации выходного файлы с полным описанием и грамматики, и матрицы. А также программа, генерирующая по этому файлу код на C++ с синтаксическим анализатором. Но Вы едва ли во всём этом разберётесь, так что читайте теорию. Ну или если лень, используйте постфикс/префикс. Там, повторяюсь, всё элементарно. Знак перед/после операндов, никаких скобок. Читай себе символы и определяй, что это. Кстати, и для инфиксной формы (сиречь обычная форма записи, когда оператор стоит между операндов) можно не заморачиваться с грамматикой. Используйте стек, и всё (в грамматике простого предшествования он, собственно, и используется). Я использовал грамматику, дабы была возможность её расширения.
Ну да, или используйте готовую библиотеку, ссылку на которую кинул CMETAHA. :Grin: Но вообще-то, знать основы построения трансляторов не помешает.
OverDoser
04.11.2011, 15:03
Знания в c# далеки от хороших, поэтому задаю вопрос:
Собственно задача у меня такова:найти объект на изображении с помощью образца(второе изображение).
Сейчас я использую примитивный алгоритм(знаю, что есть проще намного-но хочу сделать именно с таким).Идет сравнение каждого пикселя с пикселями на образце(GetPixel).
Далее,для отметки совпадения, создается третье изображения с размерами, как у первого изображения и полностью черного цвета.И в случае совпадения, пиксель на третьем изображении с координатами, как у совпавшего пикселя на первом, красится в белый цвет(SetPixel).
Далее идет обработка третьего изображения, по свойствам образца определяем нужный нам объект и обводим этот объект на первом.Но это здесь не важно.
суть такова, что сравнение объектов идет 5<x<10 минут, и меня это НЕ УСТРАИВАЕТ.
Понятное дело, что операций перебор идет более 100млн пикселей, и наверняка замедляет процесс именно GetPixel.
Вопрос у меня такой:
1)Чем можно заменить GetPixel для ускорения программы
2)Какое доп условие можно добавить, чтобы снизить во много раз кол-во сравнений.(ну там допустим средний цвет области.Если близко к среднему цвету образца, то сравниваем.Если далек, то оставляем)
Bitmap one = new Bitmap(@label1.Text);
Bitmap two = new Bitmap(@label3.Text);
Bitmap thr = new Bitmap(@label1.Text);
for (int h = 0; h <= thr.Height-1; h++)//Делаем 3 изображение черным
for (int g = 0; g <= thr.Width-1; g++)
thr.SetPixel(g, h, Color.Black);
for (int q = 0; q <= one.Width-two.Width-1; q++)
for (int z = 0; z <= one.Height - two.Height - 1; z++)//Перебираем
//координаты на 1 изображении
{ bool b = true;//Буль для выхода в случае нахождения совпадения
for (int f = 0; (f <= two.Width - 1)&&(b=true); f++)
for (int s = 0; (s <= two.Height - 1)&&(b=true); s++)//Координаты
//образца
{
if (one.GetPixel(q, z) == two.GetPixel(f, s))
{ thr.SetPixel(q, z, Color.White);//Красим в белый
b=false;}
;
}
}
OverDoser, это область искусственного интеллекта - раз. Но об этом пока говорить рано, чувствую.
Далее, сравнивать по цветам пикселей - заведомо не лучшая идея. Большинство алгоритмов сжатия изображения с потерями, т.е. алгоритмов, которые отбрасывают "слабоощутимую" информацию, осуществляют преобразование изображения в цветовую модель YUV (http://ru.wikipedia.org/wiki/YUV). Вообще, если речь идёт об ускорении работы алгоритма со сравнением, то я бы порекомендовал именно изучить алгоритмы сжатия изображения и сравнивать результирующие коэффициенты уже после сжатия. Обратите особое внимание на вейвлеты (http://ru.wikipedia.org/wiki/%D0%92%D0%B5%D0%B9%D0%B2%D0%BB%D0%B5%D1%82%D0%BD%D 0%BE%D0%B5_%D1%81%D0%B6%D0%B0%D1%82%D0%B8%D0%B5) - полагаю, именно результаты вейвлет-преобразования Вам подойдут особенно хорошо, поскольку представляют собой уменьшенные копии рисунка. Соответственно, сравниваем грубую часть вейвлет-разложения, если сходится - то можно сравнивать более тонкие коэффициенты.
Итог: если не хотите связываться с искусственным интеллектом (хотя обращение к нему не альтернатива, а дополнение алгоритма, на самом деле), используйте методы сжатие изображения с потерями и сравнивайте их результат. Такие методы строятся на математических функциях и сколь угодно точно могут представлять исходное изображение, выделяя так или иначе "грубые" коэффициенты и "более точные" - чисто исходя из своего предназначения. Как отмечалось выше, из всех методов сжатия мне кажется лучшим применение вейвлетов в силу построения уменьшенных копий исходного изображения, а не малопонятных матриц коэффициентов.
P.S. Рекомендую книгу "Фракталы и вейвлеты для сжатия изображений в действии", С. Уэлстид. (http://ifolderlinks.ru/knigi/fraktaly-i-veivlety-dlya-szhatiya-izobrazhenii-v-deistvii.html)
OverDoser
04.11.2011, 17:06
pokibor, То есть я правильно вас понял:
Выделяю на 1 изображении область,равную 2 изображению. Произвожу вейвлет преобразование этой области и 2 рисунка. Оцениваю коэффициенты.Если совпадают, то произвожу точное сравнение.И так на всем изображении?
OverDoser, Вы оба рисунка приводите к вейвлет-преобразованию, а затем начинаете искать на соответствующих уровнях коэффициентов первого изображения второе изображение. Т.е. искать вхождение "крупных" копий изображения сначала на "крупных" копиях картинки, потом на более мелких. Естественно, о точном сходстве речи идти не может, тут необходимо выработать определённый критерий похожести. Однако и в Вашем методе о точном сходстве до единого пикселя можно говорить весьма условно.
P.S. Кстати, алгоритмы распознавания образов используют, как правило, нейронные сети.
Если же Вы ищите именно точное сходство, пиксель к пикселю, то придумайте какую-нибудь контрольную сумму по изображению, и всё. Но тогда задача будет совершенно бесполезной и нереалистичной.
OverDoser
04.11.2011, 17:20
pokibor, То, что используются здесь в основном нейронные системы-читал, но для меня пока рано)
С принципом распознавания здесь я понял, спасибо)
Теперь будем разбираться с самим вейвлет-преобразованию)
Не подскажете видеоуроки(ну или любой другой материал), с помощью которых можно с нуля обучиться этому языку программирования.
deriop,
учимся читать FAQ.
OverDoser
06.11.2011, 17:03
Значит, вернусь к задаче.
Таки мне удалось сократить время выполнения операции сравнение пикселей( с 7 минут до 1 с за счет другого подхода +распараллеливания задачи).
Теперь задача моя формулируется по другому:
Имеется два изображения:первое изображение бинарное(те состоит из 0x000000 и oxFFFFFF), на котором изображены различны объекты(они не пересекаются) На нем фон-черное, объекты-белое.
Второе изображение цветное(известно только, что фон белый), на нем изображен какой то объект( и известно, что этот объект изображен на 1 изображении:он может быть повернут под углом или масштабирован,но сама по себе форма остается постоянной).
С помощью каких средств и способов можно реализовать поиск объекта,изображенного на втором рисунке, на первом изображении?
OverDoser, давайте сразу решим, алгоритм какой сложности и работоспособности Вам нужен. Всегда можно перебирать "в тупую", ограничиваясь лишь элементарной оптимизацией вроде подсчёта контрольной суммы и прочего подобного.
И, конечно, есть более сложные, но и куда более эффективные алгоритмы, требующие определённого преобразования данных, использования методов искусственного интеллекта, обучения и прочего.
Конкретно Ваш случай, я думаю, предполагает вектризацию объектов как основу алгоритма. Поворачивать и масштабировать векторные изображения куда проще, нежели растровые (что очевидно). Тем более на одном из изображений фактически контур объекта и изображён.
P.S. А вообще, тут можно с огромным интересом обсудить применение фрактального подхода, т.е. подбор для изображения IFS и сравнения коэффициентов. Но это совершенно отдельная тема.
OverDoser
06.11.2011, 18:02
pokibor, С учетом того, что сам по себе алгоритм имеет довольно большое кол-во условностей, считаю, что для поиска не нужен сильно мудреный способ поиска.(тк первоначальный этап алгоритма-отбор лишних цветов-сводит на нет необходимость в сложных алгоритмов)
Те чтобы сочеталось простота+эффективность+(если это возможно)быстрота
OverDoser, тогда перебирайте все возможные растровые варианты, раз быстрота на третьем месте :Grin:
Дело в том, что вектризация всё равно необходима, на мой взгляд. Масштабирование - ещё куда ни шло, можно, как Вы делали в предыдущем алгоритме, привести одно изображение к масштабу другого, а вот поворот... ну разве что вращать на 360 градусов с достаточно малым шагом и (для каждого!) масштабировать, затем смотреть. Это трудно назвать эффективным и быстрым алгоритмом, тем более учитывая возможные искажения при повороте.
С вектризованным же изображением работать попроще будет. Как минимум, поворачивать/масштабировать надо будет вектора, а не пиксели, что само по себе сильно упрощает дело. Ну и затем можно накрутить массу оптимизационных улучшений. Например, если вектризация идёт до отрезков контура, то можно запоминать последовательность их длин на контуре, и сравнивать сперва именно длины (отсюда сразу с хорошей вероятностью получается масштаб). Но, опять же, всё это будет работать лишь примерно, в определённых пределах, за счёт погрешностей.
OverDoser
06.11.2011, 18:45
pokibor, А возможно ли использование индивидуальных свойств объектов(если они, конечно, есть =) ), которые не меняются при масштабировании?
Мы же можем их перебрать, и если погрешность очень низкая, то очевидно, что это нужный нам объект.
Да, я выше немного сглупил. По вечер голова плохо варит.
OverDoser, если масштабирование полное, а не отдельное по каждой оси, то при таком масштабировании сохраняются углы. Подобие же, как-никак :) Только Вам всё равно придётся вектризовать изображения (предположим, каждый объект - один непрерывный контур, состоящий из отрезков прямых; полагаю, для Вашего случая такое предположение справедливо). Соответственно, последовательность величин углов между соседними сторонами должна быть одинаковой: выстраиваем их в список по определённому направлению, по или против часовой, и начинаем сравнивать углы (только точку старта, вследствие поворота, придётся двигать по всему списку). Если какой-то случай совпадает, то сравнить длины сторон всё равно надо, ибо подобие при равенстве углов гарантируется только в случае выпуклых многоугольников. Но упрощение всё-таки налицо.
А если Вы про свойства в растровом изображении, то я не понимаю, какими они могут быть. Нет, контрольную сумму и для этого случая можно придумать, но это достаточно сложная задача.
Добавлено через 3 минуты
Хотя... для теста можете, скажем, подсчитать две величины: расстояние между самыми отдалёнными пикселями фигуры и её площадь. Первая величина позволит Вам зафиксировать отношение размеров образца к размерам объекта, ну а вторая как раз и будет некой контрольной суммой.
Добавлено через 7 минут
В общем, если Вам нужен простой и эффективный алгоритм, работающий на достаточно разных изображениях, то это вариант как раз подойдёт, пожалуй. Ложных срабатываний должно быть не так много, и для каждого можно уже включить более тонкие варианты. Только не забывайте, что площади образца и масштабированного изображения будут относиться как квадраты их одинаковых (до подобия) отрезков, площадь же.
OverDoser
06.11.2011, 19:47
pokibor, М, не понял.
Так что мне значит нужно считать и находить:
Нахожу самый длинный отрезок, который соединяет противолежащие точки границы.
Нахожу площадь.
Далее смотрю :нахожу коэффициент k=(отрезок на данном объекте/отрезок на образце)^2.Далее , если (S(объекта)/k)~S(образца),то это нужный объект.
OverDoser, да, именно так. Самое простое, по-моему, что можно придумать. Площадь для пиксельного объекта считается элементарно, а вот самый длинный отрезок между точками границы... Ну, тут придётся немного подумать. Но не думаю, чтобы это было сложно.
Добавлено через 1 минуту
Хотя вместо самого длинного отрезка можно брать, например, длину периметра. Тоже линейная штука, её, возможно, проще будет считать.
OverDoser
06.11.2011, 20:01
pokibor, Самый длинный отрезок-это есть самый длинный отрезок из двух, которые соединяют крайние противолежащие точки.
Получим координаты этих точек-вот и готово.
Хотя,таки,площадь и правда легче считать)
PS.Я вот подумал.. Почему бы не найти центр тяжести объекта, считая его относительно прямоугольника, который описывает фигуру?
У нас же объект может:поворачиваться или перемещаться(все происходит вокруг центра тяжести, значит, координаты остаются прежними, или масштабирование(центр тяжести const)
pokibor, Самый длинный отрезок-это есть самый длинный отрезок из двух, которые соединяют крайние противолежащие точки.
Получим координаты этих точек-вот и готово.Вообще-то при неровной фигуре какие там "крайние противолежащие точки" ещё поди сообрази. Периметр считать проще. Но дело Ваше.
PS.Я вот подумал.. Почему бы не найти центр тяжести объекта, считая его относительно прямоугольника, который описывает фигуру?
У нас же объект может:поворачиваться или перемещаться(все происходит вокруг центра тяжести, значит, координаты остаются прежними, или масштабирование(центр тяжести const)Что значит "относительно прямоугольника, который описывает фигуру"? Если Вы поворачиваете объект, значит и прямоугольник сместится. Центр масс найти можно относительно фигуры в целом, исходя из её площади. Прямоугольник тут не при чём. Да, он должен быть постоянным при всех масштабированиях и поворотах, но постоянным относительно краёв фигуры, её вершин и прочих элементов. Можете это брать дополнительным критерием, но вообще-то вследствие возможности поворота сопоставление таких точек приводит к тому, что сказано выше про вектризацию.
OverDoser
06.11.2011, 21:39
pokibor, Как бы я искал центр тяжести:
Нашел бы самую минимальную и максимальную Y и X (назовем X1 и Y1-минимальные,X2 и Y2-максимальные)точек у объекта
Принял бы X1 за ноль, тогда вторая координата(X2) станет X2-X1.Поделил бы (X2-X1)/2-получил абсциссу центра тяжести. Также поступил бы и с Y.
Нашел бы у объекта(X3,Y3) и образца(X4,Y4) координаты центра тяжести. Сравнил бы Х3 с X4 и Y4,Y3 с X4 и Y4.
Если совпадения есть-мы нашли искомый объект
UP.Что-то тупанул, не всегда работает =(
Из положительных и отрицательных элементов массива а нужно составить 2 массива, удалив при этом получившиеся нулевые элементы, с последним как раз и загвоздка, а именно в циклах, выделенных красным цветом. Подскажите, пожалуйста.
static void Main(string[] args)
{
Console.WriteLine("Введите число элементов массива а");
int size = int.Parse(Console.ReadLine());
int[] a = new int[size];
int[] b = new int[size];
int[] c = new int[size];
int k = 0;
for (int i = 0; i < size; i++)
{
Console.WriteLine("Введите элемент {0}:", i);
a[i] = int.Parse(Console.ReadLine());
if (a[i] < 0)
{
b[i] = a[i];
}
else if (a[i] > 0)
{
c[i] = a[i];
}
}
Console.WriteLine();
Console.Write("Первоначальный массив: ");
foreach (int j in a)
{
Console.Write(j + " ");
}
Console.WriteLine();
Console.WriteLine("Массив из отрицательных элементов массива а: ");
foreach (int j in b)
{
if (j == k)
{
???
}
}
Console.WriteLine();
Console.Write("Массив из положительных элементов массива а: ");
foreach (int j in c)
{
if (j == k)
{
???
}
}
Console.Read();
}
}
}
Arantar, А в чём проблема-то? Если j != k тогда выводим.
CMETAHA, блин, точно! Как всегда.
А размер массива уменьшается при этом или остаётся прежним (только нулевые элементы не выводятся)?
Arantar, Нулевые не выведутся. А размер массивов не измениться. Ты же не удаляешь/добавляешь элементы. Ты просто выводишь значения ячеек массивов.
Так и думал.
Но хотелось бы рассмотреть вариант именно с удалением нулевых элементов.)
Arantar, Ну так ты же их и не записываешь. В массив b ты записываешь только отрицательные элементы, а в массив c только положительные. Правда ты это достаточно криво делаешь.
Почему криво?
У меня получается так например:
Первоначальный массив: 2 -4 5 9 -1
Массив из отрицательных элементов массива а: 0 -4 0 0 -1
Массив из положительных элементов массива а: 2 0 5 9 0
Но они же есть эти нулевые элементы и их нужно убрать.
Arantar, Вот именно из-за наличия этих нулевых элементов и криво. Можно ведь заполнять массивы так, чтобы не было этих нулей.
Можно ведь заполнять массивы так, чтобы не было этих нулей.
Подскажите, как это можно сделать, если нетрудно.
Arantar, Использовать динамический массив. Т.е. ArrayList. Для этого необходимо подключить System.Collections.
ArrayList myArrayList = new ArrayList();
Затем с помощью метода Add добавляешь необходимый элемент в конец.
Вот изменённая версия кода:
static void Main(string[] args)
{
Console.WriteLine("Введите число элементов массива а");
int size = int.Parse(Console.ReadLine());
int[] a = new int[size];
ArrayList b = new ArrayList();
ArrayList c = new ArrayList();
int k = 0;
for (int i = 0; i < size; i++)
{
Console.WriteLine("Введите элемент {0}:", i);
a[i] = int.Parse(Console.ReadLine());
if (a[i] < 0)
{
b.Add(a[i]);
}
else if (a[i] > 0)
{
c.Add(a[i]);
}
}
Console.WriteLine();
Console.Write("Первоначальный массив: ");
foreach (int j in a)
{
Console.Write(j + " ");
}
Console.WriteLine();
Console.WriteLine("Массив из отрицательных элементов массива а: ");
foreach (int j in b)
{
Console.Write(j + " ");
}
Console.WriteLine();
Console.Write("Массив из положительных элементов массива а: ");
foreach (int j in c)
{
Console.Write(j + " ");
}
Console.Read();
}
А почему именно в конец добавляется нужный элемент?
Arantar, Потому что так работает метод Add. Если нужно вставить в произвольное место, то можешь воспользоваться методом Insert.
pokibor, Как бы я искал центр тяжести:
Нашел бы самую минимальную и максимальную Y и X (назовем X1 и Y1-минимальные,X2 и Y2-максимальные)точек у объекта
Принял бы X1 за ноль, тогда вторая координата(X2) станет X2-X1.Поделил бы (X2-X1)/2-получил абсциссу центра тяжести. Также поступил бы и с Y.
Нашел бы у объекта(X3,Y3) и образца(X4,Y4) координаты центра тяжести. Сравнил бы Х3 с X4 и Y4,Y3 с X4 и Y4.
Если совпадения есть-мы нашли искомый объект
UP.Что-то тупанул, не всегда работает =(
Тебе помогут интегралы и матан. (http://www.textreferat.com/referat-1404-1.html)
Написать программу «Автоматизированная информационная система на железнодорожном вокзале». Информационная система должна содержать сведения об отправлении поездов дальнего следования. Для каждого поезда указывается: номер поезда, станция назначения, время отправления.
Программа должна обеспечивать выбор с помощью меню и выполнение одной из следующих функций:
первоначальный ввод данных в информационную систему (с клавиатуры или из файла);
вывод сведений по всем поездам;
вывод сведений по поезду с запрошенным номерам;
вывод сведений по тем поездам, которые следуют до запрошенной станции назначения.
Подскажите, пожалуйста, как реализовать удаление информации о выбранном рейсе или информации о всех рейсах сразу.
http://s017.radikal.ru/i417/1111/07/2014ad7475a9.jpg
Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
namespace WindowsFormsApplication14
{
public partial class Form1 : Form
{
/*
* класс рейса поездов
*/
public class reis
{
/*
* объявляем поля класса
*/
public String punkt_naznacheniya;
public String vremya_otpravleniya;
public int nomer_poezda;
public reis(String punkt_naznacheniya, String vremya_otpravleniya, int nomer_poezda)
{
this.punkt_naznacheniya = punkt_naznacheniya;
this.vremya_otpravleniya = vremya_otpravleniya;
this.nomer_poezda = nomer_poezda;
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
/*
* загрузка формы
*/
t_hour.Text = "Час";
t_min.Text = "Минута";
/*
* чтение данных из файла
*/
FileStream Stream2 = new FileStream("db.txt", FileMode.Open, FileAccess.Read);
StreamReader Reader = new StreamReader(Stream2);
string Str;
int y;
int z;
bool zxc = false;
do
{
Str = Reader.ReadLine();
if (Str != null)
{
if (zxc == true)
{
string[] arr = new string[3];
y = Str.IndexOf("\t");
z = 0;
do
{
arr[z] = Str.Substring(0, y);
Str = Str.Substring(y + 1, Str.Length - y - 1);
z++;
y = Str.IndexOf("\t");
}
while (y > -1);
string[] row = { arr[0], arr[1], Str };
poezda.Rows.Add(row);
}
zxc = true;
}
}
while (Str != null);
Reader.Close();
Stream2.Close();
}
private void button1_Click(object sender, EventArgs e)
{
/*
* добавление нового рейса в БД
*/
reis REIS = new reis(txt_punkt.Text, t_hour.Text+":"+t_min.Text, Int16.Parse(txt_nomer.Text));
FileStream Stream = new FileStream("db.txt", FileMode.Append, FileAccess.Write);
StreamWriter Writer = new StreamWriter(Stream);
Writer.WriteLine(REIS.punkt_naznacheniya+"\t"+REIS.vremya_otpravleniya+"\t"+REIS.nomer_poezda.ToString());
Writer.Close();
Stream.Close();
poezda.Rows.Clear();
/*
* считывание рейсов из файла
*/
FileStream Stream2 = new FileStream("db.txt", FileMode.Open, FileAccess.Read);
StreamReader Reader = new StreamReader(Stream2);
string Str;
int y;
int z;
bool zxc = false;
do
{
Str = Reader.ReadLine();
if (Str != null)
{
if (zxc == true)
{
string[] arr = new string[3];
y = Str.IndexOf("\t");
z = 0;
do
{
arr[z] = Str.Substring(0, y);
Str = Str.Substring(y + 1, Str.Length - y - 1);
z++;
y = Str.IndexOf("\t");
}
while (y > -1);
string[] row = { arr[0], arr[1], Str };
poezda.Rows.Add(row);
}
zxc = true;
}
}
while (Str != null);
Reader.Close();
Stream2.Close();
/*
* очищаем поля ввода
*/
txt_punkt.Text = "";
txt_nomer.Text = "";
t_hour.Text = "0";
t_min.Text = "00";
}
private void button2_Click(object sender, EventArgs e)
{
/*
* открытие формы поиска
*/
Form2 q = new Form2();
q.Show();
}
}
}
Form2 (тут осуществляется поиск):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
namespace WindowsFormsApplication14
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load_2(object sender, EventArgs e)
{
/*
* чтение данных из файла
*/
FileStream Stream2 = new FileStream("db.txt", FileMode.Open, FileAccess.Read);
StreamReader Reader = new StreamReader(Stream2);
string Str;
int y;
int z;
bool zxc = false;
do
{
Str = Reader.ReadLine();
if (Str != null)
{
if (zxc == true)
{
string[] arr = new string[3];
y = Str.IndexOf("\t");
z = 0;
do
{
arr[z] = Str.Substring(0, y);
Str = Str.Substring(y + 1, Str.Length - y - 1);
z++;
y = Str.IndexOf("\t");
}
while (y > -1);
string[] row = { arr[0], arr[1], Str };
poezda.Rows.Add(row);
}
zxc = true;
}
}
while (Str != null);
Reader.Close();
Stream2.Close();
}
private void button1_Click(object sender, EventArgs e)
{
/*
* поиск
*/
poisk.Rows.Clear();
int kol = poezda.Rows.Count;
kol--;
for (int i = 0; i < kol; i++)
{
if (radioButton1.Checked == true)
{
/*
* поиск по пункту назначения
*/
if (poezda.Rows[i].Cells[0].Value.ToString() == searcher.Text)
{
string[] str = { poezda.Rows[i].Cells[0].Value.ToString(), poezda.Rows[i].Cells[1].Value.ToString(), poezda.Rows[i].Cells[2].Value.ToString() };
poisk.Rows.Add(str);
}
}
else
{
/*
* поиск по номеру рейса
*/
if (poezda.Rows[i].Cells[2].Value.ToString() == searcher.Text)
{
string[] str = { poezda.Rows[i].Cells[0].Value.ToString(), poezda.Rows[i].Cells[1].Value.ToString(), poezda.Rows[i].Cells[2].Value.ToString() };
poisk.Rows.Add(str);
}
}
}
}
}
}
OverDoser
31.12.2011, 17:57
Тема:маркировка бинарного изображения(массива из 0 и 1)
Использовал рекурсивный алгоритм.Программа вылетает и ругается на переполнение стека. Помогите найти решение проблемы:
class Search
{
//Метод получения координат соседних пикселей
public int[,] neighbors(int l, int p)
{
int[,] nset1 = new int[2, 8];//РУГАЕТСЯ НА ОШИБКУ ЗДЕСЬ
nset1[0, 0] = l - 1; nset1[0, 1] = l - 1; nset1[0, 2] = l - 1;
nset1[0, 3] = l; nset1[0, 4] = l; nset1[0, 5] = l + 1;
nset1[0, 6] = l + 1; nset1[0, 7] = l + 1;
nset1[1, 0] = p - 1; nset1[1, 1] = p; nset1[1, 2] = p + 1;
nset1[1, 3] = p - 1; nset1[1, 4] = p + 1;
nset1[1, 5] = p - 1; nset1[1, 6] = p; nset1[1, 7] = p + 1;
return nset1;
}
//Собственно, сам метод поиска связанных пикселей и присваивание им индекса kk.l и p-
//координаты первого пикселя, получившего индекс kk
public int[,] search(int[,] y, int kk, int l, int p)
{
y[l, p] = kk; Search ko = new Search();
int[,] nset = new int[2, 8];
//Координаты соседей
nset = ko.neighbors(l, p);
for (int qq = 0; qq < 8; qq++)
{ if (y[nset[0, qq], nset[1, qq]] == -1)
{//рекурсия
search(y, kk, nset[0, qq], nset[1, qq]); } }
return y;
}
/*Здесь идет получение самого массива из 0 и 1,
единицы меняем на -1, дабы избежать путаницы с индексом 1*/
int k=0;
for (int i=1;i<=300;i++)
for(int z=1;z<=300;z++)
{if (op[i,z]==-1){k++;op=dlo.search(op,k,i,z);}}]
Можно как-нибудь увеличить размер самого стека?Пишу в Visual Studio 2010
Играюсь тут с разработкой под Windows Phone, пытаюсь сделать простенький клиент для API вконтакта. Суть в том, что при первичной авторизации клиент получает токен, который далее необходимо отправлять с каждым новым запросом к API. Так вот, где и как лучше хранить этот токен, дабы он не терялся после перезапуска приложения?
И еще, silverlight совсем никак не поддерживает синхронные http запросы?
Digimortal
24.07.2012, 00:11
При попытке установить MS Visual Studio 2010...вылезает вот это...каждый раз.
http://i.pixs.ru/thumbs/4/8/1/govnojpg_5897031_5342481.jpg (http://pixs.ru/showimage/govnojpg_5897031_5342481.jpg)
Чем победить?
P.S.
Всё, проблема решена.
ребятушки. я парюсь с xna. с 3d. проблема - программа тормозит. УЖАСНО тормозит. я, в общем-то, сам виноват. но проблема от этого не исчезает.
что вам надобно знать. представьте себе майнкрафт. если не знаете и лень гуглить, то пояснение - визуально это выглядит как стотыщмильон кубиков. и ничего, кроме них. дак вот, у меня майнкрафт. и каждый кубик - это отдельная моделька из 3ds max. и загружаю я несколько тысяч таких моделек. и визуализирую. и тормозит.
а вот теперь - самый интересный момент. когда я визуализирую не куб о двенадцати полигонах, а teapot о нескольких тысячах таковых - производительность падает в жалкие два раза. когда я пытаюсь визуализировать в сто раз больше тех же кубиков - падает.. ну, вы поняли. нереально. соразмерно, то есть. раз в сто.
но полигонов-то столько-же получается! то есть критично количество моделей, а не полигональность. ибо сто моделек по десять полигонов на порядок медленнее, чем десять моделей по сто полигонов.
дак вот. каждую модель я визуализирую отдельным вызовом
BasicEffect effect.EnableDefaultLighting();
вопрос - как делать по-другому? то есть чтоб набрать, например, много одинаковых моделек и все их скопом отрисовать? или полигонами в массив какой запихать и оттуда рисовать (правда, тут с текстурами будет неслабый геморрой). или ещё как. как подскажите?
вопрос глобальный - как сделать так, чтоб не тормозило?
$finX, с XNA я дела не имел, последний раз занимался 3D-графикой довольно давно, но позволю себе дать несколько общих советов.
Первый - при компиляции в Debug-режиме 3d-графика тормозит намного существеннее, нежели в Release. По крайней мере, при написании на C++ с Irrlicht так.
Второй - естественно, тысячи кубиков тормозят, поскольку компьютер вынужден рассчитывать видимость для каждого из них. Например, когда кубик окружён со всех сторон шестью другими кубиками, ежу понятно, что он не может быть видимым. Ежу, но не компьютеру. Он сообразит это только когда просчитает видимость всех граней с того места, где находится камера.
Поэтому выход один - оптимизировать код так, чтобы гарантированно невидимые кубики даже не подавались на рендеринг. А в идеале - не подавались не только кубики, а отдельно невидимые грани (т.е. кубик как отдельная моделька из 3dmax'а - это очень плохая идея). Как это сделать? Лезть в глубины XNA и математики, никак иначе. И писать шейдеры.
Ну и наконец, XNA и .NET сами по себе добавляют тормозов, чисто исходя из своей сути и архитектуры. За удобство нужно платить.
Первый - при компиляции в Debug-режиме 3d-графика тормозит намного существеннее, нежели в Release
знаю. делал в релизе - качественных изменений нет. может, делал как-то неправильно, но всё же.А в идеале - не подавались не только кубики, а отдельно невидимые грани
дадада! я тоже так хочу. мне только бы код. как создать полигон в xna? не могу найти.
лезть в глубины математики не нужно, там просчитать можно просто, по моим прикидкам. не идеально, но существенную часть невидимых кубов выкидывает.
лан, я вроде нашёл что-то про примитивы вчера. буду через них думать. спасибо, но вопрос не снят.
Подскажите, пожалуйста.
Как получить кол-во строк в DataGridView не в методе, а в классе, чтобы потом можно было использовать это число в качестве размера массива. Если я делаю так, как в коде ниже, он выдаёт ошибку: "Инициализатор поля не может обращаться к нестатическому полю, методу или свойству "*.Form1.dataGridView1""
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
здесь создается таблица нужного размера.
}
int r = dataGridView1.RowCount;
double[,] a = new double[r, r];
private void button2_Click(object sender, EventArgs e)
{
здесь должны производиться операции над массивом a.
}
...
}
Как получить кол-во строк в DataGridView не в методе, а в классе
ась? оО
странная ошибка - код верен и логичен. разве что - а ты дейтагридвью создаёшь динамически в коде?
ну и вообще, на какой строчке-то хоть ошибка?
Собственно сам код. Выделенное у меня в коде, он считает ошибкой.
Извиняюсь, там немного другой текст ошибки, такой: "Инициализатор поля не может обращаться к нестатическому полю, методу или свойству "*.Form1.r""
public partial class Form1 : Form
{
...
public void Form1_Load(object sender, EventArgs e)
{
comboBox1.Text = "4x4";
for (int i = 0; i < 8; i++)
{
comboBox1.Items.Add((i + 2) + "x" + (i + 2));
}
for (int i = 0; i < 4; i++)
{
dataGridView1.Columns.Add("", "X" + Convert.ToString(i + 1));
dataGridView1.Rows.Add("");
}
dataGridView1.Columns.Add("", "B");
}
private void button1_Click(object sender, EventArgs e)
{
dataGridView1.Rows.Clear();
dataGridView1.Columns.Clear();
textBox1.Clear();
textBox2.Clear();
string b = comboBox1.Text;
sbyte v = Convert.ToSByte(Convert.ToString(b[0]));
dataGridView1.Size = new System.Drawing.Size(100 * v + 135, v * 22 + 26);
if (v > 4)
ClientSize = new System.Drawing.Size(368 + (v - 2) * 100, 250 + (v - 2) * 22);
else ClientSize = new System.Drawing.Size(600, 286);
for (int i = 0; i < v; i++)
{
dataGridView1.Columns.Add("", "X" + Convert.ToString(i + 1));
dataGridView1.Rows.Add("");
}
dataGridView1.Columns.Add("", "B");
}
int r = dataGridView1.RowCount;
double[,] a = new double[r, r];
private void button2_Click(object sender, EventArgs e)
{
операции с массивом a[r, r].
}
...
}
Получить никак).
Это значит ты можешь создать переменную вне функции (то бишь в классе), присвоить её значение внутри функции, а пом создать массив используя переменную в классе.
Это все от того что клоичество столбцов может динамически меняться и значит что вне функции узнать значения не получится. Делай какое нибудь поле аля
int r
{
get { return dataGridView1.RowCount;}
}
Но создавать массив вне функций а прямо в классе, используя переменную нельзя
Собственно с этим понятно теперь, но возникла другая проблема.
У меня есть два класса: в одном описываются методы для решения СЛАУ, другой Form1, в котором я их вызываю. Но возникает проблема, нужно передать значение dataGridView1.RowCount в первый класс, в котором это значение есть размер динамических массивов.
Что мешает обратиться к гриду или массиву из другого класса?)
Передача данных между классами дело элементарное.
самое просто передавай ксласс форм в конструктор первого класса и обращайся к нему через переменную)
Продемонстрируйте, пожалуйста.
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
SomeClass something;
public Form1()
{
InitializeComponent();
dataGridView1.Rows.Clear();
dataGridView1.Columns.Clear();
for (int i = 0; i < 10; i++)
{
dataGridView1.Columns.Add("", "X" + Convert.ToString(i + 1));
dataGridView1.Rows.Add("");
}
dataGridView1.Columns.Add("", "B");
something = new SomeClass(this);
}
private void button1_Click(object sender, System.EventArgs e)
{
something.SomeAction();
}
}
public class SomeClass
{
Form1 parent;
public double[,] array;
public SomeClass(Form1 form)
{
parent = form;
int n = parent.dataGridView1.RowCount;
array = new double[n, n];
}
public void SomeAction()
{
MessageBox.Show(array.Length.ToString());
}
}
}
Как я понимаю нужно что-то такое. Есть класс Форм1, в котором есть датаГрид, есть какой-то другой класс, в котором есть двумерный массив. При создании второго класса передаем ему данные из первого и обращаемся к ним через переменную.
Датагрид, нужно пометить модификатором public вместо private в функции инициализации компонентов.
Если что-то не так, прошу более подробно объяснить суть, возможно даже с кодом
Pharaon, спасибо, но я решил проблему с помощью метода Array.GetLength.
Но у меня есть вопросы, например можете пояснить кое-какие строчки в коде. Вот эти к примеру.
Form1 parent;
public SomeClass(Form1 form)
{
parent = form;
...
}
SomeClass something;
public Form1()
{
something = new SomeClass(this);
}
Тут не совсем получается ещё, размер таблицы у меня же меняется, и он должен каждый раз при её создании в button1_Click передавать её размер в другой класс.
Тут дело в чем. Теперь все данные из класса форм доступны в классе SomeClass и наоборот.
Если ты меняешь размер то его данные изменятся и уже изменнные данные ты можешь получить с помощью переменных кооторые есть в твоей цитате.
Поясните, пожалуйста, что конкретно здесь делается, а то работать работает, а как, не совсем понятно.
Form1 parent;
public SomeClass(Form1 form)
{
parent = form;
...
}
SomeClass something;
public Form1()
{
something = new SomeClass(this);
}
Определяем объект Класса Форм1, для использование внутри класса SomeClass
Form1 parent;
// Конструктор класса. Когда мы пишем new SomeClass() вызывается эта функция
//Параметром функции служит класс нашей формы
public SomeClass(Form1 form)
{
// Чтобы сохранить переданный объект в переменной и обращаться в нему из любого места класса, присваиваем переменной parent переданный аргумент.
parent = form;
...
}
// Определяем объект класса SomeClass, чтобы использовать его возможности в любом месте данного класса.
SomeClass something;
public Form1()
{
// Создаем объект класса SomeClass, передав в качестве аргумента(this) текущий, класс, в данном случае Form1
something = new SomeClass(this);
}
Комментарии.
Если все это непонятно, то вам надо по возможности чуть лучше изучить ООП, так как шарп на принципах ооп построен.ООП (объектно-ориентированное программирование)
Скажите, пожалуйста, есть ли у элемента управления NumericUpDown свойство или метод, который определяет было ли увеличено или уменьшено значение этого элемента управления?
Arantar, Нет, но у него есть евент ValueChanged.
CMETAHA, спасибо, я так и сделал.
Ещё вопрос, моя программа работает с валютами, но их курс, сами знаете, каждый день меняется. Собственно в этом и проблема. Нужно, чтобы программа автоматически каждый раз при запуске соединилась с инетом и обновляла их курсы, но я даже не представляю как это можно сделать, подскажите с чего стоит начать...
Arantar, Всегда нужно начинать с курения MSDN. Поищи там как связываться с инетом и обновлять от туда данные.
Ещё вопрос есть. Есть ли метод или свойство, которое получает кол-во дней в текущем месяце/году?
Arantar, MSDN! (http://msdn.microsoft.com/en-us/library/system.datetime.aspx)
Есть ли метод или свойство, которое получает кол-во дней в текущем месяце/году?Ответ: да.
подскажите с чего стоит начать...Ищи любую страницу, на которой своевременно обновляется курс, и парси html.
Hast, с парсингом я не знаком, буду признателен, если подкините информацию по этой теме для изучения.
Arantar, https://www.google.com.ua/webhp?sourceid=chrome-instant&ion=1&ie=UTF-8#hl=en&output=search&sclient=psy-ab&q=%D0%BF%D0%B0%D1%80%D1%81%D0%B8%D0%BD%D0%B3&oq=&gs_l=&pbx=1&fp=33103e76deb17148&bpcl=38093640&ion=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.&biw=1241&bih=584
каждый божий раз, когда мне нужно округлить double до int и засунуть в, собственно, int, я делаю следующую штуку
intVar = Convert.ToInt32(Math.Round(doubleVar));
есть что-то более компактное, чем это, но тоже позволяющее хотя бы обрубить дробную часть?
$finX,
intVar = (int)doubleVar;
Но округлять он будет всегда в меньшую сторону.
вопрос. не по шарпу, но хрен пойми, где тут спросить. но я ж пишу на шарпе, так что формально верно? верно, верно.
форма Бэкуса-Наура. например, вот такая.
<число>::=<цифра>|<число><число>
<цифра>::=1|2|3|4|5|6|7|8|9|0
является ли она корректной?
то есть согласно ей строка "123" может быть расшифрована и как (1(23)), и как ((12)3), то есть возникает неоднозначность - возможно разбить строку на два "подчисла" двумя способами. это допустимо?
Ну вообще она не очень корректна по моему. Правильней будет <число>::=<цифра>|<число><цифра>
И тогда неоднозначность пропадёт.
CMETAHA, ну да, твоя форма безусловно лучше. но у меня форму вводит пользователь, так что я хочу быть готов к любым его нелепостям) вот и хочу знать - стоит ли мне для такого случая что-то придумывать или забить, потому что это ошибка.
$finX, ну раз возникает неоднозначность, то можешь уведомлять пользователя, что его форма неоднозначна.
bober_maniac
04.01.2013, 20:40
CMETAHA, ну да, твоя форма безусловно лучше. но у меня форму вводит пользователь, так что я хочу быть готов к любым его нелепостям)
Я бы поостерегся решать задачи путем запроса у пользователя данных в формате формы Бэкуса-Наура.
Форма совершенно корректна, все зависит от того, какой у тебя парсер. Для праворекурсивного парсера (например Coco/r) эта форма некорректна потому что first(a) равно first(b), и парсер не сможет разрешить неоднозначность.
Правильная форма для праворекурсивного парсера будет number ::= {digit}. Если я правильно помню форму.
немного ненужной истории.
пишу я на CUDA. и хочу я писать на C#. и думаю - а не сделать ли мне библиотечку? нехай кудовский код будет на крестах, а нормальные удобные вещи я буду писать на шарпе. и начался гугл, и было его тысячи, и через многие сотни времени у меня всё ж таки была dll с кодом на CUDA. и работала она. вот только к шарпу не подключалась.
файлик Hello.cu сиречь cpp
#include "Hello.h"
__global__ void MyCUDA(int a, int b, int *c)
{
*c = a + b;
}
namespace nmspace
{
extern "C" _declspec(dllexport) int myclass::Summ(int a, int b)
{
int c;
int *dev_c;
cudaMalloc((void**)&dev_c,sizeof(int));
cudaMemcpy(dev_c, &c, sizeof(int), cudaMemcpyHostToDevice);
MyCUDA<<<1, 1>>>(a, b, dev_c);
cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(dev_c);
return c;
}
}
файлик Hello.h
namespace nmspace
{
class myclass
{
public:
static __declspec(dllexport) int Summ (int a, int b);
};
}
код шарпа
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport(@"P:\study\course work 2013\asonsite\HelloWorld\Debug\HelloWorldCuda.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Summ(int a, int b);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Summ(13, 37).ToString());
}
}
}
и при тыке на кнопку он выдаёт вот такую ошибку:
Unable to find an entry point named 'Summ' in DLL 'P:\study\course work 2013\asonsite\HelloWorld\Debug\HelloWorldCuda.dll' .
что же мне делать? я что-то читал про то, какие некошерные имена функций получаются в dll, которые лишь отдалённо похожи на оригинальные, и что нучжо что-то сделать, чтоб имена получались хорошими, годными. это так?
bober_maniac
01.04.2013, 00:32
Во-первых, можешь посмотреть, какие функции экспортирует твоя DLL.
Во-вторых, тебя может спасти extern "C".
В-третьих, если я все правильно помню, все dllexport функции помечаются как STDCALL. То есть, у тебя неправильно указан формат вызова.
bober_maniac, я зафигачил экстерн си. под первым спойлером.
как посмотреть экспортируемые функции?
и при __stdcall даже отказывается компилить. судя по ошибкам, энвидиа не понимает его.
Добавлено через 47 минут
вопрос отпал. методом научного тыка подобран набор параметров, при котором всё работает. всем спасибо, bober_maniac. даст система - лайкну.
bober_maniac
03.04.2013, 20:43
как посмотреть экспортируемые функции?
Dependency walker, например.
bober_maniac, ага, как раз им и воспользовался. решилось нахождением точки входа, копипаст ручками в DllImport шарпа, выставлением cdecl в шарпе и крестах и GOTO 10, пока не переберёшь все функции. но хоть работает.
Кто-ниубдь поможет каким образом можно быстрее выводить картинки в шарпе.
Graphics.DrawImage() у меня вызывается 29 раз в цикле (то бишь рисует 29 картинок) из-за чего перерисовка занимает аж 3 секунды, картинки почти 1к х 1к.
Никак не могу понять как с наименьшими потерями или объеденить вызов в один или использовать без лишних плясок длл-ками, нужен полный минимум нестандартных дллок, и да, .Net 2.0, если в версии выше что есть стоящее - попробуем.
Никаких директХ, только хардкор и WinForms
Pharaon, а поподробнее, на чём рисуешь, что именно рисуешь?
я заводил pictureBox, в итерациях фигачил статичный Bitmap, для него создавал Graphics, рисовал, потом делал
pictureBox.Image = bmp;
pictureBox.Size = bmp.Size;
насчёт минимума потерь - помни, что всё наэкранное выполняется медленнее, поэтому рисовать напрямую на панели, например - плохо.
Добавлено через 2 минуты
плюс DrawUnscaledImage() должен, в принципе, выполняться быстрее. Плюс никто не мешает написать свой unsafe метод с копированием, особенно если размеры изображений постоянны.
Анимацию делаешь? Помню в Делфи был совет в этом случае не перерисовывать всё, а лишь измененную область. Если не вариант, то делай что-то типа двойной буферизации - держи в памяти два битмапа, в один записываешь всё, что надо вывести на экран, рисуешь его и параллельно готовишь второй. Но это костыль, потому что не предназначен WinForms для анимации, хоть убей, и в этом нет никакого хардкора.
Да у меня нет анимации как таковой.
Цель такая - вывести на экран упрощенную карту мира, которая состоит из 29 регионов. У каждого региона есть свое название и они отделены друг от друга жирными границами. Есть чек бокс для того чтобы карта выводилась без названий или с ними.
Так же есть контекстное меню, которое вызывается при клике правой на регион, в нем 8 цветов, при нажатии цвет выбранного региона закрашивается, цвет границы и названия остается тем же.
Я решил создать 29 файлов с каждым регионом и вывожу их и работаю через лист. Перечисляю в массиве и вызываю рисование, да 29 раз.
Как не извращался обновление экрана постоянно занимает около 2 секунд, может будет подсказка как это все сделать попроще?
$finX,
Совет принят, но я пытался сделать что-то подобное, хотя чуть по другому, попорбую на досуге со статичным битмапом.
-PhantomX-
06.08.2013, 14:40
Ребят, нужна помощь. Есть задача создать два потока: первый рекурсивно читает все файлы и папки в указанной папке, второй получает информацию о текущем файле/папке и отображает их в виде объекта TreeView. С первым еще более-менее все понятно:
Thread ScanThread = new Thread(Scan);
ScanThread.Start(rootFolder);
public void Scan(object objfolder)
{
FolderNode Scanfolder = (FolderNode)objfolder;
string[] dirs = Directory.GetDirectories(Scanfolder.FolderPath);
foreach (string dir in dirs)
{
FolderNode tmpfolder = new FolderNode(dir);
Invoke(new Action(() =>
{
Scanfolder.Nodes.Add(tmpfolder);
currentFolder = tmpfolder;
}));
Scan(tmpfolder);
}
if (getFiles)
{
string[] files = Directory.GetFiles(Scanfolder.FolderPath);
foreach (string file in files)
{
FileNode fnode = new FileNode(file);
ready.WaitOne();
currentFile = fnode;
go.Set();
}
}
}
Использую две глобальные переменные currentFile и currentFolder, в которые первый поток заносит файл/папку, а второй сразу же ее считывает. Синхронизацию обеспечиваю с помощью двух объектов
static EventWaitHandle ready = new AutoResetEvent(false);
static EventWaitHandle go = new AutoResetEvent(false);
Классы FolderNode и FileNode наследуются от System.Windows.Forms.TreeNode.
Так вот, проблема в следующем. Если во втором потоке просто заносить получаемые файлы в TreeView:
treeView1.Invoke(new Action(() =>
{
treeView1.Nodes.Add(currentFile);
}));
то в результате получается беспорядочный набор файлов.
Вопрос: как воспроизвести исходную файловую структуру во втором потоке? Передавать из первого потока целый объект TreeNode нельзя.
-PhantomX-, не стал особо вникать, но проблема не ясна. ты добавляешь в treeview всё в корень, естесн, что получается набор файлов. в чём проблема, ты не умеешь работать с древовидной структурой этого компонента или тебе неясно, как сохранять и передавать данные иерархии файлов между потоками?
и ещё вот это.
Передавать из первого потока целый объект TreeNode нельзя
так ты же так и делаешь - твои currentFile и currentFolder и есть объекты TreeNode, и ты их передаёшь (грубо говоря) между потоками.
и зачем эта мура с потоками? без них всё было бы гораздо проще.
Добавлено через 1 минуту
и зачем ты вообще завёл currentFolder, если нигде его не используешь?
-PhantomX-
06.08.2013, 17:07
и зачем эта мура с потоками? без них всё было бы гораздо проще.
Такое задание, реализовать именно потоками.
так ты же так и делаешь - твои currentFile и currentFolder и есть объекты TreeNode, и ты их передаёшь (грубо говоря) между потоками.
Я не совсем правильно выразился. Можно было бы сразу запихать все файлы вместе с папками в один объект TreeNode еще на этапе сканирования. Он был бы красивый со всей иерархией папок и т.д. А потом перекинуть его в другой поток. Но суть задания в том, что второй поток должен получать от первого информацию о текущем файле или папке и заносить их в TreeView. Суть именно в синхронизации потоков, как я понял.
как сохранять и передавать данные иерархии файлов между потоками?
Вот-вот. Именно. У меня нет возможности передать файловую структуру в целом, и нужно как-то ее восстановить, имея в наличии только постоянно поступающие файлы. Или может быть можно как-то передать структуру папок и потом набить ее файлами, чтобы в итоге она выглядела точно так же, как и исходная?
можно как-то передать структуру папок и потом набить ее файлами
именно. создаёшь свой класс, вот в нём ты делаешь так
class MyNode : System.Windows.Forms.TreeNode
{
public bool IsFile; //вместо твоих двух разных классов - можно вообще не учитывать, ты и так не используешь это
public MyNode Parent; //сюда ты засунешь корневой каталог
//ну и что там тебе ещё нужно
}
и ты, на этапе просмотра первым потоком всех элементов текущего каталога, передаёшь в конструктор и текущий каталог, и новый перебираемый файл/папку, а в конструкторе соответственно запоминаешь в Parent родительский каталог.
прикол в том, что любое дерево можно представить как множество пар (номер узла, номер родительского узла), и, соответственно, по ним построить то, что тебе нужно. поэтому тебе проще всего просто хранить для каждого файла и папки родительскую папку. реализовывай как хочешь - хоть числовыми идентификаторами, хоть строковыми, хоть ссылками.
-PhantomX-
07.08.2013, 16:18
$finX, извини, если надоедаю, но можно для чайника чуть поподробней? :)
Допустим, моя рекурсия из первого потока посылает файл и его родительский каталог (он же текущая папка). Второй поток его в бесконечным цикле принимает. При этом файлы из-за рекурсии поступают в порядке, обратном тому, в котором они вложены (т.е., от самого внутреннего к корневой папке).
Как мне в таких условиях эти пары сортировать?
Уже неделю с этой фигней мучаюсь %(
-PhantomX-, ну, роди алгоритм, что ты не как дома.
как мне представляется сейчас - создай класс, в нём реализуй хранилище в виде леса, то есть списка деревьев. в этот класс зафигачь метод добавления пары (файл, корневая папка), в котором будет происходить добавление ещё одного дерева в общий список. дерево, соответственно, из двух элементов. плюс реализовываешь процедуру, которая проверяет все деревья в лесу на то, что корневой элемент дерева содержится в другом дереве из леса, в этом случае ты перекидываешь это дерево в другое, в котором элемент встретился.
поясняю на примере.
у тебя подаются пары (для простоты вместо имён каталогов и файлов - просто числа):
(1, 4), (3, 4), (2, 3)
сначала лес пустой.
потом лес [(4 -> 1)]
потом лес [(4 -> 1), (4 -> 3)]. во втором дереве корневой элемент 4 встретился в первом дереве (или наоборот) - в любом случае, ты объединяешь два дерева и получаешь лес [(4 -> 1, 3)].
потом лес [(4 -> 1, 3), (3 -> 2)]. корневой элемент второго дерева 3 встретился в первом дереве. объединяешь и получаешь лес [(4 -> 1, (3 -> 2))]. единственное дерево, оригинальная структура восстановлена.
вопрос. WPF.
ввожу триггер, чтобы создать анимацию. сам вопрос простой - каким событием перехватывать нажатие кнопки мыши?
<EventTrigger RoutedEvent="UIElement.MouseDown"> - перехватывает нажатие ТОЛЬКО ПРАВОЙ кнопки.
<EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown"> - вообще ничего не перехватывает, ни левую, ни правую.
нужно именно нажатие и отпускание, а не клик. нужна именно кошерная левая кнопка.
гугл мне не внемлет. кто-нибудь сталкивался?
Добавлено через 24 минуты
так. что-то таки нашлось - по-видимому, единственным вариантом остаётся PreviewMouseDown и проверка e.LeftButton == MouseButtonState.Pressed.
вопрос обновляется. вот код:
< EventTrigger RoutedEvent="UIElement.PreviewMouseDown" >
< BeginStoryboard x:Name="OnMouseDown1_BeginStoryboard" Storyboard="{StaticResource OnMouseDown1}" / >
< / EventTrigger >
каким образом мне в xaml засунуть эту самую проверку? я пишу общий кнопочный стиль, может, там можно сделать через код на шарпе?
Задам вопрос в этой теме.
Кто имел дело с контактом - есть ли там возможность создавать опросы через апи, и какой наилучший способ сделать это на данном языке. (через апи или без)
Жду советов бывалых)
есть ли там возможность создавать опросы через апиСудя по всему, нет. Вот список всех методов для работы с опросами: http://joxi.ru/MoRxUtg5CbDvd_pvZcQ
какой наилучший способ сделать это на данном языке. (через апи или без) И как ты собрался делать это без апи?
Hast,
Без апи - эмуляция браузера, пост запросы и т.п.
Тут в чем дело, если опрос уже существует то добавить его можно, но именно создать новый не получается, и меня это честно говоря приводит в шок, они просто забыли?
http://vk.com/dev/wall.post - вот тут сказано, что указав в параметре attachments тип poll, мы отправляем опрос. проблема в том что мы не знаем ид опроса.
Сам опрос возможно создать как виджет к сайту здесь - http://vk.com/dev/Poll.
Там нажав на кнопочку получить код, внизу можно увидеть ид созданного опроса, и если я вставляю этот ид в wall.post, то он появляется на стене, НО голосовать нельзя - ошибка доступа. Если же на странице создания опросов нажать кнопочку рассказать друзьям, то он также появляется на стене, с тем же ид, и отправляя программно этот ид на любую стену опрос появляется и голосовать можно.
Спрашивается, что за хрень тут зарыта?
Без апи - эмуляция браузера, пост запросы и т.п.
Желаю удачи :))
Хрень называется vk api. Я два года работал в геймдеве для вконтакта, и ничего хорошего о платформе сказать не могу. Поэтому такие вещи как "не может быть, что они забыли" вплоне реальны. Они только недавно более-менее нормальный референс по апи сделали. И то далеко не полный.
Желаю удачи
Решил ужасно кривым но рабочим способом. Создаю голосовалку заполняя поля из браузер-контрола и програмно нажимаю кнопку отправить. Потом беру запись со стены wall.get там подсматриваю ид опроса, удаляю запись и уже через апи добавляю голосовалку на нужные стены в группах или польователям.
Теперь возникла вторая проблема. Все знают кнопку шаринга в соц сеть. Но что если мне нужно расшарить ссылку с описанием (своим)?
у wall.post можно добавить ссылку и она автоматом распарсится в нечто такое http://savepic.org/4708657.jpghttp://savepic.org/4677937.jpg
А нужно чтобы было нечто такое http://savepic.org/4693297.jpghttp://savepic.org/4685105.jpg
Елки палки, или мне кажется что я уже видел как подобное делали в приложениях. Вопрос на миллион - как?
-PhantomX-
18.11.2013, 12:50
Разбирая примеры из Рихтера столкнулся с такой проблемой, что отсутствуют некоторые пространства имен. Например, System.Threading.Tasks. Установлена полная версия Visual Studio Ultimate 2012, .NET Framework версии 4.5.50709. Какие-то дополнительные компоненты нужны, чтоль?
-PhantomX-, должен быть в стандартной комплектации дотнета. версия дотнета в настройках проекта выставлена 4.5?
-PhantomX-
18.11.2013, 15:41
Да, действительно в настройках версия не та. Спасибо. Почему-то думал, что при конвертации проекта изменится и требуемая версия.
Подскажите народ какое решение подойдет для того чтобы автоматом загружать от 10 до 80 страниц из интернета и парсить их каждые 10 секунд, и при удобном случае вызывать яваскрипт функцию с сайта и парсить то что она открыла?
ТО что сейчас работает удовлетворительно.. на каждую загрузку поток с локером браузер-контрола, но судя по скорости это очень медленно.
bober_maniac
25.01.2014, 23:14
Pharaon, разве что WebKit, но он нативный. Других способов эмулировать работу браузера нет.
[CCCP] Monster
26.01.2014, 00:10
Pharaon, Возьми какой-нить парсер хтмл, или вообще руками из странички выдери. Жаваскрипт - лучше не надо, ему виртуальную машину надо, и там, возможно, придется запилить какие-то браузерные методы, которых изначально в машине нету.
Еще стековерфлоу никто не отменял:
http://stackoverflow.com/questions/6063203/parsing-html-with-c-net
[CCCP] Monster,
Суть не в самом парсинге а в скорости обработки страницы и выполнении js кода. Я бы с радостью его не выполнял, но Надо!
Сейчас у меня данные скачиваются WebClient'ом в строку, строка загружается в парсер, в парсере ищется ссылка на страницу и та загружается в браузере, браузер жмет кнопку на которой завязан ajax-метод(иначе бы скрытый блок все равно был в ихсоднике страницы как я понимаю), открывающий данные, именно эти данные я и забираю.
Суть именно в скорости, так как обработка 40 ссылок занимает около 20-30 секунд, учитывая что на каждую ссылку выделяется по потоку, да даже по 10 ссылок на поток...
bober_maniac,
Вообще я уже думал вставить вебкит, хромиум но пугает именно нативность, нет ли для него простеньких врапперов, подходящих для моих целей?
Я спрашиваю тут в целях экономии времени и надежде быть может услышать еще какие советы. А так конечно потратить лишнее время на встраивание и разбор, быть может написание враппера это наш выбор.
Забыл упомянуть, отображение сайта не требуется
[CCCP] Monster
26.01.2014, 12:30
Pharaon, ajax-запрос - это обычное подключение и скачивание данных по ссылке. Может тебе следует выпарсить эту ссылку из js? Если она там динамически образуется, можно написать то же самое на шарпе и просто получить http-запросом опять же строку, также как тебе XMLHTTPRequest возвращает.
[CCCP] Monster,
Попробовал сделать таким способом, но на серве походу стоит защита, данные получаются, но они намеренно искажаются (в данном случае получается номер телефона, если делать прямой запрос то код оператора всегда ставится фейковый). В конце концов использую awesomium (движок chromium без интерфейса) и доволен.
Но мой вопрос сейчас не об этом. То ли я чего-то недопонимаю, то ли что.
Задача следующая, вкратце. Составляется текстовый документ - каждая строчка ссылка на сайт. В программе я загружаю каждую ссылку, делаю парсинг контента и ожидаю повтора парсинга. Так вот путем нехитрых проверок пришел к выводу что System.Net.WebClient.DownloadString не распараллеливается. Пробовал его Async версию тоже самое. Подскажите что делать и как быть?
Полный текст тестовой программы:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Diagnostics;
namespace TestTest
{
class Program
{
static List<string> ListUrl;
static void Main(string[] args)
{
ListUrl = File.ReadAllLines("BAZA.txt").ToList();
var listThread = new List<Thread>();
while (true)
{
listThread.Clear();
Parallel.For(0, ListUrl.Count, new Action<int>((int i) =>
{
var th = new Thread(new ParameterizedThreadStart(thread), ListUrl.Count);
listThread.Add(th);
th.Start(i);
}));
Console.ReadLine();
}
}
static void thread(object obj)
{
int i = (int)obj;
var text = "";
bool complete = false;
Stopwatch sw = new Stopwatch();
sw.Start();
var cl = new WebClient();
cl.DownloadStringCompleted += new DownloadStringCompletedEventHandler((object client, DownloadStringCompletedEventArgs e) =>
{
text = e.Result;
complete = true;
});
cl.DownloadStringAsync(new Uri(ListUrl[i]));
while (!complete)
{
Thread.Sleep(50);
}
sw.Stop();
Console.WriteLine(i.ToString() + " номер. " + sw.Elapsed.ToString());
}
}
}
Суть в том что работа потоков идет параллельно вплоть до того момента когда нам нужно скачать строку. В итоге чем больше ссылок тем дольше мы ждем окончания последнего потока (когда как они должны завершаться примерно одинаково).
[CCCP] Monster
14.02.2014, 14:09
Pharaon, Понятно, что задачу ты уже решил, но все же, если вдруг по какой-то причине эта штука от тебя ускользнула. Есть прога, TCPView (http://technet.microsoft.com/en-us/sysinternals/bb897437.aspx), позволяющая поснифать весь IP трафик на твоей тачке. Можно выбрать нужный процесс и подключение и посмотреть, чем обмениваются браузер и сервер, например, что позволит правильно сформировать запрос, если вдруг в следующий раз возникнет проблема с хитростями их отправки и получения.
Так вот путем нехитрых проверок пришел к выводу что System.Net.WebClient.DownloadString не распараллеливается. Пробовал его Async версию тоже самое. Подскажите что делать и как быть?
Я не уверен, но подозреваю, что DownloadString использует в тайне от тебя функционал WinHTTP (http://msdn.microsoft.com/en-us/library/windows/desktop/aa382925(v=vs.85).aspx), а у него стоит ограничение на количество потоков с одного и того же хоста (Майкрософт оправдывается каким-то стандартом HTTP протокола, не помню уже). И вот по умолчанию это количество одновременных закачек равно 2. Его можно увеличить в реестре, или использовать какие-то другие методы. В любом случае, погугли в эту сторону.
Потихоньку разбирался и пока решил заменить скачку прямым запросом с сокетов. Но и тут возникла беда.
На каждую ссылку открываю по сокету (не знаю правильно или нет, когда их будет от 30 до 200), каждые 5 секунд шлю заранее сформированный хедер, получаю нужный ответ. Все бы ничего но примерно к 20-30 сокету (работает то все параллельно) они начинают выдавать 0 полученных байт (причем если параллельно открывать оперу и перейти по той же ссылке опера тоже говорит что сервер не ответил, однако файрфокс всегда отвечает, наверное связано с архитектурой брузера), причем отсылка в сокет работает нормально. то бишь сервер получает хедер но ничего не возвращает. В итоге при таком сценарии я закрываю сокет создаю заново подключаю и получаю ответ, в итоге возвращается что нужно. Однако количество закрытый открытый одного и того же сокета может проходить от 2 до 40 раз подряд, что конечно замедляет работу. Но даже при таком сценарии опрос 70 ссылок снизился с 30 секунд до 10-13, из этих 10 около 8 тратится на переоткрытие сокетов.
В общем в сетевой части я полный профан, столько всякой ерунды всплывает уже не знаешь куда копать.
Насчет winhttp спасибо, в итоге хочу прийти к такому решению где я бы точно понимал что откуда и как, а не иметь всякие непонятности.
чем обмениваются браузер и сервер, например, что позволит правильно сформировать запрос, если вдруг в следующий раз возникнет проблема с хитростями их отправки и получения.
Я снифал трафик с помощью Charles. Вся проблема вот в чем.
За кнопочкой с аджаксом скрыт телефон, телефон получается из хмл, к которому можно обратиться напрямую, но иногда нужна капча. Так вот сама капча в хмле не присутствует, но ему нужен ответ с неё, а значит я должен откуда-то брать картинку. Это время нужно на исследование которого у меня пока нет. Поэтому на ближайший месяц хрома мне хватит (хотя отказаться от него и все делать через сетевой обмен было бы идеально)
Бывает думаю стоит или нет сделать дллку на плюсах для решения сетевых задач а потом из дотНЕта уже использовать... сильно поможет или те же проблемы будут возникать?
[CCCP] Monster
14.02.2014, 21:51
Pharaon, Если тебе пришел 0 байт (а шарповые сокеты, опять же, в тайне от тебя, используют WinSock2 sockets из няшной Сишки), стало быть, состояние сокета изменилось и надо бы его обработать. То есть или ошибка там, или еще что - это уже тебе надо выяснить. куча сокетов для общения с разными ресурсами - это ок, подругому все равно не сделаешь в параллели.
У тебя сокеты синхронные? Ты на каждый по потоку выделяешь и сидишь в нем, ждешь ответа через recv? Сервер - это твое хозяйство, т.е. ты к нему вообще как-то доступ имеешь, или эта третья фигня, типа черный ящик?
[CCCP] Monster,
Да, в каждом потоке выделаю сокет который слушает recv, сокет синхронный. К серверу доступ не имею, просто левый сайт.
На си я когда-то давно использовал сокеты, чувствую нужно освежить память.
Есть советы как это изменившееся состояние обработать?
[CCCP] Monster
17.02.2014, 19:55
Pharaon, To check status, use getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error_code, sizeof(error_code))
Какой же все-таки няшка этот Джоел Спольски и его Stack Overflow
Да я имел ввиду стандартные дотнетовские средства, ну ок будем инвокить. Я уже так сделал
У меня довольно глупый вопрос. Я всю жизнь сам, явно прописывал транзакции. Однако недавно столкнулся с кодом, где для работы с БД применяется TransactionScope. Так вот: может ли кто-то объяснить мне преимущества применения этого класс в работе с одной-единственной БД?
Что TransactionScope предназначен для распределенных транзакций - это ясно. Наверное, в таких случаях из него можно извлечь пользу. Хотя на мой взгляд, неявные транзакции в любом случае затрудняют понимание кода и отладку ошибок. Если можно, хотелось бы услышать, насколько я прав и в этом утверждении.
vBulletin® v3.8.0, Copyright ©2000-2025, Jelsoft Enterprises Ltd.